设计日志二:脚本系统

来源:互联网 发布:单端口环路检测 编辑:程序博客网 时间:2024/04/29 19:31

设计日志二:脚本系统

根据经验,修改程序的速度远远赶不上策划修改游戏设计的速度,如果用流程强制他们减慢改变的频率,也就限制了他们的创造力。如果能让他们自己做些修改和尝试,将大大提高游戏的整体开发效率。脚本系统正是用来解决这个问题。

【脚本语言的选择】

单说脚本系统是个很宽泛的概念,几行配置文件算是脚本,一个完整的编程语言支持也算脚本,Word里可以记录的宏也是脚本。让我们定义一下游戏引擎里需要的脚本系统的需求:

1. 足够的表述能力,足够用来定制游戏。
2. 较快的运行速度,性能要好。
3. 足够简单,毕竟策划一般不是程序员出身。

第一条就意味着需要一个脚本编程语言,来编写一定量的游戏逻辑规则。那么就可以把范围缩小到主流的脚本语言:JavaScript,Python,VBScript,Lua。由于.NET对其上的每种语言都提供编译器编程接口的支持,.NET上的所有语言也都可以被用做脚本。其它可能的选项还有PascalScript,AngleScript,Squirrel,CScript等。

JavaScript看上去是个非常好的选择,因为由于Web的关系,今天大多数人都多少接触过它。但JavaScript集成接口非常复杂,而且这些接口都是针对浏览器设计的,似乎有不少人试图集成过但都铩羽而归。另一方面,JavaScript的速度并不快,这也是Google的浏览器把优化JavaScript运行器作为亮点的原因。不过,.NET自带的JScript.NET吸引了我的注意。首先,它是在.NET平台上的,非常容易集成,和调用其他的.NET库没什么区别。其次,它是半编译执行的,所以速度也没的说。但是问题在于,JScript.NET是个失败的产品,微软已经停止对其的开发,而另起炉灶,在DLR上重新开发了Managed JScript。这就是另外一个话题了,有兴趣可以到IE的blog上去看。

Python功能非常的强,且非常的完备,它其实就是一个完整的应用开发语言。有不少游戏用了Python做脚本。它的问题也很单纯:速度慢,集成不太容易。Python也有对应的.NET版本IronPython和类似的Boo,不过个人总觉它们都有点“非主流”。VBScript则只能算是一个简化的Visual Basic,并不具备主流脚本语言的很多特性,数据表达能力差。用C#做脚本也有和VBScript一样的问题,而且对策划人员来说,它太复杂了。

那么Lua似乎是最好的选择,小且快,容易集成,数据表达能力强(最早起源于一个结构化数据文件的解释器);缺点是语法有点另类,过于松散。很多人都已经知道,Lua是游戏行业中用得最多的脚本语言,魔兽世界用的就是Lua脚本。Lua的数据表述能力几乎可以同时兼用作数据文件,而不必再制作额外的数据格式解析器。

【脚本的职责范围】

有了脚本也就有了强大的定制能力,但这里有个矛盾:让脚本做得越多,系统的可定制性就越好,但脚本的复杂度也就越高。这个权衡是要看每个项目的具体情况的。我的情况是,引擎只假设了某一特定类型的游戏,但具体的游戏规则,游戏的玩法都是脚本定制的。也就是说,这是一个很宽泛的系统,也就意味着脚本可能会比较复杂,需要掌控游戏的逻辑的各种可能的组合。这种复杂性并不是非程序员背景的人所擅长的,所以必须进一步的简化。

有所得必有所失,为了简化必须进一步限定引擎的适用范围。我选择了以为数据中心的脚本模式,即脚本不编写流程逻辑等控制逻辑,而只关注和操作数据,并在各种事件中处理和修改数据。不要误解的是,这是大的设计方向,而并不是说100%都要这么做。这样对策划人员来讲,他们面对的是一个游戏的后台数据库(只是概念上的数据库),他们只需操作这个数据库,而不需要关心程序具体是怎么运作的。同样,这个数据库的结构也是允许策划做定制的。

这样脚本中的与引擎的交互功能分成四个部分:
1. 游戏定义数据库的定制和填充
2. 游戏数据的访问查询
3. 会被引擎调用的各种事件触发的函数
4. 修改数据和发出控制命令的API

其中,2和4是引擎提供的API,1是设计数据表的结构并设计数值,只有3是需要脚本实现的。已经算够简单了吧,当然无论怎么简单和策划们的期望还是有差距,毕竟脚本还是要写程序。对策划来说,最好是在图形界面里,点几个菜单,设置几个参数。如果我们编不出这么强大的编辑器,就只能编个足够强大的理由,比如:专业做游戏的工具自然要专业一点嘛,如果这东西简单到阿猫阿狗都会用,还要我们这些专业人士干嘛?-_-b

【脚本API风格的选择】

之后就是如何提供引擎的功能给脚本操作。为了使脚本编写尽可能的简单,最初的想法是使用纯过程式的API(应用编程接口),也就是提供像C函数库那样的编程接口,这样就不需要脚本开发者了解任何OO的知识。但后来随着提供给脚本的功能越来越丰富,这样的API就变得不好用了。重新考虑一下这个问题:OO的复杂性并不在使用上,而在类的设计上。VB(.NET之前的)作为被用得最多且最简单的语言之一,同样支持对象的概念和使用,只是没有提供编写类的能力,这种方式被称作Object Based(基于对象)。那么,合理的选择应该是,提供基于对象的API,但并不要求脚本开发者派生或编写对象。

不过,由于Lua对对象的支持是半路出家,访问对象属性是用obj.property,而调用成员函数却要obj:func(),这个差异非常的不顺手,我自己都经常用错。

原创粉丝点击