探討 Unity 實時多人遊戲的現狀,不同遊戲型別中的不同網路架構。
網路架構模式
遊戲開發者使用各種網路架構模式來確保多人遊戲中玩家之間可靠且快速的互動。每種模式都有其自身的優缺點,選擇合適的模式取決於您正在使用的特定遊戲型別和互動場景。
在本節中,我們將討論以下模式:鎖步、回滾、快照插值和延遲補償。此外,我們將討論最適合不同型別或遊戲的模式。
鎖幀(LockStep)
鎖幀(LockStep)是最古老的網路遊戲同步方法之一,如今仍然經常使用。雖然這種架構可以採用多種形式,但我們將重點介紹最常見的實現,然後討論必要的條件、限制和可能的配置。
在鎖步架構中,每個玩家將其輸入傳送到其他所有玩家,然後在收到所有玩家的輸入後立即推進其模擬——就是這樣!遊戲在網際網路上完全同步,使用非常少的頻寬,每個玩家始終看到事件的展開方式與其他所有人完全相同。
為了使遊戲與鎖步架構相容,必須滿足幾個條件。讓我們討論一下。
確定性
鎖步架構的主要要求是遊戲模擬必須支援嚴格的位級[確定性](https://www.whatgamesare.com/determinism.html)。由於網路程式碼只同步輸入,因此遊戲模擬必須在每個幀中使用相同的輸入資料在每臺機器上計算出相同的結果。否則,遊戲模擬將不同步、發散並偏離彼此——最終導致遊戲看起來完全不同。
這通常是一個難以滿足的條件,遊戲必須經過精心設計才能保持確定性。開發人員通常在每個幀或幀中的多個點檢查遊戲狀態校驗和,並將這些校驗和在參與者之間進行比較,以幫助跟蹤和修復在遊戲測試期間發生不同步的非確定性來源。
此外,任何使用浮點運算的遊戲(即大多數現代遊戲)都需要額外的考慮。如果您的遊戲在多個平臺上執行,由於平臺和編譯器之間的差異,浮點確定性可能特別難以實現。每個編譯器可以使用不同的指令集、重新排序指令或自動向量化。每個系統都可以以不同的方式實現超越函式,例如餘弦、正弦和正切。所有這些都可能導致平臺之間甚至構建之間出現不同步。一些開發人員完全使用定點運算或軟體模擬浮點運算來實現其遊戲模擬,以繞過使用浮點數產生的非確定性。
其他非確定性來源包括使用不同的種子生成隨機數或以不同的順序處理物件,例如物理中的接觸。所有這些考慮因素也極大地限制了可以用作遊戲模擬一部分的第三方庫,例如碰撞檢測庫、物理引擎等。因此,這對於許多型別的遊戲和引擎來說可能不切實際。
固定幀率
鎖步還要求所有玩家同步每個輸入和滴答所代表的時間單位。換句話說,遊戲將以固定的幀率進行。一些遊戲將渲染幀率鎖定為與固定模擬幀率匹配。其他遊戲允許以任意幀率進行渲染,並在固定滴答結果之間顯示插值。
問題和限制
雖然鎖步架構是最容易實現的架構之一,並且沒有視覺偽影,但它存在一些問題和限制。在某些情況下,可以透過對遊戲實現做出一些妥協來克服這些限制。在其他情況下,這些限制可能只是限制了這種架構對特定遊戲的適用性。
輸入延遲
鎖步透過等待直到收到所有相關資訊才推進,從而防止任何延遲引起的視覺偽影。這種等待有一個缺點:輸入延遲。
“輸入延遲”通常是指使用者按下按鈕到在螢幕上看到響應之間的時間。從使用者的角度來看,當他們在螢幕上看到該輸入的結果時,他們會感知到對他們輸入的響應。如果使用者必須等到所有其他玩家收到並處理他們的輸入才能看到此響應,這會導致明顯的輸入延遲。
在對反應性要求很高的遊戲中,例如射擊遊戲,輸入延遲可能是關鍵因素,因為它會使遊戲響應速度變慢,更難玩。
回滾
接下來,回滾是一種流行的網路程式碼架構,廣泛應用於現代競技遊戲,尤其是在格鬥遊戲中。
回滾可以看作是經典鎖步架構的擴充套件。在回滾架構中,玩家在每一幀傳送他們的命令,並在不等待其他玩家的命令的情況下繼續他們的遊戲。遊戲在不等待來自遠端玩家的資料的情況下進行——這被稱為“客戶端預測”,因為遠端輸入資料尚不可知,客戶端必須對其他玩家的未來行動做出假設。
與鎖步架構(它提供幀到幀的完美順序,但存在輸入延遲)相比,回滾架構提供即時命令響應,但以順序為代價。
在回滾過程中,遊戲會進行,並且一旦本地玩家的命令傳送出去,就會立即顯示出來。但是,由於尚未收到來自遠端玩家的命令,因此顯示的資訊是預測。一旦收到來自遠端玩家的資料,就必須將此新資訊與預測進行協調。如果資訊與預測不匹配,則遊戲將回滾以“糾正”錯誤。
什麼是“回滾”?
假設在客戶端準備渲染第 7 幀時,收到了來自遠端玩家的第 5 幀的新資料。在這種情況下,客戶端需要執行以下步驟:
-
載入/恢復整個遊戲的狀態,使其處於第 4 幀,即所有命令都已知的上一個不可預測幀。
-
使用第 5 幀的原始本地命令以及從遠端玩家新收到的命令,將遊戲移動到第 5 幀。
-
透過對每一幀應用本地命令繼續向前推進,直到我們到達當前幀(在我們的示例中,這是第 7 幀)。
完成這些步驟後,我們可能會注意到,遠端玩家在第 5 幀中的操作可能導致的結果與預測的結果不同;現在將在遊戲中顯示這些更正後的結果。
因此,在這種情況下,“回滾”意味著遊戲“回滾”到所有內容都已知的最後一幀,然後使用新資訊“重播”向前。這提供了糾正預測錯誤的能力。
需要注意的是,為了使此方法有效,遊戲必須能夠快速儲存和恢復其完整狀態,以及使用任意命令向前移動任意數量的幀。根據遊戲的複雜性,這可能需要大量的計算資源。
快照插值
快照插值是一種由遊戲 Quake 推廣的技術,此後已廣泛應用於源自 Quake 的遊戲和遊戲引擎。事實上,這種模型特別適合射擊遊戲。
快照插值方法基於遊戲物件兩個獨立的時間流的概念:一個反映過去物件的狀態,另一個反映未來物件預期狀態。
客戶端(玩家)將其命令傳送到伺服器,伺服器處理這些命令,更改遊戲狀態,然後將遊戲當前狀態的“快照”傳送回客戶端。此快照包含有關遊戲中的所有物件在建立快照時狀態的資訊。
為了保持遊戲的響應速度,客戶端會立即將部分命令應用於某些物件,預測其行為。這會導致物件在玩家的螢幕上同時以不同的狀態存在:
-
插值物件以它們在過去某個時間點的狀態表示。
-
預測物件以它們在未來某個時間點預期存在的狀態表示。
這會產生一種有趣的動態,例如,當您預測的角色試圖躲避一個正在插值的傳入彈丸時。這可能比看起來更難,因為您的角色正在未來移動,而彈丸則在過去。
儘管如此,這種模型還是有一些優點:
-
遊戲會立即響應玩家命令;與鎖步模型不同,不需要輸入延遲。
-
與完整的回滾架構相比,客戶端需要更少的處理時間。
-
物件在從伺服器獲得的已知狀態之間進行插值,因此物件只透過它們已經處於的狀態。
需要注意的是,為了有效地使用這種模型,遊戲必須能夠快速處理和傳輸遊戲狀態的快照,以及立即響應玩家命令。
不同遊戲型別的最佳架構
每種遊戲型別都會對網路延遲、穩定性和吞吐量施加其自身的限制。例如,MMO 遊戲需要高吞吐量、低延遲和高穩定性。同時,第一人稱射擊 (FPS) 遊戲需要低延遲和高吞吐量。在這兩種型別中,建議使用具有權威遊戲伺服器和基於狀態和輸入的資料交換的伺服器-客戶端拓撲。
下表提供了不同影片遊戲型別的網路需求、資料交換格式、推薦的網路拓撲和網路模式的比較概述。
透過分析此表,我們可以得出一些結論:
-
網路需求在很大程度上取決於型別:例如,RTS 和 FPS 遊戲需要低延遲才能確保流暢且逼真的遊戲體驗。
-
資料交換格式也因型別而異:大多數遊戲使用狀態和輸入交換,但有些遊戲,例如 RTS 和動作遊戲,只使用輸入。
-
網路模式和拓撲是根據每種型別的特定需求選擇的:動作和體育遊戲通常使用預測和回滾,而 MMO 和 RPG 遊戲通常使用快照預測和插值。
繼續前進
每款遊戲都有其自身的一套需求和型別交叉,這會對其網路互動施加其自身的限制。在許多情況下,選擇經過驗證的解決方案將比獨立開發更好。
在這篇文章中,我們回顧了實時多人遊戲中網路架構的主要模式。我們還彙總了一個針對不同型別推薦解決方案的通用表格。當然,這些建議並非最終的和通用的,但它們可以作為您選擇架構解決方案時的起點。