Case Studies

Bugbear Entertainment

从漫长的彻夜编译到使用 SCon s和 Incredibuild 持续集成多平台资产编译

2010年2月24日 – Timo Kämäräinen,Bugbear Entertainment

关于 BUGBEAR ENTERTAINMENT

Bugbear Entertainment 位于芬兰赫尔辛基,是一家有着业界殊荣的领先级独立动作游戏娱乐工作室。它成立于 2000 年,专注于动作竞速和终极破坏类游戏。

www.bugbear.fi

关于作者

Timo Kämäräinen是 Bugbear Entertainment 的技术总监,主管 Xbox 360、Playstation 3 和 PC 游戏开发的各个方面。他曾是 Sega Rally 公司 PSP 分部的首席程序员,并曾负责 Playstation 2、Xbox、Xbox 360 和 PC 平台的 FlatOut 系列游戏开发。

摘要

本文介绍了Bugbear如何从漫长的彻夜编译转型为面向多平台(包括Xbox 360、Playstation 3和PC)的连续集成编译,以及这样的转变对整个团队有着什么样的意义。前面已经介绍了代码编译,这里将重点介绍使用 Incredibuild 进行的基于SCons的资产编译,以及编译时间在连续集成中的总体重要性。

人人自危的氛围

在使用涉及漫长彻夜编译的旧编译系统的情况下,每一项最新编译的实现一直都无异于一场赌博。编译崩溃司空见惯,必须手动热修复,否则,至少在开展下一次彻夜编译之前,它们会一直保持破坏状态。同时基于三大平台的工作通常也意味着,如果在很少使用的配置上编译和运行代码,将产生不可思议的错误,只有在彻底清除这些错误之后,才能开展任何其他任务,这就意味着,相比漏洞修复,在查找漏洞上耗费的时间要多得多。紧密合作的程序员和设计师必须手动将资产或可执行文件复制给彼此,以便确保工作同步,这通常会形成“非正式”编译,在出现新资产或可执行文件时,这些编译非常容易崩溃。这就产生了一种人人自危的氛围,除非编译崩溃(在达到某个点时,必然发生这种情况),否则没有人愿意更新工作。

难点

必须采取应对措施,连续集成似乎就能够解决其中的大部分问题。虽然必须要改善代码编译时间,但很显然,在打造全企业范围内的连续集成时所面临的最大挑战之一将是资产编译时间,必须大幅缩减这个时间,才能在一天内多次运行编译。旧系统基于每个轨道(或层级)来分配手动配置的编译过程,这就意味着,编译过程所耗费的时间与最大轨道的编译时间一样长,同时已经完成较小轨道编译的机器则只会闲置下来。

不同于数量只有数十个的轨道,每个平台的被处理的编译数据包含成千上万的文件,因此,需要根据每个文件分配编译。另外,很显然,必须在编译系统自身中检查增量编译的依赖性,而不是像单独的工具那样,在当时执行时间戳检查。这就不需要通过网络分配无需处理的文件,对于数据总量约为1至8 GB(取决于项目阶段)的处理资产,这是需要关注的方面。

备用方案

一旦确定了相关需求,我们就可以考虑各种编译工具和分配软件。对于我们而言,最重要的需求是,编译系统应尽可能像分布式环境一样开展本地工作,并且所有三个平台的代码分配以及资产分配最好应受到同一分配系统的控制,以便最大程度提高效率,简化维护。由于希望尽可能简化新系统构建,我们很快排除了为此创建和维护一个内部工具的想法。

解决方案

作为一款编译工具,Scons 似乎能够满足我们的需求——它能提供基于 md5 的依赖性检查、支持并行编译、基于 Python 的可扩展性以及用于编译结果的缓存系统。对于 Xbox 360 和 PC 代码编译,Incredibuild 似乎是一个可行的选择,但影响我们决策的真正因素是,通过 Incredibuild 的 automatic interception 接口实现了对 SCons 和 PS3 代码编译的开箱支持。我们采用另一款第三方工具来处理连续集成过程的其他方面,如版本控制集成和电子邮件编译故障报告,而 Incredibuild 则将提供编译所需的初始处理能力。

编译农场

