Ant Engine 开源
我在自己研发的游戏引擎上已经工作了 6 年了。在 2017 年底,我写下了对这个新引擎最初的构想 。现在回头来看,当初的想法居然都落实了,只有一点例外:我们中途把编辑器从 IUP 转移到了 ImGUI 上。
2022 年,我们启动了第一个用这个引擎开发的游戏项目,它是一个和日本公司合作的动作游戏。后来,这个项目没有走下去就取消了。之后,因为我们的引擎开发组喜欢 Factorio ,便想用自己的引擎在手机上重现一个 Factorio Like 的游戏,这一干就是一年多。
现在,游戏的技术部分基本完成,可以验证引擎的可用性(功能完整、性能达标),只是游戏性方面还有不少路要走。简单说就是还不太好玩。
从一开始,我就希望以开源模式经营这个游戏引擎,但同时又觉得没有得到验证的东西不适合拿出来。既然引擎已经初步可用,现在就应该迈开这一步了。
毕竟引擎是公司的资产,原来我是自己创业公司的老板,但现在公司已经被阿里收购。开源并不是我一个人可以做的决定。最近一段时间,我争取到了公司的支持。甚至,公司不仅同意我将整个引擎项目开源,还愿意把我们正在制作的游戏的代码及其美术资产也捐赠给这个开源项目。这可以方便引擎开源后潜在的用户去理解引擎。
关于这个开源引擎,有太多的东西可以写,我这里先摘录一些我在向公司申请开源时的报告中的一些内容。文字上有一些吹嘘之词,也有一些未经核实的臆断,但总体上可以反应我的看法,一家之言,姑且听之:
为什么需要一个新的游戏引擎?
目前市场上有两大成熟的游戏引擎:Unity 和 Unreal 。为什么有商业游戏引擎,却依然选择自研游戏引擎?Unreal 目前开放了源代码,而 Unity 我们公司也采购了其源代码。所以,掌握源码并不是主要原因。
我们公司赖以生存的网络游戏项目,和 Unity/Unreal 这些游戏引擎所面对的游戏项目,有很大的本质不同。即,几乎所有的网络游戏产品,都处于长期维护状态,并不以创意多产为主的。商业游戏引擎,它给产品带来的便利在于可以速成游戏原型,而在长期维护方面并无太多优势。一旦产品进入稳定期,更多的是需要在产品上慢慢维护和打磨,或是更换非程序资源以较小代价制作衍生产品。针对特定产品,拥有一个易于维护的游戏引擎,成本是逐步下降的。无论是 Unity 还是 Unreal ,它们的维护成本都极其巨大。我们甚至已经放弃了 Unreal 的维护工作,专注于 Unity 的维护,但依然成本高昂。对 Unity 增加项目需要的特性、性能优化、相对一个按项目定制的引擎来说要考虑的问题更繁杂。
维护 Unity ,不光是我们公司独有问题。国内各大游戏公司都花了极大的人力做这件事。最流行的游戏:王者荣耀、原神等都声称对 Unity 做了极大的改造,几乎全部更换了其核心组件。这也是自然的选择:一个全功能的游戏引擎,必然包含了大量单个游戏所不需要的部分,这些都会成为长期的负担,而游戏运营时间越长,它所需要的引擎功能越单一,维护人员需要聚焦在特别需要的功能或优化上,对原版引擎做改造以适应。
Unity 原本并不为我们这类游戏网络所设计,它的资源包打包更新、针对移动设备的优化、和脚本语言(Lua)的整合,从来都是各家国内游戏公司所面临的痛点。国内大厂几乎都购买了 Unity 源码,但至今只听说层出不穷的补丁方法,而未见有对这些改造彻底的方案(包括我公司)。拥有源码的访问和修改权限,并不能解决这类问题。
为什么 ANT 引擎可以胜出?
开源界最近些年也有一些开源引擎,例如 Godot 。但是,我们的优势在于,更理解我们的游戏项目到底要什么,并可以依据我们的理念掌控引擎的发展方向,而不是像 Godot 那样,企图复刻一个开源版的 Unity 。我们从 2000 年开始开发网络游戏,几个大的成功项目均使用自研的引擎代码:例如西游系列、陌陌争霸、三国志战略版。只是它们均为 2D 项目(随着项目发展加入少许 3D 技术),这是因为 3d 技术的门槛要高的多,需要更多的积淀。
业内,游戏引擎技术每隔几年就有新的想法涌现,然后对已有的引擎做大的改造。开始越早的引擎,历史包袱越多,改造就越困难。例如 Unity 推行的 DOTS 技术就是为了解决它低下的性能问题,但好些年了也未能彻底推翻旧框架。后来的引擎可以轻装上阵。我们的开发团队即有长年(超过 20 年)的技术积累,又能不受老架构的束缚。ANT 本身也经历了 6 年的开发,踩了太多的坑,交了许多的学费,这样才获得了技术上的自信。
维护良好的引擎能随着公司的发展获得越来越大的成本效益。自研引擎的弊端在于开启阶段的风险(很可能无法按质完成),初始投入巨大;而这一步,ANT 已经迈过去了。
为什么要选择开源模式?
游戏引擎属于产业的基础设施。游戏产业早就过了通过秘密掌握更好的基础设施以获得竞争优势的时代。基础设施最适合开源。例如操作系统领域,几乎所有提供公众服务的系统都跑在开源内核上。越是基础设施,越需要更好的性能,更高质量的实现。增加开发人员对提高质量并无收益,它需要的是领域专业人员。而领域专业人员在整个世界范围都是稀缺品,并非靠招聘就能解决,一个好的开源项目更容易吸引到这样的人才加入。
同类别的开源项目也有竞争,竞争的是用户和高质量的开发人员。而开源游戏引擎(尤其是 3D )因为门槛很高,竞争并不激烈, 在国内圈子甚至是空白。所以现在做此开源项目有先发优势。一个良好的开源项目长期运营,必须凝聚人和项目,要持续有人用、有人持续开发。一旦人捆绑上去,项目就会像滚雪球一样壮大。我们并不需要掌控技术本身的秘密来获得技术壁垒,掌握项目的主导性就可以获益良多。开源项目的良性发展会不断促进项目本身的质量,远超闭源项目。项目的高质量是极其珍贵的。
Skynet 就是一个极好的正面案例。
Skynet 是一个为网络游戏服务的基础框架。 2012 年 7 月开始编写第一行代码,同年 8 月就以开源模式维持到今天。它为我们公司所有的游戏项目提供了高质量的底层保障,有很多 Bug 甚至是未在我们自己的项目上出现之前就被解决掉的。这得益于它有大量的公司外用户。因为它一直以开源形式开发和发展,吸引了大量的用户。现在在 github 上拥有了 12.4K Star 4.1K Fork 以及 123 个 contributors ,大多数 contributor 不是我们自己公司的同事;部分 Contridutor 后来加入了我们公司。
因为 skynet 被各个公司的项目采用,它的应用面远超我们一家公司的应用场合。这使得 skynet 的发展过程中,会非常仔细的考虑各种边角,保持它的精简,避免它演变为屎山。这么多年没有演化为屎山又反过来给它带来更多的用户。目前 skynet 不光是用于游戏服务器领域,在视频网站、路由器管理方面,也有不少应用。
从搜索引擎的结果看, Skynet 在国内网络游戏圈子,已经是众多中小公司的选择。在招聘网站上,很多游戏公司招聘都会有限考虑有 skynet 经验的候选人。从这个角度,它也帮我们节省了巨大的人力成本。我们因 skynet 树立的技术品牌,吸引了高质量的人才;新加入的员工在进入公司之前就用丰富的 skynet 经验,可以更快的融入工作。
对于程序员来说,也更希望在职业生涯中使用一项活的技术,而不是换了公司,换了行业,就放弃了过去的积累。为开源项目工作可以获得更大的成就感,成就感对顶尖的程序员来说至关重要。
ANT 引擎的特色
ANT 专注于移动平台,在移动平台上,不光要保持帧率更要节省能耗。这会导致引擎结构设计上有所配合,这些是我们在设计时时刻考虑的方面。而且,ANT 区别于 Unity ,它尽可能的让开发工作随时保持在真实移动设备上运行,这对在移动设备上做出更好的交互体验,意义重大。
ANT 基于 Lua 开发,有极低的理解成本,和极高的动态可定制性。以往基于 Lua 这类动态语言开发的基础设施中,最难解决是性能问题,而性能恰巧又已被 ANT 解决的相当不错。ANT 在手机上有极好的性能,我们用它开发的游戏,在及其复杂的场景下,iPhone 12 上依然可以小于每帧 10ms 的速度渲染。对于同等复杂度的场景,Unity 实现同等的效率将非常困难。
因为有几十年的网游维护经验,我们深知资源打包更新这些对项目的重要性。ANT 在这方面做了彻底的支持,方便客户端更新。方便很多美术、策划一起共同创作。
ANT 一开始就设计成易于定制的,不用的特性可以轻松的去掉、渲染管线可以轻松改写。甚至可以方便拓展到非游戏应用中。例如腾讯的 QQ 客户端就集成了 Unreal 引擎,而这项集成至少会增加 App 数十兆的体积;而 ANT 引擎本身只需要链接 1M 的二进制模块。
ANT 引擎的现状
已经开发了 6 年,使用这个引擎开发的游戏有一年历史,技术部分已经全部完成(游戏体验部分还需要调整),性能方面超出预期。
目前只有 iOS 版本完全可用。引擎可以在 Windows 上运行,但缺乏一些和 PC 相关的支持(比如接入 Steam ,更好的键盘鼠标支持)。Mac 版本略有不足,Android 版本尚未完成。
引擎缺少引导性的文档,需要在开源发布前编写一些基本的指导。
目前的游戏代码并不是很好的引擎示例,因为它跟随着引擎最近几次重构,残留了许多不太好的实践。而内置例子只用于测试,还相当不完善。我们还需要制作一个更轻量的 Demo 展示引擎特性。
今天,我已经将 Ant Engine 的私有仓库公开。感兴趣的同学可以自由访问。但这个项目尚未正式发布,该有的文档和实例都很不完善。这是我们正在开发中的游戏使用的引擎,所以至少它是可用的,同时也可能随时被修改。
我会在过年前多写一些文章介绍引擎的结构和设计思路,这也是 skynet 开源初期我所做的事情。等年后,再将我们的游戏代码仓库也开放出来。