| |
|
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
| -> 系统运维 -> 从游戏服务端角度分析移动同步(状态同步) -> 正文阅读 |
|
|
[系统运维]从游戏服务端角度分析移动同步(状态同步) |
从游戏服务端角度分析移动同步(状态同步)
??对于游戏服务端来说,针对状态同步主要需要考虑的是三大模块,即校验、模拟、计算。客户端输入的任何信息都需要进行校验,避免多人游戏作弊情况的发生。客户端在进行游戏的同时,服务端也同样进行游戏模拟,只不过对于服务端来说只有数据,且数据是离散的,而客户端不仅有数据,同时还有渲染表现。计算即对模拟的过程进行计算,比如已知速度时间求速度等。
技术术语
客户端策略??由于服务端和客户端的时间差异,将会引起逻辑上的问题,并且随着网络延迟的增高问题变得更加严重。如果所有的操作客户端都是等待服务端响应之后在处理,那么在快节奏的动作游戏中,甚至几毫秒的延迟,玩家都会有延迟感,并且对于命中判断这种问题,会造成难以击中其他玩家、难以和移动物体互动的情况。下面客户端通过两个方法来解决这个问题。一是客户端输入预测,一是平滑差值处理。 客户端输入预测??客户端在UI交互之后立即发送操作给服务端,此时,客户端不应该等待服务端的反馈,而应该立即移动,这个过程我们叫做客户端输入预测,那么客户端本地具体如果预测(我们约定本地玩家为p1)的目标点呢?我们假定客户端的输出流是稳定的(即客户端进行逻辑帧控制,按照一定的频率进行输出),那么客户端的始终总是会超前于服务器的,从客户端到服务端的时间,我们预计它大概超前半个RTT加上一个缓存帧的时长(缓存帧即多久进行一次输出处理)。也就是说,服务端收到客户端的状态改变移动同步请求时,客户端已经移动至如下位置(假定为二维平面,客户端当玩家操作UI时就立即进行响应移动)
??而服务端也会根据半个RTT加上从缓冲区取出玩家状态的时间来在当前Tick模拟角色状态。
这也就是为何客户端永远领先于服务端。正因为客户端是一股脑的尽快接受玩家输入并渲染响应,尽可能地贴近现在时刻提高玩家体验。而如果还需要等待服务器回包才能响应的话,那看起来就太慢了,会让游戏变得卡顿。服务端模拟完角色状态之后,响应对该角色感兴趣的角色(包括它状态改变的角色本身)正确的位置信息。那么也就意味着,客户端根据玩家输入的预测(历史轨迹)需要使用一个队列进行存储,最终服务端的回包不是和当前角色所在状态比较,而是跟角色的历史状态比较。判断是否合法。如果与服务端模拟结果相同,那么客户端会开开心心地继续处理下一个输入。如果结果不一致,那么就是一个”预测错误“。这时简单的处理就是直接使用服务都安下发的结果直接覆盖当前客户端的结果,但是这个结果可能已经非常”旧“(相对于当前时刻的输入来讲)了,因为服务单的会包可能都是在几百毫秒之前的了。复杂的做法是使用例外一个队列记录玩家的历史输入(注意,这里是记录输入,而不是输入后的预测),当预测失败时,我们将从服务端没有进行校验的历史操作到当前操作的所有历史输入一次性打包发送给服务端(即从最后一次被服务器确认的运动状态到现在的全部输入都发送给服务端),服务端一次性模拟完所有的操作(相当于重播一遍直至追上当前时刻,也被称为缓存重放机制),返回一个最新状态给客户端,也就意味着服务端直接追上客户端,与客户端状态保持一致。这时服务端再次响应所有对该角色感兴趣的角色(包括当前状态角色)正确的状态信息,客户端为了玩家体验,会进行平滑插值处理。 平滑插值??这里不做过多简述,可查阅网上资料。 服务端策略数据压缩??这里主要是对数据进行优化压缩,比如服务端AOI算法,具体可参考链接:https://blog.csdn.net/qq135595696/article/details/128377140 服务端滞后补偿??让我们来假设玩家在客户端时间10.5s时对某一个目标发出射击。开火的消息被打包成用户指令,并且发送给服务器。当这个数据包在网络传输,服务器还在持续模拟游戏世界的运行,相关目标可能会移动到一个完全不懂的位置上。 当10.6s时,玩家指令包到达服务器,但是此时服务器已经检测不到这个命中,尽管玩家确实瞄中了目标。这种错误,需要使用服务器端的滞后补偿来修正。 ??滞后补偿系统记录前1s内所有玩家的位置。如果一个玩家指令被执行,服务器将会用下面的公式来估算指令的生成时间:
??然后,服务器将所有其他玩家(只有玩家)移回到指令执行时刻的位置。这样玩家的指令在执行的时候就可以正确瞄准了。在用户指令被处理完成后,玩家恢复到当前时刻的位置。
??上图是监听服务器的屏幕截图,有200ms的网络延迟。红色的有效射击区表示的是目标在客户端上100ms + 平滑插值延 前的位置。从有效射击区显示的时间点开始,用户指令向服务器传送,目标也持续向左边移动。用户指令到达服务器,服务器根据估算出的指令生成时间重置目标的位置(蓝色有效射击区)。服务器运算出设计的弹道轨迹,并且检测出命中。 ??【额外说明】关于上图显示框体到底显示的是哪个时刻的简单计算:
??服务器和客户端的有效射击区并不是完全匹配的,这是因为时间精度上差异造成。对于高速移动的物体,就算是几毫秒的差异,也会造成数英寸的错误。多人游戏中,命中检测并不是完美的像素检测,他受到Tick频率精度和运动速度的影响。 ??网络中延迟和滞后补偿将会带来一个矛盾,这两个看似会使得游戏世界的运行与真实情况的偏离。举例来说,你可能在进入掩体之后,仍旧被一个已经看不到人击中。这个是因为,服务器已经把你的游戏角色的有效射击区及时移动到掩体后,但是在攻击者的客户端上,你的角色仍旧是暴露在掩体外的。这个不一致的问题,在缓慢的数据包传播速度之下并不能被解决。但是事实是,你并不能意识到这个问题,因为光速(数据包的传输速度)太快了,所以所有人都可以见到一个相同的、正确的世界。 |
|
|
|
|
| 上一篇文章 下一篇文章 查看所有文章 |
|
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
| 360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年10日历 | -2025/10/28 8:59:37- |
|
| 网站联系: qq:121756557 email:121756557@qq.com IT数码 |