简直是从零开始学,业余时间多抓紧。再浑浑噩噩全家都要跟我一起遭殃!
https://www.zhihu.com/question/29076648/answer/1946885829?utm_psn=1746438947788804096
Z乎:在《Valorant》中,客户端与服务器的移动和物理都是保持128帧运行的,这使得两端的每一帧都可以 一一 对应上,这极大地方便了服务端的命中判定,服务器只需把其他人的位置回退固定的帧数,就可以与客户端上的位置匹配。
参考OOD设计模式:备忘录模式
备忘录是行为模式,核心行为是“恢复快照”,它是罕见的不需要依靠OOP多态就能实现的设计模式。
在任一时刻,客户端看到的自己的位置始终是领先于服务器的,但看到的其他人的位置又都是落后于服务器的。这导致——战斗中,我们始终是在用将来位置的自己去打过去位置的敌人。例如客户端A在t3时刻瞄准了B,并开枪射击,服务器收到射击事件时已经是第i帧了,但t3时刻和t4时刻 玩家B在服务器上的位置都不是PBe。
解决命中问题的经典方案是 —— 服务器做玩家位置回退。服务器记录一段时间内每个人的历史位置和Pose,收到A的射击事件时,服务器把A之外的所有玩家都挪回到一个恰当的历史位置去,使服务器上其他人的位置与A看到的其他人位置基本一致。这样,客户端上能打中的 服务器上就也能打中了。
但这种方案也有问题:它对被打的那一方不公平。例如t3时刻,玩家B明明已经躲起来了,在客户端B的世界里 玩家A是打不到自己的(位置PAe与位置PBi),结果你t3时刻的开火还是打死了自己。
要解决这个问题,一般是给回退的时长加一个约束,例如最多只允许回退一个RTT。
服务器未收到移动输入,仍然根据当前的状态每帧做预测,当出现分歧时始终以服务器的模拟为准,并且每帧都下发角色的位置。
这样做,无论个人怎么卡,其他9个人看到的角色移动始终是平滑的,但卡的那个人自己会被频繁地拉扯。