公司项目也完结了一阵时间了,是时候总结下经验了。
首先新手入门,中文搜索引擎能搜索到的博文我大抵上也看了7成,只推荐“云风”的那篇守望先锋同步解析博文,其他都是复制粘贴的垃圾。不然就是泛泛而谈,纸上谈兵,没有从代码层面去解析讲解。所以我推荐新手看完云风的那篇博文后去找找英语的博文,不得不承认,国外那些程序员理解很深刻且讲解很形象易懂。
然后说说我的经验之谈吧。由于能力有限,并不保证内容完全正确,如果你能够看到这篇文章请自行斟酌内容对错。
- 首先名称“帧同步”,我也不知道这个叫法谁起的,但我更认同云风博文里所说的“锁定步进算法”,这个更为形象贴切。简单来说帧同步是将整个游戏沙盒时间轴切成一个个逻辑帧,收集玩家在一个逻辑帧内的操作,然后通过中央服务器转发给所有玩家,并进行推演。文字的描述总是惨白的,不理解的可以去玩玩“文明”系列游戏,帧同步也就大体如此。
- 帧同步最基础也最重要概念:逻辑帧与渲染。反正我这么叫,不清楚他人是否也这样叫。帧同步之所以流量小对服务器压力小,因为帧同步一般只采集玩家的输入,并直接在玩家客户端推演他人的操作。当基于游戏的公平性,理论上所有玩家在同一时刻看到的画面应当相同,但由于玩家间设备、网络的差异,这是不可能实现的。(当然早年的即时战略游戏通过局域网、等待等措施消除了)由于设备的差异,有的人的画面会快一点有的会慢一点,当把逻辑依旧参杂在渲染流程中,那么势必设备好的玩家具有优势。(设备差的玩家由于卡顿,渲染稍慢,与设备好的玩家在同一时刻看到的画面不同)因此需要将游戏中的逻辑(击中,施法)从渲染中剥离,从而减少设备差异带来的不同步因素。
- 帧同步是将时间切成一块一块的,那么快越大玩家之间的延迟就越大,因此竞技类游戏一个逻辑帧是越小越好。但与此同时带宽要求也会越来越大(同一时间发送接收的数据包越来越多),所以一个逻辑帧时间应该视项目类型而定。
- “预测”:由于时间是块状的,且数据在链路上传输也需时间。因此,玩家的操作无法立即呈现在画面上,也就我们平时说的延迟感。对于一些类型游戏其实这种延迟可以忽略,但对于射击类的竞技游戏,这种延迟是万万不能有的。因此为了解决这个问题,人们在收到当前玩家操作后,会通过一系列算法去预测下一步,从而抹平延迟感。有预测就会有失败,失败后就需要回滚预测。
- “追帧”:当玩家的设备出现卡顿,掉线,链路拥堵的情况,那么这个玩家的演算进程就会比他人慢一些,为了公平,我们应当加快玩家本地的时间轴间隔,使他尽快追到他人相同的时间上。
- 网络链路不是通行无阻的,离中央服务器越远,越可能出现数据包阻塞更甚是丢包。出现这种情况时玩家本地推演将停止,表现就是其他人不动了。等数据包到达后为了公平开始“追帧”时又开始快速推演。这种情况就是人们常说的网卡了,出现这种是很影响体验的。解决方案是在当前时间上缓存若干个数据包,(时间轴推后),在网络波动时就有若干个逻辑帧的时间来等待阻塞的数据包了,这样就不会出现其他人不动的情况了。但这种处理会造成延迟感,须在二则之间寻找平衡点。
- 浮点数,这个很多博文都提到。由于计算机的实现,浮点数是有可能出现不一致的。常用解决方案是定点数或者将小数乘以一个较大的倍数(1000,10000)来抹除小数。其实都行,帧同步还是允许误差的,但可容忍的最大误差就应当视项目而定。