帧同步&&状态同步

一、概念

状态同步

同步的是游戏中的各种状态。一般的流程是客户端上传操作到服务器,服务器收到后计算游戏行为的结果,然后以广播的方式下发游戏中各种状态,客户端收到状态后再根据状态显示内容。状态同步最广泛的应用应该是在回合制游戏中。

帧同步

帧同步常被RTS(即时战略)游戏常采用。在游戏中同步的是玩家的操作指令,操作指令包含当前的帧索引。一般的流程是客户端上传操作到服务器, 服务器收到后并不计算游戏行为, 而是转发到所有客户端。这里最重要的概念就是 **相同的输入 + 相同的时机 = 相同的输出**。

二、两者之间的区别

1.战斗核心逻辑

状态同步的战斗逻辑在服务端,帧同步的战斗逻辑在客户端。战斗逻辑是包括技能逻辑、普攻、属性、伤害、移动、AI、检测、碰撞等等的一系列内容,这常常也被视为游戏开发过程中最难的部分。(由于核心逻辑必须知道一个场景中的所有实体情况,所以MMO游戏(例如魔兽世界)就必须把战斗逻辑写在服务端,所以MMO游戏必须是状态同步的,因为MMO游戏的客户端承载有限,并不能把整张地图的实体全部展现出来(例如100米以外的NPC和玩家就不显示了),所以客户端没有足够的信息计算全图的人的所有行为)

2.客户端和服务端通信

状态同步下,客户端更像是一个服务端数据的表现层,举个例子,一个英雄的几乎所有属性(例如血量、攻击、防御、攻速、魔法值等等)都是服务端传给客户端的,而且在属性发生改变的时候,服务端需要实时告诉客户端哪些属性改变了,客户端并不能改变这些属性,而是服务端传来多少属性就显示多少属性(虽然可以改变客户端数值达到表现上的效果,例如无限血量,但是服务端那边的血量属性为0时,一样要死)。再举个例子,一个英雄要释放一个非指向性技能(例如伊泽瑞尔的Q),具体的过程就是,客户端通知服务端“我要释放一个技能”-》服务端通知客户端“在某地以什么方向释放某技能”-》客户端根据这些信息创建一个特效放在某地,然后以某个方向飞行-》服务端根据碰撞检测逻辑判断到某个时刻,这个技能碰到了敌方英雄,通知客户端-》客户端根据服务端信息,删除特效,被打的英雄减血同时播放受击特效。

帧同步下,通信就比较简单了,服务端只转发操作,不做任何逻辑处理。某一个客户端玩家释放了一个技能,这时候将操作传递给服务端,服务端不做任何判断以及逻辑上的处理,将这个客户端的操作下发给所有的客户端,所有的客户端处理此时收到的逻辑。

3.针对于游戏层次的区别

(1)状态同步帧同步流量消耗大,例如一个复杂游戏的英雄属性可能有100多条,每次改变都要同步一次属性,这个消耗是巨大的,而帧同步不需要同步属性;例如释放一个技能,服务端需要通知客户端很多条消息(必须是分步的,不然功能做不了),而帧同步就只需要转发一次操作就行了。

(2)帧同步回放&&观战状态同步好做得多,因为只需要保存每局所有人的操作就好了,而状态同步的回放&观战,需要有一个回放&观战服务器,当一局战斗打响,战斗服务器在给客户端发送消息的同时,还需要把这些消息发给放&观战服务器,回放&观战服务器做储存,如果有其他客户端请求回放或者观战,则回放&观战服务器把储存起来的消息按时间发给客户端。

(3)状态同步的安全性比帧同步高很多,因为状态同步的所有逻辑和数值都是在服务端的,如果想作弊,就必须攻击服务器,而攻击服务器的难度比更改自己客户端数据的难度高得多,而且更容易被追踪,被追踪到了还会有极高的法律风险。而帧同步因为所有数据全部在客户端,所以解析客户端的数据之后,就可以轻松达到自己想要的效果,例如moba类游戏的全图挂,吃鸡游戏的透视挂,都是没办法防止的,而更改数据达到胜利的作弊方式(例如更改自己的英雄攻击力)可以通过服务器比对同局其他人的战斗结果来预防。

(4)状态同步服务器压力比较大,因为要做更多运算。

(5)首先要说,状态同步的游戏占主流,其次就是状态同步开发起来比较难。而帧同步服务器开发难度低,同一套方案可以给很多不同类型的游戏使用,反正都是转发操作;减少了服务端客户端沟通,开发效率最起码提高20%,状态同步的方案下,同一个功能至少需要一个客户端和服务端共同完成;PVP和PVE基本用的是同一套代码,做完PVP很容易就可以做单机的PVE。

(6)状态同步的断线重连很好做,无非就是把整个场景和人物全部重新生成一遍,各种数值根据服务端提供加到人物身上而已。帧同步的断线重连就比较麻烦了,例如客户端在战场开始的第10秒短线了,第15秒连回来了,就需要服务端把第10秒到第15秒之间5秒内的所有消息一次性发给客户端,然后客户端加速整个游戏的核心逻辑运行速度,直到追上现有进度。

状态同步 帧同步
流量 相对高 相对低
回放 记录文件大 记录文件小
安全性 服务器实现逻辑,安全性高 逻辑在客户端,反外挂压力大、无法避免开图挂
服务器压力
战斗校验 协议加密,内存混肴,误差校验,无法彻底解决。 服务器可以重启跑一遍战斗。
网络卡顿的表现 瞬移,回位,莫名掉血 战斗卡顿
实现 调优状态同步方式,客户端需要做插值处理。 客户端按照单机方式开发,保证逻辑层和表现层分离。逻辑层不要用到浮点数,不要用不确定顺序的逻辑结构。

三、实现

状态同步

从一个开源游戏学习网络状态同步模型的实现(上)

从一个开源游戏学习网络状态同步模型的实现(下)

演示范例:https://www.gabrielgambetta.com/client-side-prediction-live-demo.html

帧同步

游戏帧同步的流程与实现

四、适用场景

帧同步和状态同步该怎么选(上)

帧同步和状态同步该怎么选(下)

参考

两种同步模式:状态同步和帧同步

游戏开发基础-帧同步与状态同步

网络游戏研发,该选帧同步还是状态同步?对比之后你就懂了


文章作者: DreamHeaven
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 DreamHeaven !
  目录