ComblockEngine(原KBEngine)源码剖析3——移动同步分析

移动应该说是网游里面最最基础的操作了, 但也是很重要的模块,不同类型游戏对于移动同步的精准度都是不同的,对于mmo这类非战斗向核心的游戏来说,通常对于主从客户端位置精准度要求不高,moba类游戏则比较重视主从客户端位置的精准度。由此,这两类游戏的同步策略一般也都是不同的。
为了追求高同步性的,往往会关闭掉客户端先行等策略,然后采用服务器驱动主从客户端位置更新的强一致性策略;如果同步性要求不是特别敏感,则可以采取先行等方式,同时容易提升操作手感。

=.= 好像扯远了,那些同步的策略其实属于产品层面了。但引擎层实现的同步一般都是最基础的,在做产品同步策略前,肯定要先对引擎的底层同步时机有一定了解,下面主要介绍的是引擎层面的流程细节。


操作时序图

Client Baseapp Cellapp 操作摇杆,修改position 主tick中,updatePlayerToServer onUpdateDataFromClient 数据包安全校验,查找cell onUpdateDataFromClient 移速校验 校验成功: onPositionChanged 更新坐标和AOI数据, addUpdateToStream 更新AOI数据给客户端 Client Baseapp Cellapp

流程分析

  1. 玩家推动一次摇杆,对于主客户端本地来说,位置数据是会先及时更新掉的(至于要不要渲染表现根据需求自己来定义),但是最新的坐标/朝向数据并不会即使通知到服务器。ComblockEngine是在下一次主tick中调用updatePlayerToServer接口将这些基础数据打包发送给服务器。也就是在逻辑层这里最大会有一个1/threadUpdateHZ秒数的延迟(默认是10帧,0.1秒)。
  2. 客户端的更新数据包会先到Baseappp,Baseapp类似于网关,会对包体等数据做一个基本的校验,然后查找实体对应的cell数据,并把数据包封装起来,以消息onUpdateDataFromClient发送给Cellapp。Cellapp收到消息后开始处理,如果移速校验通过,则会更新实体的坐标,同时更新AOI数据。
    忽略掉Baseapp->Cellapp之间通信的时差,每个appserver取出网络包消息处理也是在逻辑tick中完成,也就是说纯逻辑层面,这一步的最大延迟时长是 2*1/gameUpdateHertz (默认是10帧)
  3. 更新完实体的坐标位置后,这个数据并不是立刻下发给从客户端的,而是要等到下一次witness的update,在update里面推送AOI信息给从客户端端们,也就是这里还会存在一个延迟时长1/gameUpdateHertz
  4. 客户端在收到AOI数据到处理,也需要等待下一次tick,也就是最大延迟时长为1/threadUpdateHZ
  5. 以上,完成的是逻辑数据的更新,等玩家真实看到角色移动实际是在渲染帧中完成,也就是最大还有一个渲染tick的时长(1/60,按60帧来算)

以上,一次玩家的移动操作,到实际同步给其他玩家,在ComblockEngine里面至少需要以上6步骤,其实,其他主流游戏的这部分同步也都大同小异。我们除去这些网络进程间通信由于网络延迟导致的时长,单纯在游戏逻辑层面,最大存在的延迟时长=1/threadUpdateHZ + 2*1/gameUpdateHertz + 1/gameUpdateHertz + 1/threadUpdateHZ + 1/60 = 0.516s


结语

通过上面的时序图分析,看得出来,在网游里面,一次简单的摇杆推动操作,其背后实际上是需要跨越很多链路流程的,其中跨越的每个进程,如果出现任何一点异常,卡顿,都会严重影响到一次操作的手感和体验反馈。
我们上面的分析中,还是去除了网络波动的条件下,在纯软件架构层面做的延迟数据分析,这个系统层面的最大延迟就达到了500多毫秒,我们再假设,如果一次网络rtt是100毫秒,也就是平均一次移动操作的延迟是600毫秒(实际情况,应该是大于这个数值的)。这个延迟的数据,在具体游戏项目开发时,我们是不能轻易去忽视掉的,而且在不同类型下,这个数据带来的游戏体验效果也是相差很大的。
如果是一款moba高精度格斗类网游,技能释放如果对距离很敏感,就得注意在游戏层面尽量降低角色的移动速度,因为每秒speed * 0.6的距离差是无法避免的,一旦速度过大,在主从端上,两个玩家看到的表现和游戏体验就会相差很大。
对于产品层面的同步策略,以后有机会再具体记录分享~

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页