尽管我们可以使用闲置机器的备用处理能力来加速编译,但却需要有部分计算机实际上在运行着这些编译。因此,我们构建了单独的服务器机架,其中包含6台四核机器。每台机器将负责同时运行不同的编译,并且还通过Incredibuild结合在一起,形成一个大的CPU专区。这种构建让我们能够连续运行所有编译,闲置编译机器可用作其他编译的Helpers,实现约64ghz的总处理能力。

代码编译

代码编译的构建相当简单。这三种平台拥有各自的编译运行机器。Xbox 360和PC代码藉由对Incredibuild原生Visual Studio的支持进行分配,PS3代码编译则通过 Incredibuild 的 automatic interception 接口加以分配。通过对代码编译过程进行分析,尤其是涉及Xbox和PC的情况,我们发现,一旦参与编译的核心达到足够数量,磁盘访问便开始成为瓶颈。因此,我们最终使用了内存容量为16GB的64位Windows设备,中间编译数据则存储在RAM盘上,以便进一步加快编译速度。

资产编译

将旧编译批处理文件(曾经只是一个简单的批处理文件)更改为基于SCons的编译脚本,比直接的代码编译要复杂一些。这是随时间推移逐渐实现的,最初,旧批处理文件用作SCons中的一系列虚拟生成器。这些虚拟生成器将运行批处理文件的某些部分,这样,我们就能够即刻改善编译分配。即使使用这种基本的编译分配,在借助 Incredibuild 的情况下,编译时间也会得到改善。但这种方法不会提供合适的依赖性检查,而且也不会根据每个文件来执行这种分配。

就资产编译的典型内容而言,纹理和几何的数据量相对于其他文件通常非常大。另外,对于我们来说,它们的处理还要耗费最长的时间,而其中的纹理压缩是最为耗时的过程。

作为全面分布式编译的第一步,我们先将编译过程的处理纹理和几何数据的部分转换成适当的 SCons 生成器,这进一步提升了在使用 Incredibuild 情况下的编译时间。同时,这意味着纹理压缩和几何处理根据每个文件分配执行。

即使几何分配是根据每个文件来执行的,文件本身也会包含用于整个轨道以及其中所有对象的几何数据。为了通过分配进一步改善编译时间,并同时改善设计师的工作流程,我们对几何管道进行了一些重大修改。以前,每次修改任何几何部分时,工作流程都会涉及处理整个轨道。新系统允许使用包含独立文件的对象库,这些独立文件能够实例化为轨道。虽然这让设计师仅能够更新自己的工作对象,但同时,它也允许几何编译过程在单独的SCons生成器中处理每个几何文件,以便实现最大程度的编译分配。

渐渐地,整个编译系统变得能针对各种类型的任务(如着色器编译、基于xml的数据生成等)使用合适的SCons生成器。它的另一个优点是,我们现在能够获得由编译系统执行的依赖性检查,从而能够为资产执行合适的增量编译。将这与 Incredibuild 提供的编译时间改善相结合后,连续集成系统能够动态处理任何类型的修改,即便固有的编译依赖性将使所有纹理在当天中再次压缩。

益处

即便采用了专用硬件编译农场,如果没有 Incredibuild 提供的编译分配,也无法达到当前水平的连续集成。得益于我们编译处理的高速度,我们能够在通常不需要的编译中添加代码配置,比如调试编译,可从每次代码提交后的编译和测试中受益良多。另外,让系统动态编译所有资产也意味着,我们能够在每次代码或资产提交后对整套产品运行测试。

较之于在一天内针对每个平台运行一次编译的旧编译系统,新系统平均每天能够针对每个平台运行约20至30次编译。每次编译包含三个不同的单元测试代码配置——调试、开发者和版本,同时还包括资产乃至简单的功能测试,以确保新代码或资产未导致编译崩溃。所有这些的周转时间约为15分钟。这对编译的稳定性有着极大影响,因为崩溃的编译会被尽可能快地检测到,并立即得到修复,而不是到第二天才修复。

在稳定性改善的同时,团队士气也得到了明显改善——大家不再担心更新编译,人人自危的氛围逐渐消失。

总结

编译周转时间在连续集成中起着重要作用。Incredibuild 为我们提供了必要的工具,助我们改善编译过程,全面利用连续集成,进而确保每位团队成员即使在游戏开发的早期阶段也能够持续运行稳定的编译。