快节奏多人游戏(4):延迟补偿

介绍

前面 3 篇文章阐述了游戏客户端-服务器的架构,我们总结如下:

  • 服务器从所有客户端获取带有时间戳的输入
  • 服务器处理输入后更新游戏世界状态
  • 服务器将游戏世界的快照发送给所有客户端
  • 客户端发送输入并在本地模拟其效果
  • 客户端获得游戏世界更新,同步预测状态和权威状态,并插入其他实体已知的过去状态。

从玩家的角度来看,这里有两个重要的结论:

  • 玩家可以看到现在的自己
  • 玩家可以看到其他实体的过去

这种情况通常表现会不错,但对于时间和空间都非常敏感的事件来说这就会产生问题,例如:爆头射击敌人。

延迟补偿

当你用你的狙击步枪完美的瞄准了敌人头部,并扣动了扳机,这将是你不能错过的时刻。

但是你并没有打到。

为什么会这样呢?

在之前的客户端-服务器架构解释中,这是因为你射击敌人的头部是在 100 毫秒之前的位置,而不是你射击时的实际位置。

在某种程度上,它就像在光速的宇宙中游玩,你瞄准了敌人过去的位置,但是当你扣动扳机时他已经消失了。

幸运的是,有一个相对简单的解决方案,大多数时候这对大多数玩家来说是都是会有一个不错的体验(下面内容讨论了一个例外)。

以下是它的工作原理:

  • 当你准备瞄准射击时,客户端会将此事件发送给服务器,服务器会提供完整信息:瞄准射击的确切时间戳以及武器的确切目标。
  • 至关重要的一步,由于服务器获得带有时间戳的所有输入,因此它可以在过去的任何时刻以可信任的方式重构游戏世界。特别是它可以在任何时间点完全按照任何客户的样子重构游戏世界。
  • 这意味着服务器可以在你瞄准射击的瞬间确切地知道武器瞄准的内容。虽然对客户端来说敌人头部是的过去位置,但服务器是知道敌人头部在你现在的瞄准位置。
  • 服务器在射击的时间点处理镜头,并更新客户端。

现在每个人都很开心!

服务器很高兴,因为他是服务器,他总是很开心。

你也很高兴,因为你瞄准了敌人的头部,进行射击,并得到一个爆头奖励!

敌人可能是唯一一个不完全开心的人。如果他在被击中时站着不动,这是他的错,对吧?如果他在动……哇,你是一个非常棒的狙击手。

但是,如果他处于空位,背后是一堵墙,然后在他认为自己安全的情况下,在几分之一秒后被枪杀了怎么办?

嗯,这可能发生。这是你做出的权衡。因为你过去向他射击,他在掩护后的几毫秒可能仍会被射杀。

这有点不公平,但对于每个参与者来说,这是最合适的解决方案。错过了一次不容错过的射击会更糟糕!

结论

这是我对于快节奏多人游戏的最后一篇文章。很显然很多事情很难做到正确,但是对于正在发生的事情有明确的概念性理解,这并不是很困难。

虽然这些文章的读者都是游戏开发者,但它也发现了另一群对这个感兴趣的读者:游戏玩家!从游戏玩家的角度来看,理解为什么有些事情以这种方式发生也是非常有趣的。

进一步阅读

尽管这些技术看起来很聪明,但我不能说对它们有任何功劳,这些文章只是我从其他渠道学到的一些概念所整理成的简单易懂的指南,其中包括文章、源代码以及一些实验。

关于这个主题相关的文章你可以参考:What Every Programmer Needs To Know About Game NetworkingLatency Compensating Methods in Client/Server In-game Protocol Design and Optimization