文档章节

Nebula3脚本系统

rise-worlds
 rise-worlds
发布于 2016/06/20 13:41
字数 1246
阅读 1
收藏 0

Nebula2的脚本系统实现了一个面向C++的脚本接口, 它把脚本命令直接映射到了C++方法. 从技术角度来说, 这是一个简捷的思路, 但是对于需要把游戏逻辑和行为脚本化的关卡设计师来说, Nebula2的脚本系统太底层和透明了.

关卡逻辑脚本一般来说构架于比C++接口更高级的层次上, 直接把脚本命令映射到C++方法会把脚本层次弄得错综复杂. Bug甚至会比同样的C++代码更多, 因为脚本语言一般缺少强类型检查和”编译时”的错误检测, 所以在本应在C++编译时发现的Bug会在脚本运行时才发现(这对于不同的脚本语言有所不同). 这是我们从Project Nomads中得出的经验, 它就是用Nebula2的脚本系统驱动的.

所以教训就是: 把你的脚本架构在一个正确的抽象层上, 并且: 把你的C++接口映射到一种脚本语言是没有意义的, 因为那样你不如从一开始直接用C++来做这些东西.

相应的, 新的Nebula3脚本哲学为关卡设计师提供一些在”正确的抽象层”的(大多是限于特定应用)积木. 当然, “正解的抽象层” 很难来定义, 因为这要在灵活性跟易用性之间找到一个平衡( 例如, 一个”Pickup” 命令是不是应该把角色移动到拾取范围内呢? )

除了太底层以外, Nebula2的脚本系统也有一些其它的缺点:

  • C++方法必须遵循可以转化为脚本的原则( 只有简单数据类型才可以做为参数 )
  • 给程序员带来麻烦. 每个C++方法都需要额外的脚本接口代码( 每个方法几行 )
  • 只有派生自nRoot的类可以脚本化
  • 对象关联到脚本系统( 思路简单, 但是增加的依赖性会使重构非常困难 )

下面是Nebual3的底层脚本的大概:

  • 脚本系统的基础是Script::Command类
  • Script::Command是一个完全脚本语言无关的, 它包含了一个命令名称, 一些输入参数的集合还有一些输出参数的集合.
  • 一个新的脚本命令通过派生Script::Comand类来创建, 脚本的C++功能代码可以写入子类的OnExecute()方法
  • ScriptServer类是脚本系统中仅有一个脚本语言相关的类, 它会把Command对象注册成新的脚本命令, 并且把命令参数在脚本语言和C-API之间做翻译.

这个观念比Nebula2更为简单, 最重要的是, 它不会跟Nebula3的其它部分交织在一起. 甚至可以通过改变一个#define来编译一个没有脚本支持的Nebula3.

当然, 书写脚本命令的C++代码跟Nebula2一样烦人, 这是NIDL的由来. NIDL的是全称是”Nebula Interface Definition Language”. 基本思想是通过为脚本命令定义一个简单的XML schema并把XML描述编译成派生了Script::Command的C++代码, 来尽量减少书写脚本命令的重复性工作.

对于一个脚本命令必不可少的信息有:

  • 命令的名称
  • 输入参数的类型和名称
  • 输出参数的类型和名称
  • 对应的C++代码( 通常只有一行 )

还有一些非必须, 但是可以带来便利性的信息:

  • 关于命令的作用和每个参数的意义的描述, 这可以作为运行时的帮助系统
  • 一个唯一的FourCC(四字符码), 可以更快的通过二进制通道传输

大部分的脚本命令翻译成了大约7行的XML-NIDL代码. 这些XML文件再用”nidlc”NIDL编译器工具编译为C++代码. 这个预处理是VisualStudio完全集成的, 所以使用NIDL文件不会为程序员代来任何困难.

为了减少乱七八糟的文件(编译生成的), 相关的脚本命令被组织到一个叫作库的集合中. 一个库由一个单独的NIDL-XML文件表示, 并且它只会被翻译一个C++头文件和一个C++源代码文件. 脚本库可以在程序启动时注册到ScriptServer, 所以如果你的应用程序不需要脚本访问文件的话, 仅仅不注册IO脚本库就可以了. 这会减小可执行文件的体积, 因为连接器会把没有用到的脚本库丢弃掉.

最后, Nebula3放弃了TCL作为标准的脚本语言, 而采用了运行时代码更加小巧的LUA. LUA已经成为游戏脚本的准规范, 这也使得寻找熟练的LUA关卡设计师更加容易.

本文转载自:http://www.cnblogs.com/flying_bat/archive/2008/12/14/1354937.html

rise-worlds

rise-worlds

粉丝 2
博文 1755
码字总数 0
作品 0
深圳
程序员
私信 提问

暂无文章

“旧城改造”的背后——银泰新零售阿里云解决方案(上)

相关免费课程《银泰新零售上云解决方案精讲》上线中 立足实战 讲透经典案例 助你快速理解新零售 第一节学习地址 第二节学习地址 传统线下商业体上云的案例 与其说银泰上云,倒不如说银泰“旧...

阿里云官方博客
4分钟前
0
0
记一次升级Oracle驱动引发的死锁

问题描述 近期项目需要从虚拟机环境迁移到容器环境,其中有一个项目在迁移到容器环境之后的两天之内出现了2次“死锁(deadlock)”的问题,部分关键日志如下: Found one Java-level deadlock:...

ksfzhaohui
6分钟前
0
0
MySQL 中的 information_schema 数据库

欢迎查看原文 - 本博客仅记录 https://blog.csdn.net/kikajack/article/details/80065753 -- 是否开启bin_log日志: off为关闭-- show variables like 'log_%'; show variables like '......

莫库什勒
14分钟前
0
0
Random在高并发下的缺陷以及JUC对其的优化

Random可以说是每个开发都知道,而且都用的很6的类,如果你说,你没有用过Random,也不知道Random是什么鬼,那么你也不会来到这个技术类型的社区,也看不到我的博客了。但并不是每个人都知道...

编程SHA
19分钟前
0
0
T5大牛带你解析:如何实现分布式技术

1.分布式事务 2. 分布式锁 Java 原生 API 虽然有并发锁,但并没有提供分布式锁的能力,所以针对分布式场景中的锁需要解决的方案。 分布式锁的解决方案大致有以下几种: 基于数据库实现 基于缓...

李红欧巴
31分钟前
31
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部