同步算法-三种同步方案

一、同步方案

根据服务端的输入输出内容,同步方案可以分为三大类,

  • 指令->指令
  • 指令->状态
  • 状态->状态

游戏中可能会采用其中的一种或几种方案的组合。服务端既可能接收“指令”或“状态”的输入,也可能输出“指令”或“状态”

如图所示。

 

在《球球大作战》中,服务端的输入是客户端发来的摇杆方向(即角色移动方向),输出是球的位置坐这种情况属于“指令->状态”同步;

又比如一些射击游戏,客户端直接发送角色的位置坐标,服务端只进行转标发,这种情况属于“状态->状态”同步。

下表列出了三种同步方案及其特性。

表中用 "√" 标记运算端,用“+”标记优化端。例如,“状态->状态”方案中,如果客户端要算出角色的新位置,那么它必须拥有物理引擎和逻辑运算功能(所以标记为"√”),服务端只需要转发协议即可。

但是,在“状态->状态”同步方案中,若玩家对客户端做手脚,则很容易作弊。如果服务端也拥有一定的运算能力,那么它可以通过做些校验来减少作弊行为,但这不是必须的(所以标记为“+”)。

再以《球球大作战》的“指令->状态”为例,由于所有的逻辑运算都在服务端,因此可以有效杜绝玩家作弊但是,如果玩家按下“前进”按键后,要等0.2秒才能看到效果(假设服务端的运算频率是每秒5次),那么玩家将感到游戏体验不佳。

"先行表现”也是一种常见的优化方法,在玩家按下“前进”的同时,客户端就会让球向前移动,若稍后服务端发来的新位置与“先行移动”到的位置接近,就不管它,如果相差太远,就再做调整。

帧同步是一种“指令->指令”同步方案,客户端发送“向前走”之类的指令,服务端只做转发,后续章节会有详细讨论。

 

二、适用场景

不同的同步方案适用于不同的游戏,如表所示,

游戏类型 最适用的方案   原因

射击(FPS)

状态->状态 对实时性要求高,玩家打出一枪后期待马上看到效果,用客户端运算的
方案,能给玩家即时反馈。由于同一个场景的玩家可能有很多,因此不适合采用帧同步的方案
即时战略(RTS) 指令->指令(帧同步) 需要同步大量单位,如果使用状态同步,则意味着需要同步大量数据,而“指令->指令”只需要同步小部分的操作指令
竞技(MOBA) 指令->指令(帧同步) 对公平性要求较高,即对误差的要求较高。从原理上看,帧同步可以保证多个客户端的误差很小
角色扮演(MMORPG) 指令->状态 同一个场景中的角色较多,不适合帧同步。如果需要较好地防止作弊,
且开发时间充裕,则最好选用“指令>状态”的方案
开房休闲类(如球球大作战)

指令->状态 或

指令->指令(帧同步)

若对实时性要求较低,但对防作弊的要求较高,则适合使用“指令->
状态”的同步方案。若需要同步大量单位(比如,在《球球大作战》的基
础上加个食物随机飘动的需求),则适合使用帧同步的方案

虽说每种游戏都有其最适用的同步方案,但有时候出于开发难度、人员配置、服务端硬件水平等多方面的考量,会进行诸多权衡。

例如,项目组客户端团队能力强,而服务端能力较弱,那么选用“状态->状态"或“指令->指令”的方案,能把工作量放到客户端;相反,如果服务端团队能力强,那“指令->状态”的方案能够减少客户端的工作量。

有时,我们需要结合多种同步方案,例如,某些角色扮演类游戏(ARPG)使用“状态->状态”的方案同步角色的位置,使用“指令->状态”的方案同步技能,使服务端具备一定的反作弊能力,同时又能平衡工作量,

因为客户端引擎大多集成了物理模块和寻路模块,容易实现角色移动的功能,服务端实现起来则相对比较困难。

下面,我们就来分析几款知名游戏的同步方案。

 

三、案例

  • 天涯明月刀

《天涯明月刀》是一款动作角色扮演类游戏,场景部分采用“状态->状态”的同步方案,辅之以服务端强校验。

不采用完全的“指令->状态"方案,是因为《天涯明月刀》的场景结构、技能触发规则都很复杂,如果完全由服务端运算,则负载太高,所以服务端通过采用低精度的地图数据和较低的运算频率来降低负载。

虽然服务端的运算结果不是很精确,但它足以应对作弊行为。“服务端同步运算"也意味着较高的开发成本,为了在服务端处理3D大地图,开发团队花费了很多精力。

 

  • 王者荣耀

竞技游戏《王者荣耀》采用了“指令->指令”(帧同步)同步方案,一方面是为了保证游戏的公平性,需要选用误差较小的方案;另一方面是需要同步的单位较多,算上小兵,一屏可能会有数十个单位。

《王者荣耀》选用帧同步也是经过了诸多因素的权衡,无论是“指令->状态”,还是《天涯明月刀》那样的服务端强校验,都会有较多的服务端开发工作。而《王者荣耀》开发初期工期很紧,选用“指令->指令”的同步方案,

可以有效减少服务端的工作量,客户端除了底层的“帧同步”模块之外,其他业务逻辑就像做单机游戏一样,较为简便。另外,“帧同步”也较容易实现战场回放的功能,只用把一场战斗的所有指令存储起来,逐一播放即可。

帧同步对网络质量的要求很高,为降低延迟,《王者荣耀》所采用的协议是自研的可靠UDP,关于可靠UDP,将在后面章节详细介绍。

 

  • 绝地求生大逃杀

包括《绝地求生大逃杀》在内的射击游戏大多采用“状态->状态”同步的方案。

射击游戏对即时反馈的要求很高,如果采用“指令->状态”的方式,那么数据经由服务端运算再传回,就会导致较高的延迟,从而影响玩家的游戏体验。

此外,射击游戏对物理碰撞精度的要求较高,需要精准判断子弹是否打到敌人、子弹是否被掩体挡住等问题,出于性能考虑,服务端会采用较低精度的地图(如《天涯明月刀》),因此这类游戏需要依赖客户端的运算能力。

帧同步方案不适用于这类游戏,因为地图很大,客户端难以完整计算整张地图的逻辑。使用“状态->状态”同客户端只需要关注玩家周围的事务即可,计算量较小。依赖客户端运算的游戏一般很难防止外挂作弊,

如图展示了一种飞天外挂,人物可以很不自然地在天上飞。

 

posted @ 2024-06-20 19:02  独一无二~  阅读(359)  评论(0)    收藏  举报