多人平台游戏-服务器上的单个客户端通常是否需要服务器更正?


10

我目前正在开发一个相当简单的多人平台游戏。我阅读了很多有关隐藏延迟的技术的文章,但是仍然无法理解某些概念。我觉得这个话题非常有趣,喜欢自己尝试一些想法,但我认为询问gamedev stackexchange对于我的问题会更有效。我将尽力描述我的当前状况以及在此过程中出现了什么问题。

现在,我只想让一个播放器与服务器同步。从理论上讲,我假设一个具有客户端预测功能的玩家不需要服务器修正,因为没有外部因素会影响他的动作。因此,我的原型目前只有一个播放器与服务器同步,而没有发送服务器更正。

如果您熟悉游戏网络,我认为您可能会跳过上下文部分,尽管在此过程中我也可能做错了什么。

客户端循环(每帧一次,每〜16.67ms一次)

简化的客户端循环如下所示:

  1. 检查本地输入(WASD)并将其打包为操作(例如Type=MoveLeft, Time=132.0902, ID=15)。我们保留打包的操作,以便最终在以后发送它们。此外,我们将所需的动作直接应用于游戏的本地物理模拟。例如,如果我们有一个MoveLeft动作,我们会向玩家的速度向左施加一个力。

  2. 检查发送动作。为了防止滥用客户端的带宽,请仅按特定间隔(例如30ms)发送打包的操作。

  3. 应用服务器修改。在某个时候,这将处理服务器接收到的增量和更正,并将其应用于游戏的本地模拟。对于此特定问题,不使用。

  4. 更新本地物理。在主播放器上运行物理循环。基本上,这是客户端对玩家运动的预测。这会增加玩家的速度引力,将玩家的速度应用到他的位置,修复沿途的碰撞等。我应该指定物理模拟始终以固定的增量秒执行(根据实际增量秒多次调用) 。

我跳过了有关物理学和其他部分的一些特定详细信息,因为我认为这些不是问题所必需的,但是请随时让我知道它们是否与问题相关。

服务器循环(每15ms)

简化的服务器循环如下所示:

  1. 处理动作。检查从客户端收到的操作包,并将其应用于服务器物理仿真。例如,我们可以收到5个MoveLeft动作,然后将力施加到速度5次重要的是要注意,整个动作包是在一个“框架”上执行的,与客户端在动作发生后立即应用它相反。

  2. 更新游戏逻辑。我们会更新游戏物理性,移动玩家并修复碰撞等。我们还会打包以后碰巧发送给玩家的所有重要事件(例如,玩家的健康状况下降,玩家死亡等)。

  3. 发送更正。如果他们最近改变了,我们会定期(例如,每35毫秒发送一次)将差值发送给其他玩家(例如,玩家的位置,健康状况等)。该部分目前尚未实现,因为我希望单个播放器的模拟在客户端和服务器上给出相同的结果而无需更正,以确保客户端的预测工作正常。

问题

当前的系统在简单的情况下仍然可以正常工作,而令我惊讶的是它在简单的水平移动下给出了非常相似的结果(我相信,这种误差是由于浮点精度误差引起的):

通过简单的碰撞/运动,同步效果很好

请忽略原型图形。白色矩形=播放器,红色矩形=障碍物,蓝色=背景

但是,在进行时间敏感的动作(例如跳跃和移动到孤立的障碍物附近)之后,出现同步错误:

同步不起作用,因为我在时间敏感的时刻绕过了指定的障碍物

从理论上讲,我希望两者总是能得到相同的结果,因为没有任何外部因素影响客户的立场。不过,在实践中,我认为我理解问题所在。

由于围绕这样的障碍物跳跃非常取决于玩家的时机,因此将速度应用于位置的微小变化将对结果产生影响(例如,客户可以及时移开以避免与障碍物,而服务器会在稍后接收到整个动作包时执行该操作,并停留在障碍物上一小段时间,从而更改最终结果)。客户端和服务器处理方式之间的区别主要在于,客户端在发生所有操作时都会执行所有操作,而服务器在接收到它们时会批量执行所有操作。

问题

如此长的语境最终引发了我的问题(感谢您阅读到目前为止):即使只有一个播放器与服务器同步,要求服务器更正是否正常,还是应该在某些对时间敏感的情况下使用某些技术来避免不同步? ?

我已经想到了某些可能的解决方案,其中一些我不太满意:

  1. 实施服务器校正。只需假设这是正常行为并纠正错误即可。无论如何,我都想实现它,但是我只是想确保到目前为止所做的事情是可以接受的。

  2. 使用提供的客户端时间来应用所需的操作。我想这与滞后补偿类似,需要“及时返回”并检查运动。有点像应用服务器更正,回到过去,然后重新应用下一个操作。我真的不喜欢这个主意。它看起来很复杂,资源昂贵,并且需要信任客户的给定时间(尽管我确实打算真正检查时间是否相对合法)。

  3. 向GameDevelopment StackExchange提出一个很棒的新想法,它将解决我的所有问题。

我才刚刚进入游戏网络世界,所以请随时纠正/批评/侮辱上述任何概念,或者提供一些想法/资源,这些资源可以帮助我在“网络奇妙世界”中发展。如果可以在其他地方找到答案,请原谅我,但我失败了。

非常感谢您的宝贵时间。


您的服务器和客户端以不同的速率运行帧。如果客户端对连续的帧执行两个操作,但是服务器看到它们之间存在一帧的间隔,会发生什么?
user253751

@immibis基于gafferongames.com/game-physics/fix-your-timestep来建立自己,以尽量减少这种影响。
杰西·埃蒙德

Answers:


11

在这种情况下,最好让客户稍微具有权威性。对于这样精确的控制,即使进行真正的高级校正和预测,也极不可能获得良好的性能。

客户端需要从仅发送“我已跳转”消息扩展到发送“我在时间T从X,Y跳转”消息。然后,服务器检查该位置是否接近其在时间T(您可以将其限制为过去的相当短的时间)所认为的玩家位置,以防止作弊,然后模拟从客户端位置的跳跃已发送。服务器仅在客户端无法正常运行(通常是由于滞后或类似原因)时才纠正客户端。

这种技术与校正和插值结合使用,以使游戏在本地客户端上具有响应能力,并为远程客户端提供流畅的外观。


很有意思。我将尝试实现这一点,并观察其进展。非常感谢您抽出宝贵的时间回答。顺便说一句,您提到“近距离”和“过去的时间很短”,您是否只需分别以恒定的距离和时间进行检查?还是您会使用更复杂的技术,例如保持头寸历史和使用客户的平均往返时间(或其他任何时间)?
杰西·埃蒙德

一切适合您的游戏。从简单开始,仅在您认为必要的程度上使它复杂化。有些服务器保持各种各样的快照历史周围~max(RTT)在过去的服务器蜱,而是你是否需要为你的游戏具体我也不知道。对于射击风格的游戏来说,它甚至更方便,在射击游戏中,您还希望在客户端上进行一定程度的命中/击发检测,不仅需要知道玩家在46ms之前的位置,还需要在46ms之前的目标位置以及任何目标位置移动闭塞平台在哪里。
肖恩·米德迪奇

完善。我将进行实验,看看最有效的方法。将其标记为可接受的答案,再次感谢!
杰西·埃蒙德
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.