快节奏多人游戏同步(4)-延时补偿

Author Avatar
sNatic 5月 30, 2018
  • 在其它设备中阅读本文章

持续一个月的坑终于要填完了~全系列最后一篇贴出「原文地址」还有最后的「演示 Demo」,翻译的好累而且又不太能翻译到很通畅还能附带些许个人风格,感觉好难~下次还是自己原创一些文章比较好。最近几天打包打到晚上11点下班好累,希望有空可以真的把自动化打包的坑继续填起来。。。

PART 1 概述

之前三篇文章主要解释了关于 client-server 游戏架构,总结起来大概就是以下这些:

  • 服务器从所有的客户端获取带着时间戳的输入
  • 服务器负责处理所有输入并更新游戏世界的状态
  • 服务器向所有客户端发送游戏世界的快照
  • 客户端发送输入并自己模拟该输入造成的结果
  • 客户端获取世界更新
    • 将客户端自行预测的状态更新到与服务器一致的状态
    • 将其他客户端控制的实体插值到过去的状态

从玩家的角度来看,以上行为会导致两个重要的结果:

  • 玩家看到 自己 处于 现在
  • 玩家看到 其他玩家 处于 过去

通常来说这种情况并没有什么问题,但是在时间或空间敏感的状况下不太适合,比如说爆头之类的

PART 2 延时补偿

假设你正用狙击枪完美的瞄准目标的头部,此时射击绝对万无一失。

然而却没打到。。。

为什么会发生这种事情。。

因为我们之前解释过的 client-server 架构,你瞄准的是 100ms 之前的玩家的头,而不是开枪的时候的玩家的头。。。

在某种程度上相当于你在一个光速非常非常慢的宇宙中进行游戏,你瞄准的是敌人过去的位置,当你扣下扳机的时候他早就走远了。。

幸运的是,有一个相当简单的方案可以让大多数玩家在大多数情况下满意(下面会解释)

方法如下:

  • 开火的时候,客户端发送开火指令到服务器,同时包含开火的一瞬间确切的时间和方向。
  • 至关重要的一步,服务器获取到所有带有时间戳的输入后,服务器可以重新构建过去任何时刻的游戏状态。尤其是可以精确的重建任何客户端在任何时间点看到的游戏状态
  • 这意味着服务器可以确切的知道在你射击的一刹那你的枪瞄准的到底是什么,虽然那是你的目标的过去的位置,但是服务器知道你瞄准的就是你的目标在你自己的「当前时间」所在的位置
  • 服务器处理「该时间点」的射击行为并更新每个客户端

于是皆大欢喜~

服务器很开心是因为他是服务器,他永远都很开心。。。哦好冷啊

你很开心是因为你瞄准目标头部并射击,完成了一记漂亮的爆头

你的敌人可能是唯一不完全开心的哪个,如果他站在原地被你爆头那就是他的问题,但是如果他在移动的话,只能说明你是特别厉害的狙击手。

但是如果他在掩体附近,然后移动到掩体内部的安全位置后才被命中了呢?

好吧这的确有可能发生,但这就是你要为此付出的代价,因为你可以射击「过去的他」,他可能在进入掩体后几毫秒被射击。

从某种程度上来说这是不公平的,但这是大家接受程度最高的解决方案了,明明瞄准开枪最后却 miss 问题更大~

PART 3 总结

这篇文章是快节奏多人游戏同步这个系列的最后一篇了,虽然这类问题很难得到完美解答,但是对相关概念有了清晰理解以后再看也并不是那么困难。

虽然本文的读者都是游戏开发者,但依然有着另一部分读者对此很感兴趣,那就是玩家们。对玩家来说去理解诸如此类问题依然是一件很有趣的事情。

扩展阅读

以下是一些参考资料包括文章和源码之类的,可以帮助大家更方便的理解相关概念。

与本文相关性最高的文章如下 What Every Programmer Needs to Know About Game Networking Latency Compensating Methods in Client/Server In-game Protocol Design and Optimization.


原文链接:https://snatix.com/2018/05/30/018-lag-compensation/

本文由 sNatic 发布于『大喵的新窝』 转载请保留本申明