Unreal Engine Improvements for Fortnite: Battle Royale
2017年10月4日

虚幻引擎为 Fortnite: Battle Royale 项目做的改进

作者 Nick Penwarden

什么是 Fortnite: Battle Royale?

最近,我们发布了一个新的 PVP 游戏模式,叫做 Fortnite: Battle Royale。该游戏模式中,100 个玩家空降在一个 5.5 平方公里的游戏区域,玩家之间互相战斗,最后一个玩家则是最终胜利的玩家。在这个需求下,这样的游戏规模给 Fortnite 开发团队带来了一些新的挑战,这篇文章就来讨论一下这些挑战。

 

该视频另一地址

 

为了开发 Battle Royale 这一游戏模式,我们做了诸多方面的改进,包括性能的改善,内存优化和工作流程优化。这些改进不仅仅是为了 Fortnite: Battle Royale,更将会为虚幻引擎 4 的开发团队带来改善,尤其是在开发中遇到类似需求的开发团队。

所有的这些改善都可以通过 Perforce 或者 GitHub 获得。相当多的改进都会在这个月即将发布的虚幻引擎 4.18 中得以整合,来不及整合的一些剩余改进则将会在整合在 4.19 中。

专属服务器(Dedicated Server)的性能

首要需要解决的一个挑战是优化 dedicated server,以便能在游戏中同时容纳 100 个玩家,保持在每秒 20 帧服务器计算刷新率,并且保持较小的带宽需求。

在每帧中,服务器会将一个玩家附近所有的 actor 信息更新给该玩家。这意味着对于每个玩家,都需要判断和该玩家相关的所有 actor 是哪些,找到这些 actor 发生了什么样的变化,并且将这些变化信息打包发送给该玩家。为了将 CPU 的计算时间控制在最小的数值上,并且发送最小的网络包,这样才能为游戏提供最佳的游玩体验。
UnrealEngine%2Fblog%2Funreal-engine-improvements-for-fortnite-battle-royale%2Fblog.CMBC2LsJWCY-a0613ff07e39f48bbdbdde75576b0755cd5e2a29

这项工作主要都是在分析游戏性能并优化游戏逻辑代码,但在这一过程中,我们也发现了一些需要对引擎进行改进的地方。

以下就是我们为 dedicated server 优化所做的引擎的改进:

  • 在用户连接的时候,将 level streaming 的远程调用(RPC)合并,以减少远程调用的次数。(将会在 4.19 中整合)
  • 将操作系统中的 Socket Buffer 大小改为可配置,并在 Battle Royale 的项目中增加该数值。这个改动将能够避免同时连接的客户端的 buffer 溢出而导致服务器的过度加载。(将会在 4.19 中整合)
  • 当角色并未站立在任何其他 component 的时候,减少 CharacterMovement 远程调用所需要的带宽,比如在跳跃的过程或者在降落的过程中。(将会在 4.19 中整合)
  • 新增了一个功能,用于限制服务器的每帧发送更新给客户端的数量。我们目前的默认设置是在游戏大厅中限制在每帧只给 25 个客户端更新,在游戏中每帧只给 50 个客户端更新。(将会在 4.19 中整合)
  • 限制客户端向服务器发送移动更新的频率。避免因为客户端的帧率过高而频繁的向服务器发出移动消息而使得服务器过度负载。(已经在 4.17 中整合)
  • 新增了一个选项,可以选择不要复制一个客户端的 ping 的信息给其他客户端,因为该方法在大量玩家的情形下会导致很多额外的网络流量。(将会在 4.19 中整合)
  • 移除了在网络同步时 FArchive::SerializeIntPacked 函数中几处分配内存的调用,修改了 CompatibleChecksum 的计算方式。(将会在 4.19 中整合)
  • 修改了 property type 比较方式,从原来的字符串比较改为 FNames 的比较,加快网络复制进程的速度。(将会在 4.19 中整合)
  • 新增了一个功能,能够在客户端上实时的查看当前的 dedicated server 的网络统计信息,对于那些将服务器部署于云端的项目开发获得调试的便利。(将会在 4.19 中整合)
  • 对 ability system 做了修改,更好的计算相关性,在使用 ability system 的时候将极大的减少网络同步的开销。(将会在 4.19 中整合)

