内容概要
2009年开始,我在之前《功夫Online》的引擎经验之上结合对Unreal Engine 3的理解,开始构建自已的新一代3D引擎,这篇文章是当时对于混合语言编程在游戏开发中应用的一个总结。

【欢迎转载,请注明作者:房燕良,原文出处:游戏程序员的自我修养

前言

为了搭建新的技术平台,我在2009年,大概花去了半年的业余时间去试验混合语言编程的具体方案。早在几年前我就曾经感慨过,作为游戏开发者只掌握C++语言已经不够了,必须再掌握一种开发效率高的动态语言。很多人说C++过时了或者C++渐渐淡出主流了,我想至少在游戏开发领域不是这样,C++依然是不可或缺的,但是“只掌握C++已经不够了”!可以说底层使用C++,上层使用一种高级语言是我在开发《功夫世界》项目是就确定的长期目标;后来在开发《神兵传奇》的时候,其实也算是这样一种架构,我们使用的Unreal Engine 3它上层就是使用Unreal Script的,但是Unreal Script的设计还是显得有些陈旧了。上层选择一种什么样的语言,或者什么样的开发平台和C++搭配呢,这是一个问题。

09年上半年我主要实做了两种方案:C++使用Boost.Python包装,上层使用Python语言;C++使用C++/CLI包装,上层使用C#。其实Lua也曾经是一个选择,但是,无奈于我对面向对象已经“中毒太深”,Lua不能直接支持OO,而是需要用什么table去模拟,使我相当不爽。具体如何去比较两个方案的好坏,我个人认为去看别人的评论文章或者是评测结果,都是远远不够的,最靠谱的莫过于自己亲身一试。所以,我使用两个方案,在我的Nexus Engine的上层开发了同样功能的两套编辑器,都开发到了具有一定基础功能的程度。从中细细体会各个方面的问题,包括语言基础特性,标准库,IDE,运行效率等。接下来我讲主要说一下自己这个过程中具体的体会,以及最后的结论。

在进入具体细节之前,先说一下我对混合语言编程的一个整体的体会。混合语言编程,其实是大大的增加了整个系统的复杂度,所以,我们并不能追求对于项目中所有人在所有时间都更省力更省心,我们所能达到的目标是对于多数项目成员的大多数时间开发更简便,工作效率更高!既然是混合语言,往往中间需要一个“粘合层”,粘合层需要能够实现两种语言代码的互相调用,并且能够对于跨语言边界的数据问题提供尽量便利的机制。跨语言边界的问题可能包括对象生存期的管理,函数参数转换等等。

我从2008年8月开始,花了大量的业余时间,在原有的引擎框架基础之上,吸收 UE3 的 “Shader 架构”、“Drawing Policy 机制”、“Anim Tree” 等思路完成的一个3D引擎原型,包括编辑器,目前已经上传到 GitHub:

Python方案

Python是属于那种你一眼就会喜欢上的语言,真的很可爱,我非常喜欢他提供的这种统一的对象概念。我也曾深入C Python的源代码,对于它所实现的使用C语言描述的对象机制也深感敬佩,所以我决定首先尝试这种方案。

在粘合层方面几乎没有什么选择,要么是使用原生的C Python API,尝试了一下,细节太多,很容易出错;也找了一些其他开源的包装库,但是真的比Boost.Python都差太多了。Boost.Python的包装代码写出来很漂亮,很简洁。对于对象的生存期,也不用手动处理引用计数,相当方便了。值得一提的是它使用return_value_policy 很巧妙的解决了函数返回值的生存期管理问题。使用Boost.Python可以方便的包装C++已有的class到Python中使用,同样在Python中很方便的去派生这些类。当C++代码去调用Python派生类重载的虚函数的时候,就很完美的实现混合语言的多态。Boost.Python有一个非常大的缺点,就是相当的复杂,需要了解的大量细节,才能放心使用;另外它的具体实现,也只能想象其大体的思路,如果要我读懂它的整个代码,目前我对模板的掌握还达不到这个水平。所以用起来还是有些忐忑。

对于IDE方面,我尝试了很多,例如Wing等,可能是我比较偏好大型的IDE,所以最后我选择了Eclipse+PyDev。用起来还是满顺手的,书写,调试都比较方便,但是相对Visual Studio还是“手感”上差了一点。

因为我们的目标是开发一个游戏的编辑器,所以还需要界面库,我选择了wxPython。

最终花费三个月的时间,从摸索学习,到实现基础功能。

MS .Net方案(C++/CLI,C#)

记得几年前就对这个方案非常感兴趣,不过当时的Managed C++确实让我很倒胃口,那一次尝试就算是失败了。不过听说CLI这一套就是Lippman搞的,有鼓起勇气,这次一试才知道,现在的.Net已经不是当年的.Net了,而且Lippman的野心真的非常大,CLI也真的很强大!

我曾经想,如果使用Python方案,那开发人员只需要掌握C++、Python两种语言就可以了,如果使用.Net的话,似乎更复杂,因为要多一种语言。最后,我发现掌握C++/CLI这样一种新的编程原因,其难度应该说比掌握Boost.Python这样一个库是要低的!

IDE方面就不用选了,Visual Studio。C#代码的书写非常方便,Windows Form的可视化编辑也很方便。调试就更别说了,在单一的一个IDE里能够跨语言跟踪调试!特别是PropertyGrid控件,节省了很多工作量,而且还显得挺专业。

我不能不说我已经爱上了.Net!真的,以前看老外说用C++写引擎,C#写编辑器,还担心这样做会不会很累,现在看,完全是值得的。

还得说一下效率的问题。Python是出了名的慢的,据说比C++慢50倍;而C#代码借助.Net的JIT编译机制,效率损失还是很小的。

最后,使用.Net平台,还有一个最大的问题没有解决,就是代码的安全性的问题。如果客户端发布的EXE可以被很轻松的反编译,那外挂,私服可以说都很简单了,哪位高手有什么好方法,请指点。

比较与结论

最终选择了MS .Net平台方案。其实我是一个Linux爱好者和忠实用户,现在公司的服务器和我家里一台笔记本都装的Ubuntu。这么多年来,一直想要摆脱微软,哈哈。也许是宿命吧,MS还是很强大的。对于.Net平台的强大,我想很多人比我在行多了,所以我也就不深说了,其实我还是一个这方面的新手啊。给我最大的感触有两点:

  1. 跨语言的调试:我可以从C#代码一直Step Into到C++/CLI代码,一直到Native C++代码;我想MS吹的跨语言特性还真不是虚的;
  2. Windows Forms还真是很方便,以至于我很乐于为Menu,ToolStrip等配上小图标,一下子整个界面就显得专业多了,呵呵;

MS .Net/C#对于我、我们这个团队还是一个新东西,肯定还需要很多实践、摸索才行。所以,欢迎有.Net平台开发经验、又对游戏开发感兴趣的朋友加入我们!