/ 编程 /一年的雨:网络优化
编程

一年的雨:网络优化

2020-07-31T16:42:02 + 02:00

在虚幻引擎4中创建没有锁柄的在线实时策略游戏。

随着一年的雨,我们正在使用虚幻引擎,为台式电脑带来完全新的团队实时战略体验。传统上,这些游戏一直在使用流行的LockStep方法,用于在所有游戏客户端之间交换数据。但是,虚幻引擎依赖于客户端 - 服务器网络架构来创建多人游戏。在本文中,我们将仔细看看我们面临着创造与虚幻引擎的在线实时策略游戏以及我们所做的内容的挑战。

LockStep网络
LockStep假定客户最初知道相同的游戏状态。然后,一旦每个(网络)帧,它将收集来自所有客户端的输入并在所有客户端中分发它们。最后,所有客户端都将应用所有输入来生成相同的新游戏状态。通常,这需要您的游戏逻辑在所有连接的客户端中都是确定性:相同的计算需要产生完全相同的结果,必须以相同的顺序生成伪随机数,并且所有游戏系统的执行顺序必须是相同的。

一般而言,所有这些都会导致以下含义:如果任何客户端都未能及时发送其输入,例如,由于延迟或数据包丢失,所有其他客户都必须等待它们。这是传统的实时战略游戏中非常常见的景象。由于所有数据都可供所有客户端使用,因此LockStep通常也意味着技术上不可能从本地播放器完全隐藏有关游戏状态的详细信息。这为大量的当地黑客开放,比如地图黑客禁用战争的雾并揭示整个地图。
另一方面,所有机器之间发送的数据量受播放器输入的大小的限制,而不是游戏状态的大小。随着实时战略游戏的游戏状态数据的数量可能变得相当大,特别是当有数百甚至数千个单位时,LockStep对这些游戏变得如此受欢迎。

虚幻引擎中的客户端 - 服务器网络
虚幻引擎4中的网络基于传统的客户端 - 服务器模型。有一个称为服务器的单个机器,它是关于游戏状态的权威:服务器是唯一一个允许实际更改游戏状态的人。所有其他连接的机器都被称为客户端:它们会将它们的输入发送到服务器,并尽可能从服务器接收最新的游戏状态,近似于与所有玩家提供流畅的游戏体验。如果游戏状态的近似与从服务器接收的实际略有不同,则客户端通常会在多个帧上平滑这些差异以返回到正确的状态。如果差异太大,例如,由于意外的变化或尖峰,他们必须突然更新他们的本地国家,以便向球员呈现正确的世界版本,这通常会导致视觉艺术品。

在虚幻引擎中,每个游戏世界都是由演员组成的。基本上,虚幻的一切都是演员:石头,树木,射弹和人物。这些演员都存在于服务器和客户端,并且虚幻使用一个过程,用于同步其数据和远程过程调用(RPC)称为Replication。属性在随时改变时自动复制,而过程调用仅在执行时进行复制。

并非所有演员都必须复制:虽然字符通常是,但是,静态网格不是。此外,即使属性不改变(因此,没有消耗任何带宽),仍然在确定该值是否已改变时仍然存在静止服务器CPU开销。

跳过初始复制显示了更平滑的网络配置文件。在这个阶段,我们最终可以更深入地优化带宽。

带宽优化技术
有多种方法可以减少参与者在虚幻引擎中消耗的整体带宽。首先,每个演员都有特定的网络更新频率。降低该频率将导致演员更少复制。

接下来,Unreal使用网络相关性的概念来确定是否应该为特定连接复制actor。如果它们不可见,则会自动认为演员对玩家无关,不可听,对该玩家没有显着影响。该发动机也提供了基于距离的复制剔除,最后允许游戏代码完全与自定义规则覆盖相关性。

此外,虚幻中的每种类型的演员都有一个网络优先价值。数量越高,演员相对于他人接收的带宽就越多。这种负载平衡技术优先考虑所有演员,并根据它对游戏玩法的重要性提供带宽的每一个公平份额。最后,Unreal中的演员可以最初或暂时休眠,防止它们复制。这有助于防止演员复制,以防你知道没有必要这样做。例如,EPIC Games一直在使用休眠,以优化Fortnite中的建筑物的网络性能。

优化一年的雨
当我们开始优化一年雨的网络性能时,我们首先设置一个(大多数)的确定性测试方案。我们创建了一个具有代表性的树木的小竞技场地图。树木以前一直在游戏的各个领域造成绩效问题,我们也怀疑他们也在网络中这样做。然后,我们设置游戏以最初产卵每位玩家20个单位,并让它们攻击地图上的中央信标位置,导致它们在那里移动并在途中攻击任何敌对单位。我们从每个会话开始时拍摄了30秒的网络配置文件,并比较了结果。这是使用称为网络分析器的独立虚幻引擎工具完成,该工具允许您打开包含录制数据的文件,并显示所有Actors为属性和RPC的带宽贡献。只有服务器能够录制所有内容,客户端都刚刚记录自己的RPC,我们正在服务器端拍摄网络配置文件。

