幀同步和狀態同步
02-28
這裡我根據自己的理解和經驗對比一下幀同步和狀態同步的主要區別以及各自的優缺點。幀同步我沒有使用過,在具體的理解上可能會有偏差。
幀同步:
伺服器負責轉化客戶端的操作,每個客戶端在固定的邏輯幀執行該幀所有客戶端的操作命令,通過在嚴格一致的時間軸上執行同樣的命令序列得到同樣的結果。主流的老牌RTS遊戲都是幀同步:星際爭霸、war3
優點:
- 開發方便,可以無視客戶端伺服器(但是要考慮邏輯和表現分離)
- 打擊感反饋好,例如所有的命中都能在本地馬上觸發相應的扣血和打擊表現,反饋及時準確,無須像狀態同步那樣等待伺服器推送扣血或者向伺服器請求扣血。
- 網路流量小,這個會帶來很多好處:帶寬費用小、用戶成本低、降低收發包帶來的耗電(據說比較可觀)
缺點:
- 對網路要求高。這個涉及到具體幀同步實現的方式。
鎖幀問題,伺服器會等待所有的客戶端的第N幀操作都到齊之後再發送到各客戶端第N幀的操作,這樣一旦有一個客戶端網路波動,所有人都會卡住。war3的做法是加入了超時機制,如果在第N幀超時沒有收到某個客戶端第N幀的操作,就不再等待這個客戶端的這幀操作,並認為該客戶端在這幀什麼都沒做。但是如果這個客戶端只是延遲很高,他所有的操作是否都會被伺服器判定無效呢?
邏輯幀平滑問題,一般收到的邏輯幀命令數據會加入客戶端正在順序執行的邏輯幀的隊列中。如果隊列設置過長,操作延遲就會比較高;如果隊列很短,在網路波動時,就會出現隊列為空飢餓狀態,造成邏輯幀不平滑。這個可以採用邏輯和表現分離、平滑插值等做法。邏輯和表現分離做的比較好的話可以做到無buffer。平滑插值是一些表現的過渡處理,比如卡頓感一個很主要的來源是怪物移動的不平滑,一個比較好的應對方法是以怪物方向為主計算位置,即使沒有邏輯幀,表現幀也會繼續根據當前方向速度計算位置,這樣即使延遲出現波動時也不會出現位移的不平滑。 - 反外掛能力差,容易本地修改,開圖,修改屬性等。
- 斷線重連需要追幀
- 客戶端邏輯計算性能壓力大,需要每邏輯幀計算所有遊戲單位的邏輯狀態,即使單位不在屏幕內。
- 對結果一致性控制比較嚴格,如果使用了第三方的庫,需要能夠控制結果的一致性。其他因素包括浮點計算在不同平台的誤差差異、隨機數序列一致性、一些容器的訪問順序問題。
狀態同步:
伺服器承載所有計算,客戶端只做表現。主流的大型MMO遊戲都採用狀態同步。
優點:
- 容易斷線重連
- 容易防外掛
- 簡單粗暴
缺點:
- 流量大
- 打擊感反饋匹配不夠精準,因為所有的表現都是伺服器推送的,在網路波動、客戶端伺服器不同計算的誤差下,客戶端各個表現比較難契合。
- 對網路要求也會比較高,如果2中說的各個表現的契合,以及位移等都會受到網路波動的影響。
無論是狀態同步還是幀同步,對於網路延遲的優化都會涉及到的問題是:
- 在網路協議層優化,可靠UDP代替TCP,降低延遲
- 在表現上優化,客戶端先行、平滑插值等在表現上降低對延遲的感受
推薦閱讀:
※狀態同步的錄像系統
※狀態同步扣血匹配的坑
※遊戲排行榜
※skynet初探
※遊戲線上的伺服器風險
TAG:遊戲伺服器 |