【網絡遊戲同步技術】幀同步的一致性

【參考博文】GAD-網絡遊戲同步技術

引言

  幀同步的形式很泛,根據不同遊戲,使用的技術範圍又不一樣,所以大家都在講方法論,要全面覆蓋可能需要較大的篇幅,所以,我簡單描述下。

  假定大家對幀同步和狀態同步有一定的認識,理論上的問題,我就不作過多解釋了。

  大家都知道,幀同步的核心是一致性,通過一致性的算法,使得各端輸入一致的情形下,輸出也是一致的,以此,可以解決同步的根本問題——仲裁的結果是一致的。

  嚴格的幀同步,實現起來,解決算法一致性、輸入一致性的問題基本就能實現了,然而實踐過程中,由於網絡延時、抖動、用戶實時體驗帶來了一些其他的問題,使得問題解決起來變得更復雜,爲了把問題聚焦,這部分內容我們就不重點討論,後面的篇幅,主要聚焦在如何保證算法一致性和輸入一致性。

1.算法一致性(或者確定性)

  算法不一致的主要原因是數值計算不一致和算法流程不一致。

數值計算。
浮點數的運算精度,在不同機器上有不同的表現,由此,導致了浮點數的精度可能導致計算結果不一致。
所以,首要問題是把遊戲邏輯部分(後續會有關於邏輯和表現分離的說明)所使用的浮點數運算全部改成具有一致性的數值運算。

那麼,怎麼實現一種數值運算,既具有小數的表達能力,又有一致性的運算結果呢?
常規方法中,儘管形態多樣,但理論來講,基本都是定點數(關於定點數的實現,可以翻看其他資料)。

工程上,還要考慮定點數的精度,不同的精度,性能可能不一樣,如何在精度和性能之間做平衡,需要結合自己的數值範圍來確定。

綜上所述,我們導出需要實現的代碼。
實現1:定點數
包含浮點數計算的常規算法,包含加、減、乘、除、絕對值、負運算等基本運算,另外,還要根據自己的使用實現開平方、指數函數、對數函數,三角函數等。
其中定義域較大的函數,一般使用解方程的方法,比如牛頓法,定義域較小或者可以限制到一個週期以內的函數,比如三角函數,定義域在0-2pi,可以使用泰勒級數,具體用幾階,要根據自身對精度的要求,同時,由於有限項的泰勒級數只在某些定義域區間較好的擬合度,所以需要在通過數值分析來論證精度。最後,其實三角函數可以通過查表法來實現,性能快,精度與所需要存儲的表格大小有關係。

至此,我們擁有了一致性的定點數,我們用它來替換浮點數,然後在有些應用場景,邏輯層也會使用到更多的數學工具,比如向量、矩陣、歐拉角、四元數等,所以我們得實現這部分數學工具。

實現2:一致性數學工具
1. 向量、矩陣、歐拉角、四元數
2.幾何工具:點、線、面、體,各種幾何元素的關係,相交性檢測(做一個射擊遊戲,需要射線檢測來判定是否命中),不是所有的都要寫,用多少實現多少。

除了上述的內容,還有邏輯層可能用了物理,物理部分主要包含碰撞檢測和動力學
比如拋出一個籃球,帶拋物線的,需要一致性的物理運算,籃球碰到框則需要一致性的碰撞檢測,碰到框之後的反饋也可能需要動力學表現(這部分可以是表現層)。

實現3:一致性物理系統
包含邏輯層需要使用的動力學和碰撞檢測

有些遊戲邏輯需要動畫系統支持,比如動作遊戲,一個技能觸發一個動作,動作除了表現層的動畫(比如2D遊戲的圖片序列),還有一些影響邏輯的部分,比如動畫控制了攻擊判定框在時間軸的變化,這個時候需要實現邏輯層上的動畫,主要需要解決的問題是,時間要改成整數或者定點數,另外,插值數據的類型也得使用一致性得數據類型,比如位置向量等。

實現4:一致性動畫系統
與常規得表現層動畫類似,可以根據需要簡化。(比如不需要骨骼或者不需要融合)

數值一致性的常規問題大致說這麼多,還有些其他的內容,比如尋路,AI判定等凡是有浮點數的地方,全部換成定點數,最終還是需要根據項目需求,選擇需要實現的內容。

注意:定點數的運算性能比浮點數差很遠,數量級在10-100以上,需要評估性能,好規劃策劃設定的問題規模。

前面講到,算法不一致的另外一個原因是:流程不一致。
流程不一致的主要原因,可能是輸入導致的,也可能是架構導致的。

輸入導致的算法流程不一致,這個問題,我們把它歸到輸入一致性,後面討論。
主要討論架構導致的流程不一致。

首先,幀同步需要在架構上做邏輯和表現分離,那麼,什麼是邏輯,什麼是表現,其實沒有絕對的定論,一般來說,對遊戲結果有影響的部分爲邏輯,對遊戲結果沒影響,隻影響視覺、聽覺、和其他與遊戲結果無關的用戶交互的部分爲表現。

整個幀同步的運行體系,簡單的模型歷程流程大致爲:
遊戲框架跟從網絡收取同步包->上傳用戶輸入->分發同步包給邏輯內核(用戶輸入)->邏輯內核更新->邏輯內核發送消息給表現層->表現層更新

需要注意的幾點:
1.邏輯更新頻度和表現更新頻度不一致
2.邏輯內核更新的時間片是等間隔的,表現不一定
3.同步包的內容是所有用戶在某個時間片以內的輸入

容易出錯的地方是,邏輯層和表現層交織在一起,表現層影響邏輯層,導致算法流程不一致。

所以,幀同步實施的第一要務是明確分離邏輯層和表現層。

輸入一致性

  完了算法計算一致性,接下來,我們要討論,輸入一致性的問題。
這裏所說的輸入比較籠統,整理講的是邏輯層的輸入,包含一些全局變量、隨機數的種子等等,最重要的一個問題是,邏輯層每幀的時間間隔是固定的,沒有特殊需求的話,建議用整數表示,精確爲毫秒。

一致性的細節問題還有很多,先大概講這麼多吧。

解決了一致性問題,一個嚴格的幀同步模型,後續實施就相對輕鬆了。

強調下,爲什麼反覆提“嚴格”的幀同步模型,因爲實際運行過程中,很可能出現不嚴格的模型,當網絡延時較大、抖動、以及遊戲對輸入響應有更高要求的時候,需要做一些預先的表現(表現層的預測),當結果預測不一致的時候,需要回滾,這個跟狀態同步差不多,當然也有邏輯層的預測,算幀同步的高級應用,目前少有遊戲使用。

最後,說下回放、斷線、反外掛、注意事項

幀同步實現回放有天生的技術優勢,因爲有了一致性的保證,存儲初始數據和用戶輸入,邏輯內核啓動播放模式,將時間軸的用戶輸入,按照時間軸消耗即可。

斷線其實是回放的變種,應用形態不一樣,技術差不多,可以不驅動表現。

反外掛,幀同步的遊戲結果是所有客戶端一起說了算,算法一致性保證了大家的結果是一致的,可以簡單使用少數服從多數的方式來判定誰用外掛,兩方數量一致(或者差不多)的情形,可以使用部署在仲裁服務器上的邏輯內核來計算結果,以服務器爲準。

注意事項
幀同步適用的情形:參與玩家數量不多(人數影響單個同步包的大小)
有利情形:各端需要同步的NPC數量衆多、遊戲邏輯運算量很大

大概就這麼多,表達能力有限,感覺也沒講清楚,只是希望對你有所幫助。

發佈了22 篇原創文章 · 獲贊 7 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章