3月27日,虚幻引擎Unreal Circle线下技术沙龙在深圳开幕。其中,太空FPS游戏《边境》的开发商柳叶刀工作室CEO李鸣渤(Frank)带来了有关虚幻引擎使用经验的精彩分享。
《边境》是整个索尼「中国之星计划」首曝的第一款游戏,是当年国内极其罕见的小团队使用虚幻引擎开发的独立游戏,凭借出色的“失重太空战”游戏玩法概念、以及次时代画质,一经曝光即获得了国内玩家的高度关注,2019年,虎牙还签下了《边境》代理权。根据计划,《边境》将是一款面向全球市场的产品,会有 12 个国家和地区的本地化内容,全球将同步上线(PS4 和 steam 双版本)。
那么这样一款有口皆碑的游戏是如何开发的呢?尤其是小团队如何掌控难度颇大的虚幻引擎?
在演讲中李鸣渤介绍,柳叶刀工作室刚刚成立的时候团队仅仅只有4人,在4年左右的时间里,团队长期保持在7-14人的开发规模。慢慢的团队开始发展到40人左右,所对应的开发管线也逐渐发生变化,对于管线的优化帮助团队之间更好的协同,提升项目的产出效率。
以下是演讲实录:
李鸣渤:大家下午好,我是柳叶刀的Frank,我今天分享的大概是我们过去5、6年中无数杯咖啡后,我们做的UE4开发管线历程,这可能是一个与直接的开发技术关系不大,但与开发流程密切相关的东西。
在讲之前首先介绍一下我自己,我大概是在2002年加入游戏行业,那一年我去了英国学习,并找到了我人生中的第一份游戏工作,一直呆到了2014年。英国的十二年期间,我做的大多都是3A级的游戏,只做过两种类型的游戏,一种是射击类另一种是开车类型的游戏。
我们柳叶刀做的一款游戏叫做《边境》,是一款5V5的多人对战太空射击类游戏。公司最开始组建的时候仅仅只有4个人,除了管线管理、项目管理、公司运营之外,我们四个人覆盖到了整个游戏开发产品制作的所有方面,包括技术、美术、创意以及一些音乐音效。
因为我个人是从3A工作室出来的,然后我的合作伙伴他们是从腾讯出来的,我们一直都是在成熟管线团队中工作了很多年,可能知道在这当中如何使用管线,我们只是使用管线中的一环,但是我们没有独立搭建过管线,所以当我们自己开始做工作室的时候,我们大致能够了解想建一个怎样的管线,要建成怎样?其实我们没有任何经验。
首先我介绍一下我们只有7人时候的管线。那个时候的管线其实非常简单,当时,无论是技术、美术还是设计部门都有一台电脑,电脑上所做的开发环境是一摸一样的,要安装所有的开发软件,美术的软件、设计的软件和版本控制的软件等。
版本控制的软件,我们使用的是Perforce,因为在我的职业生涯中只使用过一种版本控制软件就是Perforce,这也是选择它的主要原因。我们最开始设计版本控制的时候非常简单,我们只有一个分支,就是主开发分支,当时我们四个人都工作在一个分支下。
UE非常大的好处是,已经把这种版本控制的软件集成在了引擎中,不知道大家平时工作中有没有发现,UE把Perforce、SVN、Git等集成在其中,我们就是通过这样的方式让美术、设计部门使用Perforce,程序部门就不用说了。
开发流程这一块比较简单,对于美术与设计师这两个部门所产生的资产向上提交,问题都不是很大,因为不需要改代码,不需要重新编译编辑器等等,不会对项目、对其他人造成致命性的伤害。但是工程师是会对项目造成致命伤害的,工程师往往提交一段其认为可靠的代码时,早期的时候可能会引起巨大的混乱。
当我们扩展到7~30人规模的时候,如果继续使用这样的开发方法,我们发现了很多的问题。首先是一种恐惧感,相信各位美术或者设计师打开visual Studio的时候都会十分恐惧,生怕把整个游戏弄垮了,这种恐惧可能对于美术就有天生的杀伤力。
我们当时的流程就是,当工程师将代码提交到版本上,每一个其他的成员都需要将这一段代码拉到本地端,然后他们做的第一件事就是,打开visual Studio然后如果引擎有修改就要编译引擎,游戏有修改就要修改游戏,这对于除了程序之外的很多人是有恐惧的。其实,程序在内的人也会或多或少的有恐惧,特别是当有新的东西需要往下拉,然后去编译的那一刹那。
UE中有一个非常好的插件叫UnrealVS,它在visual Studio提供了一个非常好的界面,在其中能够选择工程、设置、平台,比如就如这张图中,我可以将UE引擎放在第一条,将项目放在第二条,这样当你编译的时候一切就解决了,这大大的缓解了美术的焦虑感,也缓解了一些程序的焦虑感。
对于美术与设计师打开visual Studio是需要勇气的,为了克服这种障碍,还有一种方法,就是使用了一种命名行的形式来进行对游戏引擎的编译。这个时候技术部门写了一个自动化的编译脚本,让广大美术的爱好者执行这个脚本,然后选择想要做的事情开始编译。其实与刚才说的UnrealVS做的事情非常类似,只不过UnrealVS提供了一个非常好的图形交互性的界面,而这个就是纯命名行,不需要打开visual Studio,只需要打开脚本编译。
还有一个灾难,当时我们所有人都工作在一个分支下,所以工程师在工作中会遇到一些难以避免的问题,有的时候工程师在提交很多内容的同时,忘记提交一些本地已经修改过的代码,或者修改过的资产,这个时候工程师在本地工作一切良好。因为Perforce并不负责检查工作,只负责管理的工作,所以Perforce实际已经垮掉,但是隐性的,谁都不知道。
美术与设计师看到后,就会拉取新的东西,可想而知那天早晨会发生什么。美术与设计师拉取了代码,打开visual Studio编译了这段代码,游戏没办法运行了,甚至没办法编译通过,这个时候,所有的美术与设计师就会非常紧张。
所以,我们在分支上就做了一个这样的架构,把这种人为的错误通过分支的架构隔离出来。原来我们所设置的主分支就变成了最高层的分支,每次的Release就从这个分支发布,这个分支是永远不能让人来碰的。在这底下还有一级开发的分支,如果有新的特性开发,就在这一层级中开发,并且也在当中完成,直到有一天达到稳定可以发布的状态就会提交到Main,在Main中足够稳定了就会继续发布,这两级开发的分支是不允许任何人手工交付。
在下面,我们又开了另外几个分支,因为我们是采取的敏捷开发方式,所以一个Spring是两周的时间。然后我们还引入了CEO概念,两个Spring是一个CEO,每一个CEO就会开一个类似这样的分支,好处就在,当大家在某一个分支上开发过长时间,对于美术与设计的恐惧感增加的不强烈,但对于程序而言有强烈的恐惧感,因为会或多或少的认为这个分支被污染了。所以我们每一个月(四周)后就会完完全全的换一个新的分支,减少了一些比如资产隔离上的工作,而且会给团队带来一些安心感。
那么每一个开发者是如何工作?其实每一个开发者的工作是建立在这之下的,他们会拥有自己的分支,这样的好处显而易见,当一个开发者工作在这个分支下,做了无数的事情,即便将这个分支弄的非常混乱,但这一级对于其他的开发者是完全隔离的,除非他把“有毒”的代码提交上去,而这一级我们是通过人工的第二次审核隔离。如这张图所示,程序提交“有毒”的代码,最容易出现问题的就在这一级。
为了解决这一问题,我们引入了持续化集成这样的成熟理念,当时市面上有四种软件可以让我们使用,Jenkins、TeamCity、CircleCI、ElectricCommand,当我们用了Jenkins和TeamCity后,我们认为TeamCity会更友好一些,最终选择了这个软件。
这时候我们的流程就会变成这样,当工程师提交一段代码到Preforce的服务器后,TeamCity所做的第一件事情就是先检测,你可以将它看作是一个机器人,它会将代码打包验证,但仅仅只能验证这个包能否顺利的编译通过,它只做这一件事。
当TeamCity认为代码OK后,美术与设计师就可以将代码拉取出。这样的架构或多或少的帮助我们有一定效率的隔离“惨案”的发生,并且这样的架构有一点好处,我们能够根据TeamCity来检测每一个代码的健康性。
做UE的游戏其实有两件事情,第一就是如果修改代码的话需要编译编辑器,第二件事情如果修改代码必须打包游戏让每个人去玩,刚才所做的都是编辑器,是为了让每个人都拿到健康的编辑器版本。那么对于游戏的编译,我们采取了另一种方式,美术、工程师、设计师等提交代码到Perforce后,TeamCity进行检查并打包游戏后存到我们的文件服务器上,然后把我们每一次提交打包游戏的版本存了下来。
我们在TeamCity上使用的还是BuildCookRun,以命令行的形式出现,这是我们大致上打包的命令,包括命名方式、打包时间等。
这个是我们文件服务器所看到的样貌,大家可以看到,每编译好一个成功的游戏包,在这个服务器上就会将每一个版本的游戏一次存档。
刚才所说的都是游戏端所发生的事情,UE4的开发工程是由两部分组成,一部分是游戏端,另一部分是引擎。引擎是什么概念,当每次有引擎升级的时候,比如从4.1升级到4.2、4.3,这是引擎端的工作。我们最早做的流程是找到UE4版本控制的服务器,拉取到本地,而后提交给Perforce。当时做这段事情的时候,中间基本是手工完成,这是非常痛苦的事情,首先国内的线路连到海外质量一般,第二个是UE4 Depot的规格非常庞大,造成了过程十分痛苦。
但是会发现,这其实是一个很简单的问题,并不应该去用“人”来干涉的东西,当时我们部署了TemaCity做的另一件事情就是帮我把Epic最新的代码或者已经发布健康的代码自动下载下来,然后我们再集成到Perforce服务器上。
这实际就是TeamCity所干的事情,会发现在这当中有很多的错误,这意味着机器在进行无数次的下载,直到完成,我们就能拿到有效的代码。虽然会花上一两天甚至更久,但不用人为去管理,这是我们下载UE Depot的过程。
还有一个比较痛苦的事情是,我们如何把UE引擎和我们已经自定义过的一些部分的内容如何做到集成,这是一个刚开始非常痛苦的过程。大家可想而知,当UE的代码下到本地的时候,比如4.2与4.3的代码有多少更改内容,我是不知道的,除非要去仔细的查证。我了解的是,我们的引擎端修改了多少代码,所以当我手工的在本地比较这些代码的时候,可想而知,每次升级有上百个文件,都需要靠人工一个个找出来,然后还需要去询问开发者这个代码是我们做的还是Epic做的,这是一件很痛苦的事情。
所以我们建立了这样的架构,首先我们做了一个UE Release的分支,只负责拉取UE官方发布的内容,在这里我能够直观的了解到有效的更新都是什么。然后我们在中间建立了一级分支,这与我们开发的代码分支是分开的,通过这一级的东西来集成Epic下来的东西以及我们上去的东西,通过这一分支解决冲突。好处是当用了有这一分支后,整个Perforce系统会把所有能够自动解决的冲突全部解决掉,我的注意力就能够集中在少数几个有冲突的部分。
我们最早的引擎升级大概在2~3个月的时间,会发现我们早期的升级都是偶数级的升级,比如4.10、4.12、4.14等,因为我们需要花两到三个月的时间做这样一件事。当做完了这样一套架构后,把我们升级的时间缩减到了一周到两周内。
我们现在已经从去年底的20多人已经升级到了40多人的团队,我们面临更多的问题,所以我们正在做的事情就是,完全的让美术与设计克服visual Studio恐惧症,将visual Studio从美术的电脑中彻底根除,这是一件非常重大的事情。
我们在下一步要做的事情是,TeamCity需要帮我们部署InstalledBuild的引擎,我们在拿到源代码引擎后可以编译出,可以部署、不需要再编译的引擎,这是引擎端。第二件事情就是,TeamCity帮助我们部署游戏端所产生的二进制动态库,有了这两件事后,我相信美术与设计应该可以从visual Studio的恐惧中彻底的解脱。他们所用的是一台新机器,安装了Proforce后,只需要在Proforce端拉取已经编译好的引擎、拉取有效的二进制动态库的游戏,就能够无障碍的进行工作。
在shader编译还没能实现分布式功能前,它只能通过一个线程来编译shader,可想而知当打开这一个editor后,会花上1~2个小时。所以我们需要通过TeamCity帮助大家编译所有的shader,放在一个有效的文件夹中,这个我们叫Shared DDC。第二件就是把Build Lighting这件事情放在TeamCity上做。
最后,因为现在我们要打包的东西很多,所以TeamCity上花费的时间也会变长。我们是一款多人对战游戏,所以每一次验证都是从editor到客户端游戏,再到服务器端的程序,还有不同平台上的包。所以,打包时间会变得很久,这是我们需要优化TeamCity的原因,也是我们正在做的事情。
以上就是我分享过去几年的历程。
,