ComblockEngine(原KBEngine)源碼剖析3——移動同步分析

移動應該說是網遊裏面最最基礎的操作了, 但也是很重要的模塊,不同類型遊戲對於移動同步的精準度都是不同的,對於mmo這類非戰鬥向核心的遊戲來說,通常對於主從客戶端位置精準度要求不高,moba類遊戲則比較重視主從客戶端位置的精準度。由此,這兩類遊戲的同步策略一般也都是不同的。
爲了追求高同步性的,往往會關閉掉客戶端先行等策略,然後採用服務器驅動主從客戶端位置更新的強一致性策略;如果同步性要求不是特別敏感,則可以採取先行等方式,同時容易提升操作手感。

=.= 好像扯遠了,那些同步的策略其實屬於產品層面了。但引擎層實現的同步一般都是最基礎的,在做產品同步策略前,肯定要先對引擎的底層同步時機有一定了解,下面主要介紹的是引擎層面的流程細節。


操作時序圖

ClientBaseappCellapp操作搖桿,修改position主tick中,updatePlayerToServeronUpdateDataFromClient數據包安全校驗,查找cellonUpdateDataFromClient移速校驗校驗成功: onPositionChanged更新座標和AOI數據, addUpdateToStream更新AOI數據給客戶端ClientBaseappCellapp

流程分析

  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的距離差是無法避免的,一旦速度過大,在主從端上,兩個玩家看到的表現和遊戲體驗就會相差很大。
對於產品層面的同步策略,以後有機會再具體記錄分享~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章