posts - 4,comments - 15,trackbacks - 0

这两天,有关游戏引擎脚本系统的预研还在继续。在google上找了一些资料来学习,目前网络上这部分的资料是比较少的,主要还是在gamedev上有一些相关的主题。泡了两天的鸟文论坛,做了一打的摘录。现在整理一下思绪,感觉脚本系统的轮廓已经比较清晰了,但还有很多细节需要去了解,后续会对这些细节再慢慢研究道来。

 

脚本的基本特性

1、从语法的角度来说需要支持到顺序、条件、循环,并且最好语法接近某种成熟语言(比如C),这样有利于学习&使用;

2、性能,性能,性能。要在实时的游戏里面发挥作用,性能无异是贯穿始终的话题。

 

语法功能解决方案

1、可以选择一门成熟语言作为借鉴;

2、删掉不需要的Keyword,裁剪语言元素。特别对于C语言,完全去掉有关函数声明等部分可以大大降低parse&excute的复杂性。

 

脚本库

1、脚本语言的函数库比脚本语言的语法更加重要,这个说法的出发点仍然是性能。在上一篇文章中,我有提到“冗余”的概念,就是这句话很好的体现。尽量将复杂的函数功能封装在游戏引擎本身,而不要在脚本中编写这些函数,甚至可以在脚本中不提供用户自定义函数的功能。

2、提供给用户(脚本编写者)完善的库函数集,从环境配置命令到信息查询等等。用户用这些函数来控制游戏环境,脚本语法只是提供分支&循环控制。 

 

事件响应

1、上篇提到“事件”(event)指的是所有外设输入的统称,这种说法是不全面的。除了外设输入,事件还可以由游戏引擎内部来触发,比如timer事件,这里做一个小小的更正。

2、事件包含一些参数,参数的内容是“哪些Object要响应”&“事件类型”。

3、一个脚本可以调用其他脚本,实现脚本之间的通信。

4、事件,可作为脚本系统&游戏引擎的连接,也就是说,游戏引擎只有在处理事件的时候才会调用脚本系统,而脚本系统的唯一任务,就是响应事件。

5、再次强调一下,事件不是只能有游戏引擎内部的object来触发,还有timer、startUp、sceneEnd等等。

 

脚本运行模型

1、每个脚本都可以“挂”到任何数量的object上去;

2、每个脚本都可以看作是独立的虚拟机,拥有自己独立的变量、堆栈&运行点(execution pointer),这一点我自己有保留的想法,出于性能原因,可能独立虚拟机的概念难以实施,需要进一步寻找变通的方法。

 

访问控制

1、上篇提到脚本需要能读取&改变游戏引擎内部object的属性,这里需要注意一个问题:让脚本直接访问object的属性是很危险的事情,出于defensive coding的考虑,个人认为不应该让脚本直接地来访问内部数据,而应该提供库函数,通过库函数来对内部数据进行访问,这样做的好处是:将边界检查等等安全性工作加入了进来,并且让脚本编写者在编写脚本的时候不用对安全性进行考虑;坏处是:肯定效率是有所降低的。(或者还有更好的办法?想想。。。)

 

库函数

1、库函数的实质是C/C++(引擎编写语言)的函数指针,对于脚本系统来说它们是可见的全局symbols。这里引入两个小话题:一是在引擎初始化的时候,需要注意建立这些函数的入口地址表,让引擎在需要调用的时候有表可查;二是,java呢?有没有类似函数指针的东西?(这里属于实现阶段的问题,我只是提出,没有去研究)

2、脚本运行的时候,如果遇到调用库函数,则跳转到native C/C++代码去。这里存在运行环境切换的问题,从脚本语言的堆栈里弹出参数,传给native C/C++函数来执行,执行结束以后,返回结果压入脚本语言的堆栈中。如果把游戏引擎看做虚拟机,那么脚本系统就是嵌套在这个虚拟机里面的虚拟机,^_^,拗口哦,不知道您明白了没有?

==================================================================================================== 

以上讨论的,是运行与游戏引擎部分的脚本系统。以下的,是有关脚本本身的一些讨论,这个应该归属于游戏制作工具的一部分。

====================================================================================================

编译

1、当然,这个步骤叫“解释”,与C语言一类编译式语言有所区分的话更加准确。但由于在做法上跟C是类似的,所以也可以叫“编译”。

2、两个阶段:一是把脚本源代码拆成语言元素,token,不知道这个用哪个中文表达好,编译原理学了都忘了;二是把所有token组织起来,组成基本命令序列。

3、什么“基本命令序列”?刚才不是说把脚本看过虚拟机吗?这个“基本命令”就相当于这个虚拟机CPU的机器指令或汇编指令。也就是对于这个虚拟机来说的可执行代码。

 

“汇编指令”

1、为了简单,就把脚本这个虚拟机设计成单堆栈的吧。

2、基本的命令包括:push,pop,go,stop,callfunc,add,asign等等。

 

举个小例子吧:比如写了如下的脚本(语法上近C)

a = 1 + 2;

通过编译,变化成如下的“可执行序列”:

push 1

push 2

pop   // store 1

pop   // store 2

add   // store result

push 3   // push result

pop   // store 3

pop   // var name a

asign   // a = 3

这里只是示意,可能与实际实现有出入。

 

这篇略显枯燥了,聊点轻松的。一直在强调脚本语言的性能问题,来看看 各种语言性能比较 吧。LUA好像在脚本语言里面排名靠前呵,我正好也下载了它的源码,并在VC上编译好了。在Python&LUA之间犹豫了一下,还是选择LUA吧,比较小,简单,Python目前已经做得很复杂了。再说偶的脚本系统里面目前不需要提供自定义函数机制,也不需要OO滴,看看几个月后能不能作出自己的脚本语言来?到时候再跟Python等等一较高低!:)

好戏在后头哦,下期开始实际以LUA为例子研究脚本系统了。。

posted on 2007-06-01 22:35 tianlinux 阅读(1165) 评论(2)  编辑  收藏 所属分类: 脚本语言

FeedBack:
# re: 游戏引擎脚本系统(二)
2007-06-07 19:25 | lyjyl
懒人快更新  回复  更多评论
  
# re: 游戏引擎脚本系统(二)
2007-09-27 11:15 | guafeng
嗯,不错,继续写LUA的东东撒。  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航: