拆除Valorant的战争雾的墙壁

嗨,我是保罗“arkem”张伯拉特,反作用的领先英勇的,骚乱的新战术fps。我是一部分英勇的一支游戏工程团队,我是骚乱的人之一,旨在追求游戏安全。了解更多信息英勇的安全,查看我们的反作用内核帖子,并阅读英雄联盟安全技术,查看我们的反作用技术博客文章

从一开始英勇的发展,我们首要地建立了欺骗性,以确保竞争完整性。在这篇文章中,我会走过这些防骗系统之一 - 战争迷雾。这是其中之一英勇的一家关键安全系统,侧重于打击欺骗游戏客户端访问信息的作弊,如墙壁。

什么是壁虎?

骗子使用Wallhacks通过墙壁来看对手。在战术射手中喜欢英勇的,这使得它们在各个战斗遭遇以及整个圆形的战略决策方面提供了巨大的优势。墙壁尤其存在阴险,因为它们给出了一个并不总是显而易见的优势 - 你的敌人可以使用wallhacks ......或者也许他们只是想出,你每一轮都赶去b。我们真的想防止那种对球员徘徊的怀疑感,在比赛结束后毒害他们的经历。

没有战争的迷雾:Wallhacks给出了播放器的大量游戏优势。

英勇的团队(包括我)是战术FPS类型的长期粉丝,我们都有一个以上的比赛在其他游戏中被欺骗毁了。亚博论坛在开发开始时,当我们谈论该项目的安全目标时,一遍又一遍地出现的两件事是壁虎和瞄准。

在其中一个计划会议期间,我被生产者询问为什么英雄联盟壁纸没有问题。我解释说明联盟的战争迷雾系统-如果你想了解更多关于这个,看看这篇关于战争迷雾的文章联盟,和这一个关于净可见性. 他问是否有可能在欧洲实施类似的措施英勇的,我的答案是“好吧,也许,但这会很棘手。换句话说......我在它上!“

我们解决方案的骨架

联盟战争系统的雾化是因为游戏服务器扣留有关敌人位置的信息,直到客户需要显示它。我知道如果我能实施这样的东西英勇的我们可以解决沃尔哈克的问题,因为沃尔哈克看不到任何东西。如果对手在墙后,我们不会将他们的位置发送给敌人玩家,让他们隐藏起来,直到他们决定偷看角度。如果我们能做到这一点,这似乎是理想的解决方案-但我们不知道这是否是可行的虚幻引擎。

这对我来说是一个艰巨的任务。我是新的项目,这是我的第一个未发布的游戏项目,使用发动机我不熟悉,并通过完全不同类型的游戏灵感的技术。我们的战争系统将基于联盟的,除了在一个新的引擎,运行在一个更复杂的三维环境,它将不得不适应英勇的那太严格的性能约束

网络相关性

首先,我拿到了我们需要做这项工作的库存:

  • 一种决定每个玩家所必需的信息的方法

  • 一种防止玩家接收不必要信息的方法

  • 当必要的信息变得不必要的信息时捕获球员的方式。

是时候潜入虚幻引擎的内脏了。

一个星期的阅读文档和引擎源代码所推动的配乐到(二)最好的黑客电影一直以来都有一些有希望的线索。我发现Unreal Engine有一个网络相关性的概念,可以用来限制网络更新,甚至消灭不相关的参与者。我还发现,虚幻引擎复制系统最终是一致的,所以一旦信息变得相关,敌方玩家的状态就会迎头赶上。在这一点上,我越来越相信这是一个可行的解决方案。我想我们可以将这些网络功能与Unreal Engine的光线投射结合起来进行视线检查,这样我们就可以做生意了。

注意:

一个“演员”在虚幻引擎术语是一个独立的游戏对象,可以通过网络同步。特工、武器和能力都是网络参与者的例子。

原型设计

我去上班了,仍然兴高采烈,心想也许这终究不会那么难。一周后,我做了一个简单的原型。

Here’s how it worked: Every time the server wanted to send a network update (usually once each tick), it would do a line-of-sight check from each networked actor (agent, weapon, etc) to the point-of-view actor for each player. If the line-of-sight check failed, we’d mark the actor as不相关并停止发送网络更新。否则我们将它们标记为相关的并发送通常的更新,并在他们错过的任何更新时赶上它们。

在标记演员时不相关,服务器向该播放器发送了一条消息来标记不相关演员像看不见和无形的(因为他们处于过时的位置并显示它们会误导)并最终审议他们。当演员变成了相关的同样,它会发送一条消息来产生它们(如有必要),然后使它们可见并启用碰撞。

怎么样了?成功了!

好。。。有点奏效了。有很多错误,但基本的想法是正确的。如果你看不到敌人,服务器不会告诉你他们在哪里,所以wallhacks就没用了!但是,性能有问题,视线检查有一些严重的限制。还有很长的路要走,我很快意识到这并不像我希望的那么容易。但我知道这是可以做到的。

在接下来的几个部分中,我将通过这些问题,以及我们如何解决它们,这使我们能够达到我们有保护的战争系统的稳定和有效的迷雾英勇的今天。

问题与解决方案

在甚至思考修复错误之前,我需要一些调整,以便正确地嵌入战争迷雾英勇的。我不得不在音频系统中绑定,为设计者添加工具,并处理游戏事件的系统通知。这些是相对简单的修复,一旦完成,我就可以专注于服务器可见性问题和性能问题的更复杂问题。

同时,随着比赛的其余部分走到一起,我还需要继续对战争的迷雾进行小调整,从janky原型转变为抛光英勇的我们今天有。这意味着反复返回以固定飞机的碎片,而它已经在空中。

服务器可见性问题

在测试初期,很明显可见性检查存在问题。在测试过程中,演员们会突然出现,或者无限期地隐身。没过多久就发现原型基于光线投射的视线计算是不够的。光线投射直到太晚才检测到演员何时可见,有时检查根本不会成功。

我之前经历了几次迭代,然后在持续工作的解决方案上。最初,我通过添加额外的射频来计算界限框的边缘来集中在视线计算中,但这没有解决弹出窗口。我的第二次尝试涉及扩展边界框以试图捕获未来的行为,但视线检查仍然是从根本上过于悲观(偏向消极结果以避免误报)。第三次和最终尝试是第二次尝试的“展望未来”的混合,结合基于遮挡的剔除,以取代不可靠的射线。

视线计算

我第一次解决的问题是悲观的视线检查。第一个原型从玩家的相机位置朝向演员的中心施放单个光线,但这会产生不准确的(悲观)结果。

这是有问题的,因为有时间玩家无法看到演员的中心点,但仍然可以看到演员。它会在门,壁架或角落遮挡演员的中点的情况下完全不准确的结果 - 以及作为敌人偷看一个角落的大量流行。换句话说,这将是一种新的极端形式的帕克斯的优势。

对演员的中心进行基本的视线检查效果不太好。

尝试#1

我的第一个解决方案是从相机中取出原始单线轨迹,使其10射线:一个用于演员边界盒的每个角落,一个到演员的相机位置,一个到中心。这更好但仍然不完美,因为演员的中心和角落被阻塞的地图上,但它们的一些小部分仍然可见。所以这种解决方案是缺乏缺乏的,它会使系统10x更昂贵 - 当我们致力于128个刻度网时,它真的很难证明数千次射频。

对边界框的视线检查有助于缓解但不是完整的解决方案。

尝试#2

我的第二次迭代明显成功。我通过将演员的速度扩展到速度乘以比预期的Ping时间更大的“前瞻”时间来扩展演员的边界盒,使雷科观看了未来。这通过将信息发送到敌人在敌人周围的角落之前来阻止弹出效果。服务器有效地研究了未来,以便在时间上获取客户所需的信息。

扩展边界框以解释运动和延迟真正有帮助!

此时,系统是可行的,但仍有错误和性能问题。在一些问题上通过一些问题谈论英勇的在更具图形倾斜的工程师,我们意识到我与视线计算的服务器可见性问题非常相似于称为遮挡剔除的公共客户图形问题。

服务器端遮挡剔除

遮挡剔除是一种游戏引擎用于从场景中删除不必要的对象,然后将其发送到图形卡以呈现。减少发送给GPU的对象数量使渲染的场景更快。

我在战争能见度雾的问题是相似的,因为:

  • 两个系统都决定了哪些对象是可见的。

  • 两者都需要乐观的结果,如果我们不需要,我们只会删除东西。

  • 两者都需要非常快,使它值得做遮挡剔除放在第一位。

我决定采取我们的客户闭塞剔除系统,并将其运行在游戏服务器上,作为做十条射线的替代方案。

我们的遮挡剔除系统使用了一种称为潜在可见集(PVS)的技术。PVS系统预先计算场景的哪些部分(我们的地图)可以看到其他部分。我们提前运行了一个过程,将场景划分为多个单元——想象Minecraft中的体素。然后计算场景中每个单元格和其他单元格之间的视线,然后将所有数据存储在一个查找表中,就像一个巨大的乘法表。

杰特的牢房可以看到所有绿色阴影的牢房。

我获取了这个查找表,并开始将其包含在服务器资产和客户机包中。我没有在相机和演员之间进行光线跟踪,只是做了一个表格查找,看看相机的体素是否能看到目标演员的体素。这比光线投射要快得多,也很乐观。只要一个体素的任何部分可以看到其他体素的任何部分,表格就会返回“可见”。这有助于我们避免出现漏洞,并带来了巨大的性能提升。

这个预先计算的能见度表给我们提供了快速和慷慨的视线测试。

表现

在实现遮挡剔除解决方案之前,我们的服务器性能是可怕的,帧时间加倍,基本上将我们从128滴回到64个勾号。在10名玩家游戏中,我们每帧计算相关性超过350倍,每一个都包括相对昂贵的原始10射线视线检查。

基于新的PVS的检查大大提高了性能,并且我通过其他一些优化获得了更多。例如,系统开始假设相关的演员保持与少量时间相关,并假设附加的演员共享父母的可见性。因此,如果玩家可以看到另一个角色,系统不会打扰他们是否可以看到他们的武器。这些变化减少了系统执行显着使其更快地执行的计算量。

如今,战争系统的迷雾占上2%的服务器帧时间(我们的第一个原型中的50%)。整体系统甚至提高性能由于网络消息的减少服务器发送给由战争雾隐藏的播放器。

一致性与国家管理

解决服务器的可见性和性能问题是朝着正确方向的巨大步骤 - 但我们仍然有错误粉碎!一些错误是相对较小的,如敌人在记分牌上没有显示,如果一个球员还没有看到它们,那么这一轮。当我们捕获它们时,这些需要小调整和修复。

但其他的,较大的错误可能会严重影响游戏 - 就像一个没有在正确的动画姿势中所示的敌人(这是击中登记),或者在拐角处行走后的时刻是不可见的。一个共同的错误来源是游戏中的地方,其中逻辑由联网事件(使用虚幻引擎的RPC系统)而不是最终一致的复制系统。

这个bug类的一个例子是,当一个被战争迷雾隐藏的敌人开始解除刺时,一个观察到他们的玩家会看到他们的默认角色姿势而不是解除刺姿势。

左:玩家看到了什么。
右图:实际上发生了什么。

这将发生,因为由于战争的雾,不会发送“开始尖峰声明”事件,并且没有机制在离开战争之后修复国家 - 而他们的位置会更新,他们的目前姿势不会的。这类错误很常见,发生在游戏系统处理自己的网络消息和状态管理时。这种模式在原型设计过程中经常发生,因为它允许并行构建系统,所以在尖峰相关内容上进行的实验不会妨碍基础设施工作或像《战争迷雾》这样的安全系统。

通过添加战争和解逻辑的雾后,我们决定使用任何系统可以使用的标准解决方案来单独修复这些错误的每一个和每个实例。负责代理和游戏系统负责的游戏工程师构建了一个称为效果容器的系统。这种整齐的客户端游戏效果并提供了一个标准机制,以便在战争雾中出现后重新启动和快速转发效果。在演员留下战争雾之后,钉子播种的尖峰播放不仅会播放,但它也具有正确的剩余持续时间。

这类修复错误的系统方法只有两个原因。首先,由于开发早期有多早,创造了战争系统的迷雾。第二,因为工程师来自跨越英勇的热衷于安全和很乐意考虑到安全问题在设计他们的系统时。

测量有效性

我与战争迷雾有一个问题是如何跟踪它是否按预期工作。对于特别的安全系统,重要的是测量有效性并确保正确运行的功能,或者失败可能会被忽视。

在战争雾的发展期间,我建立了一些不同的壁虎工具来测试。他们做了一项非常好的工作,展示了在行动中的战争迷雾,但这个工具更适合寻常检查而不是捕获错误,所以我建立了测试和仪表板,以确保我们一直捕获事情的工作。

自动化测试

为了在系统中构建更多的信心,我通过创建一些自动测试案例在我的Wallhacks上扩展,其中一些自动测试案例让机器人进入和退出战争。这有助于我们确保战争系统的迷雾仍在运行后在每个新构建后运行。这些自动化测试很好在检测系统中的总缺陷,但他们并没有真正帮助我们发现微妙的问题,并且他们不会让我们整体看待系统效率。

仪表盘

要捕获这些微妙的问题并获得整体系统性能的快照视图,我创建了仪表板以跟踪真实匹配中的健康和效果。我建立了遥测到游戏服务器,测量每次战争查询的结果。然后我使用这些结果来构建仪表板,显示敌人的时间数量相关的数量以及每个结果的雾百分比每个结果(例如,“不相关”或“由于视线上的相关”或“相关”)。然后,仪表板通过Map和Agent进一步突破,所以我可以看到那些特定内容类型是否存在任何问题。

使用此遥测,我有能力设置警报阈值,以确保我注意到当新的内容或系统更改时会影响战争的雾。例如,如果一个代理商被列为远远超过其他代理人,我将被警告,并可以调查以查看是否有任何具有任何功能的错误。像这样的情况是一个错误,杰特上升的能力发挥了一种会在循环中陷入困境的声音(虽然在不明显)。它在这个遥测中出现了捷克运动员的明显更高的相关时间。

这种类型的仪表板比较了战争相关性统计的代理迷雾,以帮助我们找到错误。

最后的想法

安全作为核心产品目标

战争迷雾系统(除了其他英勇的安全功能)只有可能因为团队将安全性视为核心产品目标。该英勇的团队开始在生产周期中非常早期锻炼安全功能,这使我们能够在构建关键游戏系统时考虑安全要求。这创造了一个氛围,所有开发商在游戏的安全方面投入(和涉及)。我相信这已经严重改善了整个游戏的安全性。通过使我们所有的开发人员在安全问题上工作,我们认为我们为战斗骗子建立了最佳基础。我们将继续致力于寻找用于保持新的解决方案英勇的安全。

所有这项工作导致了一个系统大大减少了敌方位置可用于玩家的系统,从而降低了墙壁的有效性。

期待

我期待着制造的一些优化 - 战争系统的雾是一个平台,在我们获得新信息时会继续提高。我们可以扩大战争系统的雾,收紧公差,以提高安全性。当我们获得更多关于平均延迟的数据以及有关不断的作弊景观的更多信息时,我们将能够调整最大的战争。

战争雾后:墙壁的影响大大减少了。

谢谢阅读!如果您有任何疑问或意见,请随时在以下意见部分发布。

保罗张伯伦发布