幀鎖定同步演算法

2021-09-30 16:46:35 字數 2835 閱讀 1768

幀鎖定演算法解決遊戲同步

早期 rts,xbox360 live遊戲常用同步策略是什麼?格鬥遊戲多人聯機如何保證流暢性和一致性?如何才能像單機遊戲一樣編寫網遊?敬請**《幀鎖定同步演算法》

演算法概念

該演算法普遍要求網速rtt要在100ms以內,一般人數不超過8人,在這樣的情況下,可以像單機遊戲一樣編寫網路遊戲。所有客戶端任意時刻邏輯都是統一的,缺點是乙個人卡機,所有人等待。

1.客戶端定時(比如每五幀)上傳控制資訊。

2.伺服器收到所有控制資訊後廣播給所有客戶。

3.客戶端用伺服器發來的更新訊息中的控制資訊進行遊戲。

4.如果客戶端進行到下乙個關鍵幀(5幀後)時沒有收到伺服器的更新訊息則等待。

5.如果客戶端進行到下乙個關鍵幀時已經接收到了伺服器的更新訊息,則將上面的資料用於遊戲,並採集當前滑鼠鍵盤輸入傳送給伺服器,同時繼續進行下去。

6.服務端採集到所有資料後再次傳送下乙個關鍵幀更新訊息。

這個等待關鍵幀更新資料的過程稱為「幀鎖定」

應用案例:大部分rts遊戲,街霸ii(xbox360),callus模擬器。

演算法流程

客戶端邏輯:

1.        判斷當前幀f是否關鍵幀k1:如果不是跳轉(7)。

2.        如果是關鍵幀,則察看有沒有k1的update資料,如果沒有的話重複2等待。

3.        採集當前k1的輸入作為ctrl資料與k1編號一起傳送給伺服器

4.        從update k1中得到下乙個關鍵幀的號碼k2以及到下乙個關鍵幀之間的輸入資料i。

5.        從這個關鍵幀到下 乙個關鍵幀k2之間的虛擬輸入都用i。

6.        令k1 = k2。

7.        執行該幀邏輯

8.        跳轉(1)

服務端邏輯:

1.        收集所有客戶端本關鍵幀k1的ctrl資料(ctrl-k)等待知道收集完成所有的ctrl-k。

2.        根據所有ctrl-k,計算下乙個關鍵幀k2的update,計算再下乙個關鍵幀的編號k3。

3.        將update傳送給所有客戶端

4.        令k1=k2

5.        跳轉(1)

伺服器根據所有客戶端的最大rtt,平滑計算下乙個關鍵幀的編號,讓延遲根據網路情況自動調整。

演算法演示

我根據該演算法將街機模擬器修改出了乙個可用於多人對戰的版本,早期有乙個叫做kaillera的東西,可以幫助模擬器實現多人聯機,但是並沒有作幀鎖定,只是簡單將鍵盤訊息進行收集廣播而已,後來capcom在psp和360上都出過街霸的聯網版本,但是聯網效果不理想。這個演算法其實區域網有細就經常使用了,只是近年來公網速度提高,很容易找到rtt<50ms的伺服器,因此根據上述演算法,在平均rtt=100ms(操作靈敏度1/10秒),情況下,保證自動計算關鍵幀適應各種網路條件後,就能夠像編寫單機遊戲一樣開發網遊,而不需狀態上作複雜的位置/狀態同步。

從上圖的演示中可以看到,兩個模擬器程序都在執行1941這個遊戲,兩邊客戶端使用了該演算法,將邏輯統一在乙個整體中。

最後這張圖是執行kof99的效果圖,兩邊完美同步。

樂觀幀鎖定

針對傳統嚴格幀鎖定演算法中網速慢會卡到網速快的問題,實踐中線上動作遊戲通常用「定時不等待」的樂觀方式再每次interval時鐘發生時固定將操作廣播給所有使用者,不依賴具體每個玩家是否有操作更新:

1. 單個使用者當前鍵盤上下左右攻擊跳躍是否按下用乙個32位整數描述,服務端描述一局遊戲中最多8玩家的鍵盤操作為:int player_keyboards[8];

2. 服務端每秒鐘20-50次向所有客戶端傳送更新訊息(包含所有客戶端的操作和遞增的幀號):

update=(frameid,player_keyboards)

4. 客戶端如果沒有update資料了,就必須等待,直到有新的資料到來。

6. 客戶端只有按鍵按下或者放開,就會傳送訊息給服務端(而不是到每幀開始才採集鍵盤),訊息只包含乙個整數。服務端收到以後,改寫player_keyboards

雖然網速慢的玩家網路一卡,可能就被網速快的玩家給秒了(其他遊戲也差不多)。但是網速慢的玩家不會卡到快的玩家,只會感覺自己操作延遲而已。另乙個側面來說,土豪的網宿一般比較快,我們要照顧。

隨機數需要服務端提前將種子發給各個客戶端,各個客戶端算邏輯時用該種子生成隨機數,另外該例子以鍵盤操作為例,實際可以以更高階的操作為例,比如「正走向a點」,「正在攻擊」等。該方法目前也成功的被應用到了若干實時動作遊戲中。

指令快取

針對高階別的抽象指令(非前後可以覆蓋的鍵盤操作),比如即時戰略遊戲中,各種高階操作指令,在「樂觀幀鎖定」中,客戶端任何操作都是可靠訊息傳送到服務端,服務端快取在對應玩家的指令佇列裡面,然後定時向所有人廣播所有佇列裡面的歷史操作,廣播完成後清空佇列,等待新的指令上傳。客戶端收到後按順序執行這些指令,為了保證公平性,客戶端可以先執輪詢行每個使用者的第一條指令,執行完以後彈出佇列,再進入下一輪,直到沒有任何指令。這樣在即時戰略遊戲中,選擇 250ms乙個同步幀,每秒四次,已經足夠了。如果做的好還可以象 aoe一樣根據網速調整,比如網速快的時候,進化為每秒10幀,網速慢時退化成每秒4幀,2幀之類的。

幀同步 什麼是幀同步什麼是狀態同步

以下是moba第七章內容 第七章 ue4底層原理和ue4跨平台通訊外掛程式封裝 7 1 什麼是幀同步什麼是狀態同步 7 2 ue4客戶端和服務端的udpsocket如何初始化 7 3 ue4服務端的udpsocket初始化流程 7 4 ue4客戶端的udpsocket初始化流程 7 5 ue4握手階...

狀態同步和幀同步

狀態同步 傳送操作給服務端。服務端處理計算邏輯,更新客戶端資料 幀同步 傳送操作給服務端。服務端中轉所有資料 通過隨機因子保證每次得出結果一樣 總結一下 1 對於回合制戰鬥來講,其實選用哪種方式實現不是特別重要了,因為本身實現難度不是很高,採用狀態同步也能實現離線戰鬥驗證。所以採用幀同步的必要性不是...

幀同步和狀態同步

實時遊戲發展迅猛,同步技術也逐漸成為解決方案的核心之一。本文簡單討論了幀同步和狀態同步。什麼是幀同步 幀同步常被rts 即時戰略 遊戲常採用。在遊戲中同步的是玩家的操作指令,操作指令包含當前的幀索引。一般的流程是客戶端上傳操作到伺服器,伺服器收到後並不計算遊戲行為,而是 到所有客戶端。這裡最重要的概...