帧同步_帧同步和状态同步该怎么选(上)
這是一篇拖延了2年多的文章…2017年10月份開始寫的,直到這次過年才寫完。。。
前言
隨著王者榮耀的崛起,使用幀同步(Lockstep)的游戲也越來越多,關于幀同步和狀態同步的討論爭論也有不少,那么到底該選哪種同步機制呢?兩種機制都使用過,各有優缺點也都踩過不少坑,這里對幀同步和狀態同步進行一下總結和討論。
首先需要說明, 這里的幀同步其實是指LockStep,是指服務器按幀轉發客戶端的操作,客戶端進行確定性運算和一致性模擬(同步操作兩邊客戶端通過完全一致的操作計算出完全一致的狀態)。每幀同步狀態這里也認為是狀態同步。
這兩種同步機制都是為了達到即時同步不同客戶端的狀態的目的,幀同步需要參與者去管理和維護其自有的那份拷貝,通過施加一致的邏輯來推動所有的狀態去同步地更新;狀態同步則隨著時間的流逝不斷地比較和發送最小的狀態變化和差異。
我們先看一些使用這兩種同步機制的案例:
可以看到大部分類型游戲,兩種同步方式都可以使用,但絕大部分游戲使用狀態同步,大量玩家戰斗的游戲只能使用狀態同步。
網絡模型發展歷程
下面簡單介紹一下網絡同步模型的發展。我們可以從DOOM/QUAKE I/II/III的演化來看到同步模型的發展。可以參考DOOM3網絡模型的演化與網絡架構這篇文章。同步方式的歷程大概是幀同步(Lockstep),快照同步(Snapshot synchronization),狀態同步(State synchronization),目前絕大部分多人游戲都使用狀態同步。
P2P 模型 (DOOM)
DOOM (1994) 的網絡模型是基于P2P的幀同步。有著幀同步的各種問題,后面會介紹。并且因為沒有主機,每個玩家直連其他所有玩家任何一個人卡所有人都卡,是一個非常古老的同步技術。
Packet Server (包的簡單中繼)
這個模型在原版 DOOM 的基礎上增加了一個 Packet Server,負責轉發所有的 tick command。玩家不再直連其他所有玩家,而是連到這個服務器 (某個玩家機器上) 以獲取最新的狀態。這樣改進后,同步量降低了,一個玩家卡只會自己卡,當然如果服務器卡就會卡。體感可以參考魔獸爭霸,主機卡了所有人都會卡。同時如果主機是服務器可以避免絕大部分作弊情況,但如果主機是玩家主機作弊就沒辦法了。幀同步的其他缺陷也沒有得到解決。
Client Server (Quake I/II/III)CS架構
Quake I/II/III 實現了比較典型的 C/S 架構 (1996)。這個模型中服務器負責所有的邏輯判斷,客戶端本質上只是一個渲染終端。玩家把自己的操作和輸入發送給服務器,收到一個實體列表用于渲染。服務器把壓縮后的快照按照固定頻率發送客戶端 客戶端使用這些快照來插值或推導出平滑連貫的體驗 。
這時候同步機制已經變成了服務器同步操作客戶端計算邏輯,服務器同步狀態的狀態同步了,解決了幀同步的大部分問題。但Quake I還做的比較簡單,和幀同步不同的是把所有邏輯相關的放在了服務器,客戶端在發送操作之后就要等服務器同步狀態。延遲問題還是沒有得到解決,同時因為要同步所有狀態信息帶寬占用很高,當游戲越復雜帶寬就越高。
Quake III做了進一步的優化。客戶端不是等待服務器而是會預測可能的游戲狀態,預測狀態和服務器端邏輯使用一套代碼,如果服務器和客戶端確實不一致,則服務器為準強同步。
預測也是降低延遲感的一個重要方式,對延遲要求很高的FPS特別重要。并且狀態同步服務器永遠所有信息也能允許玩家中途加入和退出了。但同樣的開發復雜度也變的更高了,代碼需要區分服務器和客戶端,需要邏輯和表現分離,需要處理一些聯調的問題(服務器和客戶端處理時間不一致,預表現差值問題,強同步問題)。
半條命(基于Quake引擎開發)在這個基礎上引入了一種延遲補償 (lag compensation),當玩家向某個目標 (若干毫秒前的狀態) 射擊時,做實際檢測的服務器會采用該目標若干毫秒前的狀態來檢驗是否擊中。這么做需要服務器把之前一小段時間的狀態持續地保存下來,這樣不僅增加了實現復雜度,而且導致了某種程度的不一致性。延時高的玩家反而更容易因為補償獲得更有利的判斷,嚴重影響游戲體驗 。這種補償只能對目標的位置回滾,而所有其他環境狀態的改變卻已無法倒退,這也會影響實際的體驗。
Quake III 里對同步信息做了進一步壓縮和優化,只有在 PVS 內的實體才會被同步狀態,而且被同步的是壓縮后的與上一次同步的差值 (delta compressed relative to the entity states from a previous snapshot,Delta技術) 。
可以看到當玩家比較少的時候,幀同步只需要同步操作,流量會比較小,非常適合同屏大量小兵的情況(小兵不需要同步任何信息),極省帶寬。但是當玩家多的時候每個玩家的操作都要互相同步,帶寬就會指數增長,無法優化,反而狀態同步可以通過分區域的方式同步支持更多的玩家。
與Quake III 不同,Doom III 的服務器和客戶端使用同一份代碼來更新/預測實體的狀態,這樣不用擔心服務器和客戶端邏輯的互相干擾,同時客戶端和服務器也一相同的邏輯幀率運行60fps,每幀客戶端上傳玩家輸入,服務器按固定間隔同步PVS范圍內的狀態快照,也可以理解為按幀同步的狀態同步。
Doom III在網絡上使用UDP,自己通過冗余包和滑動窗口保證服務器消息不丟失和有序并且允許客戶端上行丟包,在弱網情況下比TCP延遲更低,不需要TimeOut機制。
兩者的優缺點對比
那么我們再來對比一下幀同步和狀態各自的優缺點:
總結
以上是生活随笔為你收集整理的帧同步_帧同步和状态同步该怎么选(上)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 计算机应用基础试卷结果分析,计算机应用基
- 下一篇: 为什么支付宝理财产品的稳健理财也会有涨跌