了解多人在线游戏的原理

今天看了篇文章,讲的是多人游戏服务同步的东西。这个问题之前也有疑问,毕竟自己也玩恰鸡,但是没细想。
英文原文:链接
翻译相对还不错的中文译文:链接
挂屡禁不止,肯定有其他绕过这篇文章里技术的方案,仅了解大致原理层面。不做深究。
对于单机游戏而言,客户端和服务器的交互无所谓,只是影响自己。对于多人游戏,就要去考虑用户作弊。
一种方案就是:

不发送状态,而是发送指令,服务端判断处理并返回状态。这样就不会出现人物瞬移开挂的情况了。
但是这样对于网络延迟就太明显了,不可接受。
改进一些就是:假设用户为client1
,client1
发出的指令是正常指令(大部分用户不会开挂),那就在client1
发出指令后,上传服务器的同时,在A的电脑上渲染A的指令,比如人物移动。

但是客户端渲染的速度和服务端响应的速度不一定能对上,而且用户往往会连发指令。比如:

client1
连发两个移动指令,并且client1
的电脑渲染出了移动后的结果,但是过了一段时间后,才收到服务器第一条指令的响应。
一对比,服务器才移动到11位置,怎么本机电脑都移动到12了。
解决:给指令加上序号,客户端本地队列保存发送给服务器的所有指令,收到服务器响应后删除对应的指令。
这样才是一个客户端,多人游戏,多个客户端。
那样client1
的动作在其他人看来就是一卡一卡的,因为其他客户端,比如B,是要从服务器接受client1
的动作的,但是服务器并不是时刻知道A的状态的(是采样)。

就上这张图中client2
看到的client1
的两个状态,就要根据插值等方法去模拟连续client1
的动作用于client2
端的显示了。
这样导致的情况就是client2
得到client1
的状态是滞后的。可能你躲到了墙后面,以为安全了,下一刻你死了。
因为有延迟,在client1
自己看来,自己电脑上已经躲到墙后面了,但是在client2
看来,client1
躲到围墙后这个状态还没有到服务器,也没有到client2
的电脑上,所以client2
还是能打到client1
的。
如果网络延迟较小,体验应该还行。具体细节不深究了。
各个游戏应该策略不同,可能有异曲同工之妙。怪不得打游戏有时感觉自己已经残血躲起来了,下一刻自己挂了。
用Rust
实现一下简单的模拟。
搞了半天才跑通。
github
代码:链接
示意图,红色是我的操作,绿色是服务器端,蓝色是另一个客户端看到的我的操作。(模拟网络延迟)
