在手机上构建《权力的游戏》中的维斯特洛大陆:龙火

华纳兄弟Games Boston 认为,将维斯特洛大陆的世界搬到移动平台上,需要的不仅仅是改编一个备受喜爱的系列作品。以《龙之家族》为基础,权力的游戏:龙火将大规模多人策略和巨龙战斗融合到一款专为现代移动硬件打造的免费游戏体验中。
玩家将扮演瓦雷利亚后裔,负责孵化、饲养和指挥巨龙,同时与成千上万的其他玩家争夺铁王座的控制权。要实现这种梦幻般的体验,需要在各种设备上平衡高质量的视觉效果、可扩展的性能和实时多人游戏系统。
我们与技术总监 Ara Yessayan 和高级技术美术师 Taia Lee 进行了交谈,了解他们如何为移动硬件构建巨龙、支持大规模战略游戏玩法以及使用Unity将维斯特洛世界栩栩如生地呈现在玩家面前。

您在玩家首次游戏体验方面的主要目标和限制是什么?
阿拉·耶萨扬:在第一节会话级别/会话次数中,我们希望让玩家保持专注,避免任何可能打断他们沉浸感的空闲时间。逐步介绍我们游戏的基本规则以及我们要在“龙之家族”的世界中讲述的故事非常重要。
为了最大限度地缩短新玩家和老玩家的加载时间,你们采取了哪些策略?他们的体验有何不同?
AY :对于新安装而言,重点在于尽可能减少预先需要的数据量。我们探索了各种技术,以减少在玩家开始体验之前需要下载或加载到内存中的数据量,并利用过渡时间来处理其中一些加载操作。对于回归玩家,我们需要更多数据来构建您的玩家状态,并将您放在地图上的正确位置。虽然前提相似(尽量减少等待数据),但这些技术更侧重于反序列化成本和减少前期投入的策略方法。

在开发过程中,你是如何发现加载时间方面的最大瓶颈的?
AY:为了解决加载时间过长的问题,我们采用了几种方法。为了全面了解我们的瓶颈在哪里,我们为加载过程的每个阶段设置了自定义分析事件,并将结果写入 CSV 文件。我们汇总了多个用户时长/会话次数中的数值,以确定哪些阶段是热点。我们还将这些转换为 Chrome Trace Events 和 OpenTelemetry trace,以便更好地可视化各个阶段是如何并行加载的。
从那以后,我们深入研究了一个具体阶段。Unity Profiler的 CPU 模块让我们更深入地了解了可以清理的低效代码。在某些情况下,记录多个配置文件并使用Unity Profile Analyzer可以帮助我们评估调整某些加载值如何改善(或恶化)加载时间。
在探索出现严重卡顿的帧时,CPU 分析器经常派上用场,它可以深入分析导致权重下降的原因,并帮助我们找到更好的技术。
除了加载之外,渲染模块还帮助我们深入研究游戏内渲染的效率低下问题,而RenderDoc是我们在需要对运行时问题进行更深入分析时利用的另一个工具。
最后,为了保证用户时长/会话次数顺利进行,我们必须确保内存消耗保持在可控范围内。我们通过内存分析器快照识别出了不必要的资源和对象加载,尤其是在地图和行军区域周围,这反过来降低了进入游戏的加载要求。
您是如何使用 Unity 的内存分析器来分析资源包内存使用情况,包括检测重复资源和验证资源卸载的?您能举个具体的例子吗?
泰娅·李:我们通常使用内存分析器来识别游戏中素材资源在意外点加载并保留在内存中的情况。例如,当一个纹理在多个地方使用,但位于同一个包中时,就会发生这种情况,导致加载整个包,而实际上只需要该纹理。
这也是我们致力于创建特定共享软件包以防止这种情况发生的另一个原因。该工具还有助于发现较大的内存占用问题,特别是那些我们可能没有意识到或超出预期的问题。

早期遇到的最意想不到的性能问题是什么?尤其是在内容交付和游戏性能方面?
AY:令人惊讶的是,加载指示地图布局的地图文件数据竟然需要大量的内存。在权力的游戏:龙火玩家使用军队和巨龙来占领地图上的领土(地块)。这些规则帮助玩家收集资源,并限制玩家可以派遣军队的地点,前提是玩家或其阵营的其他成员必须拥有相邻的地块。
我们知道需要将地图数据分成若干块才能加载内容。这些数据对于游戏理解每个坐标处的内容至关重要,特别是考虑到我们需要存储覆盖多个图块的节点的额外数据。加载与 2000×4000 地图关联的所有结构体占用了足够的内存,导致某些设备崩溃。
随着我们不断改进和优化,只加载地图的相关部分而不是整个地图,这项工作显著减少了老玩家的加载时间。
为了进一步优化地图,我们还采用了另一种技术,即用网格的直接渲染替换地图上表示地形的游戏对象。这样一来,我们就避免了实例化这些游戏对象所带来的内存开销。结合策略性地仅加载周围区域所需的网格和模型,提高了地图进入和滚动性能。