制作并且渲染一个大地图

Fortnite: Battle Royale 地图的游戏区域有 5.5 平方公里。在跳伞的时候,玩家可以看到整个地图,游戏过程中也支持长距离的可见视野,因此我们需要优化我们的细节等级(Level-of-Detail)方案来使这一设计变成可能。

Unreal+Engine%2FblogAssets%2F2017%2FOCTOBER+2017%2FFortnite+Battle+Royale+UE+Improvements%2FFNBR_SocialRangerTower-770x433-a1b2112ca6bf4445b2c912c3036fff21ca8193cb

我们采用了引擎中的分层递阶 LOD(Hierarchical LOD,HLOD),由 Simplygon 提供的方案,将地图中的一些区域合并成一些低面数的简单网格体,以便于当玩家在远处时,这样的区域能够在一次 drawcall 中便能完成绘制。这些是已经可用的工具,我们在 Paragon(虚幻争霸) 中也使用过  – 但这次我们需要做一些改进,以便于美术制作人员能够更高效的进行开发工作。

地图分割的方式能够让美术制作人员互相协作,而不会和我们的 HLOD 工具混杂在一起。我们也对 HLOD 做了一些改进,以便于更好的支持美术工作流程,并新增了一个命令行工具来重新构建地图中所有的 HLOD,并能够在晚间的构建流程上自动重新构建,而不再需要美术制作人员在本地的工作电脑上构建它们。(将会在 4.19 中整合)

在主机平台发布产品

Battle Royale 模式下超远的视野距离和大量的玩家数量,在主机上也遇到了性能和内存的挑战,我们同样需要对这些挑战做出新的改进,尤其是和内存有关的问题。大部分的工作都需要在游戏项目组上对游戏内容素材进行优化,但我们也在引擎层面做了一些改进和调整。
UnrealEngine%2Fblog%2Funreal-engine-improvements-for-fortnite-battle-royale%2Fblog.UfZJHLJKRgc-31c3991617ca38eef1b5148cb4d8b42b015606d5

以下这些是我们在主机上的一些改进,将会在 4.18 中发布:

  • [XboxOne + PS4] 改进了底层内存跟踪工具,以便更好的识别潜在的内存优化空间。
  • [XboxOne + PS4] 更高效的贴图卷更新方式,新的方式降低了超过 240MB 的峰值内存开销。
  • [XboxOne] 基于启用了那些渲染特性,为不同的 render target 添加控制选项以最大化利用 GPU 带宽。
  • [XboxOne] 减少 D3D12 描述器头部的内存并节省了 120MB。
  • [XboxOne] 运行中分配并释放 render targets 并减少了 100MB 以上的内存。
  • [PS4] 优化了 texture streaming 和碎片池(defragmentation pool)的处理方式,节省了 300MB~400MB 的内存。

在为 Battle Royale 项目做开发时,我们还发现和输入延迟相关的一些问题,尤其是在 30 帧运行速度下。我们成功的对线程同步做了一些改进,并降低了大约 66ms 的输入延迟(在 60 帧的游戏中这里降低的时间约为一半)。这一修正对游戏体验会带来显著的改进,在瞄准的操作中响应更及时,瞄准也变得更容易。(将会在 4.19 中整合)

还有更多!

这里只是一些随着 Fortnite: Battle Royale 项目第一个版本而带来的引擎功能的改善。在获得了这些经验后,我们也已经看到了其他更多的一些改进空间和新的想法想要去实现,尤其是在超大地图的开发中 Level Streaming 和编辑器性能方面,这些改进将会持续对我们自己的游戏开发团队以及在游戏业内使用虚幻引擎的用户带来更高效的开发工具。