本文介绍什么游戏应该使用什么网络同步技术。
帧同步(Deterministic LockStep)与状态同步(State Synchronization)的区别,可以这么打比方:帧同步是所有客户端播放同一部电影,视觉上完全一样;状态同步是所有客户端拿着相同的剧本(状态一样),但是电影画面略有差异。而快照同步(Snapshot Interpolation),由于所有的仿真都发生在服务器,所以各个客户端视觉上是一致的,也是在播放同一部电影。
帧同步
- 对局制的,实体数量不多的可以考虑;像 mmo 这种可以随时进入退出的大世界模拟类的不适用。
- 对于面画有精确要求的,比如格斗类游戏,玩家的出招强依赖于对手的出招动作,所以保持双方视觉上的一致很有必要,此时就适用帧同步。
- 体育类、rts 等需要精细操作的也都适用帧同步。
- “很多时候需要保证服务器与客户端的每个角色对象的状态之间保持一致,但事实上很难做到一致。比如客户端和服务端更新的频率,对优化的一些裁剪,网络的抖动等等,要让每一个状态在客户端同步是比较难的,而想要调试这些东西,来优化带来的漏洞、不一致的现象,花费的周期也会比较长,想要达到优化好的水平也比较难。”[1]
快照同步
弱客户端,像小游戏,云游戏,可以使用快照同步。
状态同步
其他类型的,基本上都可以使用状态同步。
王者荣耀使用的是帧同步,这个分享《王者技术修炼之路》[1]说明了理由:
第一,它的开发效率比较高。如果你开发思路的整体框架是验证可行的,如果你把它的缺点解决了,那么你的开发思路完全就跟写单机一样,你只需要遵从这样的思路,尽量保证性能,程序该怎么写就怎么写。比如我们以前要在状态同步下面做一个复杂的技能,有很多段位的技能,可能要开发好几天,才能有一个稍微过得去的结果,而在帧同步下面,英雄做多段位技能很可能半天就搞定了。
第二,它能实现更强的打击感,打击感强除了我们说的各种反馈、特效、音效外,还有它的准确性。利用帧同步,游戏里面看到这些挥舞的动作,就能做到在比较准确的时刻产生反馈,以及动作本身的密度也可以做到很高的频率,这在状态同步下是比较难做的。
第三,它的流量消耗是稳定的。
moba 类型游戏其实是可以使用状态同步的,王者荣耀采用帧同步算是一种个性化的选择,也付出了很多努力来克服帧同步的弱点。不过上面分享的第二点也指出了,王者荣耀很强调act,画面上追求打击感,那要这种效果,用帧同步显然也是合情合理的。
守望先锋使用的是状态同步,这个分享《《守望先锋》回放技术-阵亡镜头、全场最佳和亮眼表现》[2]说明了理由:
Overwatch最终没有选择确定性帧同步方案,原因如下:首先,我们不希望程序员和策划的因为偶现的不确定性而产生心理负担;除此之外,要支持中途加入游戏也不简单。模拟操作本身就已经很耗了,如果5分钟的游戏过程,每次都需要重头开始模拟的话,计算量太大。
最后,实现一个阵亡镜头也会很困难,因为需要客户端快照以及快播机制。按理说如果游戏支持录像文件的话,快播自然就能做到,不过Overwatch并没有这一点。
参考
[1] 邓君. 王者技术修炼之路. Available at https://youxiputao.com/articles/11842, 2017-5.
[2] kevinan. 《守望先锋》回放技术-阵亡镜头、全场最佳和亮眼表现. Available at https://www.sohu.com/a/162289484_483399, 2017-8.