如何决定哪些内容必须在发布时提供,哪些内容可以稍后在线播放或加载?
AY:第一步是确定玩家进入游戏多人游戏阶段之前,首次用户体验 (FTUE) 需要什么。这让我们有机会下载玩家进入完整游戏时使用的所有数据。
还有其他与实时操作或后期功能相关的内容,也可以在后续过程中下载。我们希望确保玩家在遇到系统后能够立即享受游戏。
在后续的加载过程中,需要在预先加载内容(这可能会增加加载时间)和异步加载内容(这可能会在进入屏幕或区域之前激活加载指示器)之间取得平衡。我们将持续在这个领域进行迭代,以寻求最佳的用户体验。
您是如何构建和自动化资源包管道,以平衡下载大小、内存使用量和运行时灵活性的?
TL:我们通常的目标是将资源包的大小控制在 8 MB 以下,但根据使用情况和资源包中所需的素材资源,也会有一些例外情况。这促使我们对资源包进行结构化处理,以便运行时经常一起使用的素材资源可以同时可用。
相反,我们会避免使用体积过大、仅使用其中一部分素材资源的软件包。我们按游戏区域、功能或共享资源类型对资源包进行了分类。例如,我们的地图上有不同的生物群落,每个生物群落都有单独的素材资源来适应该特定位置。
我们不需要把北方的雪山和南方的沙漠山脉放在一起比较。但是,有些网格和纹理在不同生物群系之间是共享的,因此这些素材资源会被放在一个共享包中。
这需要了解游戏中素材资源的使用位置,才能保持性能优化,从而实现平衡。与任何实时游戏一样,这是一个持续的过程,随着更多功能的添加,我们需要对其进行审查和重新组织。
AY:在 Addressables 发布之前,我们内部开发了一套工具来帮助我们解决 Addressables 现在解决的许多问题。这些内部工具中的一些能够帮助我们了解软件包的组成,并实现下载补丁进行更新的高级技术(我们称之为“二进制补丁”)。

在使用资产包时,您遇到了哪些权衡或挑战?您是如何解决这些问题的?
TL:我们面临的最大挑战是,如果有人编辑现有的预制件或添加许多新素材资源,而没有意识到这对资源包大小和组织的潜在影响,资源包的大小可能会急剧增加。
我们曾遇到过软件包一次性增加超过 5 MB 的情况,而用户却毫不知情;最糟糕的情况是,这导致我们的 .aab 文件超过了商店提交的大小限制。此后,我们在构建管道中添加了警报,以捕获这些情况,并帮助开发人员更好地了解他们的更改何时可能会以意想不到的方式增加包的大小。
如何处理资源依赖关系以避免重复下载和不必要的内存占用?
TL:在我们的内部资产包管理工具中,我们可以看到不同资产包中存在重复的素材资源。一般来说,我们不希望看到很多重复的素材资源,尤其是较大的素材资源,所以我们直接将这些素材资源添加到捆绑包中,而不是允许它们作为依赖项从多个捆绑包中引入。我们必须确保将其添加到可在多个地方使用的软件包中,但通常我们会创建一个单独的共享软件包。

为了减少应用程序启动期间因资源反序列化引起的 CPU 使用率峰值或延迟,您采用了哪些技术?
AY:我们用于设计数据的一种技术是使用 Protocol Buffers (Protobuf) 格式进行存储,而不是使用典型的 JSON 格式。Protobuf(gRPC 使用的二进制格式)提供更紧凑的存储和更快的反序列化。
通过使用关联的结构化模式文件,我们可以更快地将数据加载到内存中,而无需解析 JSON 字符串的内容并对其进行结构标记化。我们探索了其他选项,例如 BSON 和Odin Serializer,以便更高效地存储和反序列化数据,但 gRPC 能够更高效地与我们的服务器通信,这使得它成为我们正确的选择。
有效的线程管理也至关重要。确定哪些工作可以从Unity主线程中移出,这样你就可以专注于在唯一可以执行此工作的地方加载素材资源和场景。
如何优化构建大小和部署管道,以确保更快的补丁和内容更新?
AY:我们使用几种不同的技术。首先,我们专注于在游戏二进制文件中嵌入所需素材资源和稍后可以下载的资源之间取得适当的平衡。我们的游戏有一个操作指引,需要几分钟才能完成,这为我们提供了一个窗口,以便在需要时下载额外的资源,而不会打断玩家的首次登录。
利用 Android 的 Play 资源分发功能,我们也获得了更多前期可用资源。我们开始将一些动态数据表打包到游戏客户端中,因为我们预料到其中一些数据会过时。通过仅下载已更改的表格,我们减少了加载时间。
在此基础上,我们引入了二进制补丁技术,使我们能够下载更小的二进制差异文件并修补修改后的文件,而不是直接下载新版本。我们也可以将其与资源包一起使用,根据新的实时活动需要对游戏内容进行修补。

回顾过去,为了改善玩家的加载时间,你做出的最有影响力的改变是什么?
AY:简单的答案是确保玩家只加载他们需要的内容。在试运行之前,我们发现这张地图是我们加载时间最大的瓶颈之一。当时,游戏会预先加载所有地图资源,之后我们才开始进行优化,只显示玩家大本营周围的区域。
确定我们需要的内容,并实施异步加载其余内容的技术,即使在高端设备上也能消除数秒的加载时间。我们的团队出色地完成了任务,提高了玩家的加载速度,并为我们带来了更好的用户体验,我非常感谢他们为此付出的辛勤努力。
要了解更多使用Unity制作的项目,请访问资源页面。
