爆头!(亦称:延迟补偿)

简介:

自从我发表上一篇文章以来已经过去了很长很长一段时间(足足2年!我勒个去!),而让我惊喜的是,我收到了相当多询问“下一篇”的邮件。那么这就是“下一篇”了,也可以称为“潜在敏感性事件的时间统一”,但“爆头”这个词听起来更令人满意:)

简述:

前面三篇文章解释了一种客户端-服务器结构,可以被概况为以下几点:

·→服务器从所有客户端获得带有时间戳的输入指令信息

·→服务器处理这些信息并向世界更新

·→服务器周期性的向所有客户端发送游戏世界快照

·→客户端发送输入指令并自行在本地模拟出效果

·→客户端获取世界更新并:

           将预演信息同步给权威服务器

           插值获知其他实例的过去状态

从玩家的角度讲,这里会有两个重要后果:

·→玩家看到现时的自己

·→玩家看到过去的其他实例

这种情况通常没有问题,但是如果总是这样或者遇到空间敏感事件时就是问题了;例如射击击中你敌人的头时!

延迟补偿

当你用大狙精确的瞄准敌人的脑袋瓜时,你扣动扳机——这一击你不能打偏。

但是你打偏了。

咋回事?

是因为上述的客户端——服务器架构,你所瞄准射击的是你敌人100ms之前脑袋所在的位置,而不是你开枪时的位置!

换一种说法,这就像在一个光速非常非常低的宇宙中,你瞄准的是你敌人过去所在的位置,但是在你扣动扳机是人家早走了。

幸运的是,有个相对简单的解决办法,也是大多数情况下大多数玩家乐于接受的(会有一个例外,下文再说)

这里是其运作原理:

·→当你射击时,服务器将此事件的全部信息发送至服务器;精确的射击时间戳和精确的武器瞄准点。

·→这是关键性的一步。因为服务器获得所有输入信息都带有时间戳,它可以权威紧急重建过去的世界,特定情况下,可以立即重建一个指定时间点上和任意客户端看到的完全一致的精确世界。

·→这意味着服务器可以精确或者谁在你射击的那一刻在你武器的伤害范围之内。那就是你敌人过去时的脑袋瓜儿,但服务器也知道,在你屏幕上这就是他脑袋瓜儿现时的位置。

·→服务器处理完这个时间点的这一击之后,更新给客户端。

皆大欢喜!

服务器也欢喜,因为他是服务器,他总是欢喜的。(0.0)

你也欢喜,因为你瞄准敌人的头,射击,并且得到了爆头奖励!

敌人可能是唯一一个不怎么欢喜的人,如果他站着不动当活靶子,那是他自己的锅,对吧?可是如果他明明动了...喔,你真是个牛逼狙手。

但是假如他是在一个开阔地带,背后是墙,零点几秒后挨了一枪,他还仍然会觉得自己很安全吗?

这种事一定会发生。需要你做一下权衡。因为你打的是过去的他,所以在他跑到掩体后的若干毫秒内,他仍然可能被击中。

这就有点不公平了,但这也是能够最大限度让所有参与者接受的。明明能打中的打不中可比这糟多了!

结论:

以此来终结我关于快节奏多人游戏的系列文章。这种事是典型的很难完全处理正确的,但可以使进行中的事物有明确的概念认知,学习成本很低。

尽管这些文章的读者都是游戏开发者,我也发现了另一群感兴趣的读者:玩家!从玩家角度来说去弄清楚为什么某些事会发生以及其发生的原理也是很有趣的事情。

扩展阅读:

鉴于上述技术如此之精妙,我不敢声明任何对它们的权益;这些文章只是简单易懂的引导了一些概念。我也是从其他资源哪里学习得来的,包括文章和源代码以及一些实验。

与此主题相关性最高的文章有:

What EveryProgrammer Needs to Know About Game Networking and LatencyCompensating Methods in Client/Server In-game Protocol Design and Optimization.(《每个程序员都应该知道的:关于游戏网络》和《暗中补偿法客户端/服务器游戏内协议涉及和优化的应用》)