天天看点

FPS游戏中的同步算法FPS游戏中的同步算法

FPS游戏中的同步算法

最近加班奋战2年多终于上线的游戏不到1个月因为种种原因也下线了, 随便写点东西缅怀一下。

在讲我们游戏的同步之前,我想先说下比较正统的做法,也就是守望先锋或者是unreal引擎自带的同步组件,权威服务器服务器跑完整逻辑的架构。 那为什么有这么正统的做法了,我们还要另辟蹊径呢? 原因可能是很多的。 比如要跑权威服务器服务器性能吃紧,同样机器能做到的在线就少了,比如一般服务器客户端各司其职,要统一一套相同的gameplay也因为种种原因不好统一等等。具体原因我之后介绍我们同步方案在介绍

那守望先锋是怎么同步的呢? 我们分为2个部分来讲, 守望先锋并没有具体分享远程玩家得同步,主要谈的是本地操控得玩家如何同步,我们先也分析下本地玩家,然后在讲下远程玩家的同步,其实这也是比较早得技术了,守望也说自己是站在先人得肩膀上,像雷神,CS都是这样得

local本地玩家:

因为是权威服务器,服务器有状态,所以服务器对客户端上报的每个操作都会跑完逻辑下发状态。 但是FPS游戏非常要求手感,以至于不能等到服务器回包在表现, 那样的话确实对大部分玩家来说不友好,而且网络还会有抖动等问题,如果要等到服务器回包在表现得话,那个手感就太糟糕了。所以客户端会优先响应玩家输入,并且反馈给玩家实时输出,比如移动,摇移视角等。 我们把这些都当作客户端得预测,输入也保留下来。假设客户端现在已经预测到100帧,服务器现在发回来了97帧确认得数据下来, 经过对比,一致当然最好了,我们可以开心得继续跑101帧,但是如果发现不一致呢,我们会把客户端状态退回到服务器确认得也就是97帧数据,然后把97-100帧得输入在执行一遍得到我们基于服务器97正确状态下的100帧。大部分情况下服务器应该是和客户端一致得, 因为我们是统一得逻辑代码,统一得步长等等,类似帧同步得思想。 那么什么情况下会不一致呢,首当其中肯定是外挂了,当然我们这里不强调介绍这种情况,外挂得话每一帧数据如果都是错的那么他会被一直拉回。 另外还有一种情况就是比如别人把你击杀,把你眩晕,把你冻住等等。

remote远程角色:

我们这里用得远程校色状态插值,也就是守望先锋GDC分享里面没有具体介绍过得,他们叫做(remote entity interpolation)。具体是怎么做呢? 我结合我们自己得项目讲下,大概思想就是local玩家每1/8秒会检测一次本地状态,如果有变更就发送到服务器,那么自然服务器会广播给所有客户端,那么我这边收到别得玩家同步下来得数据自然也是1秒8次左右这样子得量级,因为我这边收到远程玩家得数据是离散得,客户端需要做内插值把状态数据给平滑(当然我们得服务器也会这么做,大家可以思考下原因),并且表现。假如网络是平稳没有波动得,那么我这边得远程玩家得数据应该落后他本人一个RTT的时间. 可是网络状态往往就是那么不稳定,我可能一下收到好几个包或者一会收不到一个包,那么这种情况下,我们该如何处理呢?

我可以举几个例子,说不定会有更好的,但是我可以大体提供下思路。

1.我们可以设置一个buffer,那么这个buffer的大小就是可以抵抗网络抖动的大小,我们收到服务器状态时候并不马上执行,而是写入buffer,等时间到了在执行。如果看过王者荣耀的技术复盘分享应该也会知道这个buffer,但是王者说他们的buffer是0,意思就是并不需要这个,那么我们还能怎么做呢?

2.那么我觉得可以参考local玩家同步的方案,我们执行预测在回滚,比如我移动到某个点的时候理论上应该收到下一个包了,但是确迟迟没有收到,那么我们根据现有的状态,让他继续运动下去,等到正真的状态包来了在尝试和解。

写到这里有点累了,休息一下,也不知道会不会有人看,第一次在知乎写文章,不会排版,之后学习下。接下来应该会分享我们自己游戏local同步是怎么同步的以及这样的同步模型服务器该怎么做,比如向后缓和(backwardsreconciliation)或者说延迟补偿等,如果有更好的建议或者说有什么不认同的。都可以私信或者评论,我都会看的。也希望转发转载写明出处噢,谢谢

转自我自己的知乎CookiRui https://zhuanlan.zhihu.com/p/158008025

继续阅读