网络同步有3种:帧同步、状态同步、实时广播同步,开发过程中可以混合使用。
网络同步的目标就是时刻保证多台机器的游戏表现完全一致。
网络同步 = 实时的多端数据同步 + 实时的多端表现同步
帧同步适用于对网络延迟要求较高的游戏,例如:FPS游戏(射击游戏)、RTS游戏(即时战略游戏)。
(1)同步随机数种子(一般游戏中都设计随机数的使用,通过同步随机数种子,可以保持随机数一致性)。
(2)客户端上传操作指令(指令包括游戏操作和当前帧索引)。
(3)服务器广播所有客户端的操作(如果没有操作,也要广播空指令来驱动游戏帧前进)。
?状态同步适用于对网络延迟要求不高的游戏,例如:RPG游戏(角色扮演游戏)、回合制游戏。
(1)客户端上传操作到服务器。
(2)服务器收到后计算游戏行为的结果,然后以广播的方式下发游戏中各种状态。
(3)客户端收到状态后再根据状态显示内容。
同步方式 | 帧同步 | 状态同步 |
---|---|---|
确定性 | 严格确定 | 允许小误差,定时纠正误差数据 |
表现与响应速度 | 传统严格帧锁定要等其他客户端消息全部到达,响应比较慢;乐观帧锁定可以做到本地立刻响应,但是需要回滚的时候,体验就没那么好了。 | 一般会做预测,可以做到立刻响应。不做预测的话,响应时间是一个往返时间(RTT) |
带宽与流量 | 相对低,王者荣耀采用帧同步,流量30分钟8M。带宽随人数增加而增加,不适合MMO。 | 相对高,全民超神采用状态同步,流量30分钟20M。需要发送各种状态数据,带宽占用比较高。可以通过压缩、裁剪、增量等方式优化。 |
网络延迟适应性 | 要求较低的延迟。如果延迟较高,所有玩家体验都不好。即使采用乐观帧锁定优化,高延迟下也容易产生卡顿。 | 适应性较高,方便做各种插值优化。当然高延迟下,也容易产生位置突变。 |
开发难度 | 初期开发减法,框架容易实现,但是后期解决bug和完善系统很困难。比如浮点数、随机数、执行顺序导致计算结果不一致,问题很难排查。 | 框架比较复杂,客户端服务端一套代码,每个功能都需要客户端服务端联调。问题定位比较容易。但也会出现时序问题。 |
玩家数量 | 适合少量的玩家,比如:ACT、MOBA。 | 可多可少 |
跨平台 | 不适合跨平台,会有浮点数问题,可以用定点数来将误差控制在一个可接受范围,同时可以定时纠正结果。 | 适合。有权威服务器。 |
反外挂 | P2P架构不适合反外挂,如果引入战斗服务器来校验各个客户端结果,可以解决常见外挂,但是透视和全图视野防不了。 | 与服务器加入校验机制,可以起到比较好的反外挂效果。但是一样防不了透视外挂。 |
中途加入和断线重连 | 比较复杂。可以在断线的时候,通过快捷播放服务器同步的帧数据来快速跟上游戏。 | 容易。由于实时记录了各个对象的状态信息,所以重连的时候,直接创建这些对象,并同步信息即可。 |
性能(客户端) | 客户端要跑完整逻辑,还要执行渲染逻辑,开销比较大。 | 可以灵活优化,客户端跑较少逻辑。 |
回放(离线) | 本身收集了所有玩家的输入信息进行逻辑推进,天然支持回放,且回放文件比较小。 | 可以支持回放,但是逻辑比较复杂,需要不断记录状态信息,同时回放时候需要读取合适的时间。回放文件大。 |
回放(实时) | 比较复杂,客户端需要本地对全场状态进行序列化,才能回到目标时间。播完回放后还需要加速追上实时游戏状态。 | 相对容易,可以方便的记录快照信息,并按照录制内容随时播放。 |