一年的雨量的复制图可以防止单位的复制,由战争的雾覆盖,或因其他原因隐藏给玩家。

复制游戏玩法标签
我们将突出的树木突出显示了超过80%的带宽 - 正如预期的那样。违规属性是他们的相关游戏标签。在虚幻中,游戏玩法标签是用户定义的分层标记,允许沿着它们的层次结构甚至具有多个标记的容器查询的游戏逻辑。在一年的雨中,我们正在使用游戏玩法标签来确定一个单位是否潜入,或者基于攻击和装甲类型计算损坏奖金。

对该功能的简短分析显示,默认情况下,这些游戏标记被复制为完全字符串。幸运的是,它们具有一个名为快速复制的技术,它将为所有可用标记分配索引,并通过索引复制它们。显然,这需要在客户端和服务器上定义相同的标签。

复制运动
使用快速复制游戏玩法标签将树木消耗的总量减少了三分之二。有史以来,它们仍然是网络配置文件顶部显示的演员类型。现在,它是他们的运动,即加入到网络上发送的最多字节。树木不应该移动,我们不在乎如何以及为什么不真实的想法应该做到。因此,我们禁用完全复制树木的转移,这可以在虚幻编辑器中勾选一个单个复选框。这减少了在另外三分之一的复制树上所花费的字节。但是,树木仍然位于列表之上。

跳过初始复制
在禁用树木运动复制后,他们最复杂的财产是他们的能力。这是奇怪的,它不需要我们很长时间才能找到发生的事情:在我们的测试场景中,不是一个单位(并且显然,不是单树)正在使用任何能力。总之,没有任何应复制任何能力的状态。仔细看看轮廓,我们在一开始就注意到了一个巨大的尖峰,这是由所有参与者对所有客户的初步复制引起的。我们更改了测试场景,在开始记录配置文件之前的前几秒钟跳过,并获得对我们的更具意义的结果。

再次应用所有上述改进均显示树木不需要单个字节进行再次复制,就像预期一样。现在,它是每个玩家涉及我们的测试场景的20个单位,它在探查器的顶部出现,他们的移动数据是具有通过网络发送的最多字节的属性。

我们的测试方案是一个小型地图,每个球员攻击20个单位攻击中心位置,以及代表性的树木。

复制图和战争的迷雾
尽管如此,我们还是想知道我们是否可以做得更好。史诗般的游戏在不久之前添加了一个名为Replication Graph的新引擎功能。他们的想法是创建一个改进网络复制中的缩放系统的系统,其目标是在Fortnite中复制50,000个参与者到100个连接:Battle Royale。这正是我们要寻找的东西,以改善我们的实时战略游戏的表现。

传统上,虚幻引擎依赖于虚拟函数调用以确定演员是否与复制到连接。这引入了Fortnite中的CPU瓶颈,因为虚拟函数调用无法优化 - 每次调用的结果可能会发生变化,并且常常调用函数以确定演员相关性。因此,Epic Games创建了包含带有Actors列表的节点的复制图来复制到每个客户端。构建这些列表一次并仅在必要时更新它们,无需执行actors以检查每个帧的复制。

旨在改善与许多演员的游戏服务器的CPU性能的复制图。然而,正如我们没有通过覆盖相关性的锻炼,但是,使用自定义相关性节点实现自己的复制图,以及我们的带宽,我们使用了对每个玩家执行的服务器侧视觉计算,以存储有关哪个演员的信息关于战争的愿景和迷雾的球员可见。然后,我们更新了复制图,根据它们是可见的,在节点之间移动演员。这种方法将我们的测试场景中的带宽消耗减少了另外三分之一,由在彼此遇到之前所花费的时间。

未来的工作
此时,我们对结果非常满意。尽管如此,我们意识到我们的测试方案并不完全反映出我们游戏的实际情况。我们想尽快推出我们的树木的休眠,以检查这是否进一步提高了游戏的阶段的性能,其中许多工人单位正在砍树以收集木材以建造基地。此外,我们正在考虑优化服务器端的动画工作负载,以减少CPU负载,这将在具有许多涉及的游戏服务器的场景中转化为实际保存的金钱,可能会将其扩展到云中。


7:9 Hochformat

尼克普鲁斯
DaeDalic娱乐技术总监

2009年,他在基尔大学毕业于计算机科学中的“最佳学士”。两年后,他完成了汉堡应用科学大学的声音,愿景,游戏硕士学位,在后不久之后建于基督教的斜线游戏。

关于作者: 31. 7月20日
类别:
去顶级