Playerchain 架構 - by 5p0rt5BEArD

原文 5p0rt5BEArD編輯 Chiny2025-02-17

原文連結: https://5p0rt5beard.substack.com/p/playerchain-architecture

文字與圖片由 5p0rt5BEArD 提供;架構設計由 Farms 提供

Image
Image

Playerchain 是一種遊戲客戶端架構,它整合了網路程式碼,用於形成使用共識而非伺服器來協調的點對點多人遊戲階段。階段共識建立在每個玩家維護的不變歷史記錄之上。這些個人區塊鏈以 DAG 結構連接,並在各個階段持續存在,從而實現以玩家為中心、持久且互連的遊戲世界。

Image
Image

構成 Playerchain 客戶端的核心元素。

遊戲程式碼(圖表中的綠色區塊)遵循與現有對等網路多人遊戲相似的模式:在每個客戶端上運行確定性模擬,並在網路中共享玩家輸入。

達成輸入一致性是共識(圖表中的藍色區塊)的工作。只要所有玩家都同意彼此輸入的順序和時間,那麼遊戲就會為每個人完美複製。

只要存在核心元素:單個玩家區塊鏈連接在一起形成一個區塊鏈,從而產生完全有序的輸入,共識的實現就是特定於遊戲的。本文重點介紹盡快達成最終確定性的方法,但也可以採用其他共識方法,並且需要權衡取捨。

Image
Image

我們的 Playerchain 測試版 [8] 需要快速共識。在 Github 上遊玩並查看原始碼。

像太空射擊這樣的遊戲類型,需要盡快達成最終確定性,因為玩家必須快速對彼此的動作做出反應,而動作修正會對玩家的世界觀產生重大影響。我們選擇太空射擊作為我們的示範應用程式,以便我們可以展示 Playerchain 如何在最具挑戰性的遊戲類型中運作。

受許可的群組組成

任何人都可以創建 Playerchain,但對 Playerchain 的訪問由群組控制。

在 Playerchain 階段開始之前,對等方必須互相找到並共享一個密鑰,以確保其群組的私密性。快速共識依賴於已知的固定群組,而不是減慢無許可鏈上共識速度的時間或基於金錢的安全性。

單人區塊鏈

Image
Image

每個輸入都包含在其自己的區塊結構中,該結構通過其雜湊引用先前的區塊,從而形成此玩家輸入的不變區塊鏈。對於我們的快速最終確定性方法,每一個計時器都會創建一個區塊,因此區塊還必須指示是否沒有進行輸入。這允許其他玩家知道等待輸入與沒有輸入需要等待之間的區別。

Blocklace 組成

在 Playerchain 中形成的 DAG 結構是一個 Blacklace [1];一種適用於應用多種類型共識的 CRDT。The Cordial Miners [2] 協議提出了各種在區塊鏈上達成共識的演算法。

每個玩家通過向當前 Playerchain 群組中的所有對等方發送包含其最新區塊的簽名訊息來共享其自己的區塊鏈。

Image
Image

玩家將他們自己的鏈與遠端玩家共享的鏈結合起來。

當玩家共享他們自己的區塊鏈時,他們也共享對彼此區塊的引用。根據 The Cordial Miners [2] 論文中提出的傳播演算法,形成了一個區塊鏈結構。區塊分組成回合,在收到當前回合中三分之二的對等方的區塊之前,不能開始新的區塊。

Image
Image

特定於遊戲的區塊鏈形成將 DAG 回合與遊戲計時器匹配。

對於 Playerchain 的盡快達成最終確定性的遊戲而言,每個回合都可以被認為與遊戲的模擬計時器匹配。因此,每個回合都包含特定遊戲畫面中每個玩家的輸入或明確的「無輸入」。

輸入排序

Image
Image

Playerchain 可以預先確定總順序以加快速度。

通過將區塊鏈回合與計時器匹配,客戶端可以向其區塊添加計時器編號。結合確定的玩家順序,每個區塊實際上都具有預先確定的總順序。這在分佈式共識中並不常見,在分佈式共識中,總順序需要進一步的輸入才能以演算法方式確定區塊的順序。對於區塊鏈,這可以使用 The Cordial Miners [2] 中的 Tau 排序演算法來完成,該演算法經過優化以減少最終確定性所需的回合數,但與預排序相比,它總是會增加更多時間。

預排序假設典型情況下是誠實的客戶端,並允許遊戲在收到輸入時立即顯示輸入,而不是等待進一步輸入以演算法方式確認順序。通過模棱兩可(向兩個對等方發送兩個不同的輸入)或聲明一個更舊計時器的輸入進行的不誠實攻擊將導致重新模擬,但遊戲將保持一致。

有一些已建立的技術 [3][4][5][6],例如預測和回滾,用於確保基於輸入的多人遊戲良好的遊戲體驗。在遠端玩家輸入到達之前預測它們的輸入,允許遊戲繼續而無需等待網路延遲。邏輯模擬繼續運行,將本地玩家的實際輸入與遠端玩家的預測輸入混合在一起。當到達的遠端玩家輸入與預測不同時,模擬將回滾到這些輸入之前的狀態,並使用正確的輸入重新播放。允許更正預測輸入的時間長度是「回滾視窗」。

Image
Image

Fightin’ Words [4] 上的網路程式碼文章出色地介紹了在格鬥遊戲中使用的預測和回滾。

預測與回滾

回滾後的重新模擬發生在單個渲染幀中。如果新的輸入沒有影響本地玩家,他們可能不會注意到。如果新的輸入導致影響本地玩家的狀態更改,他們可能會看到遊戲實體突然移動、消失或出現。

在以下遊戲中,這些副作用更為嚴重:

  • 玩家很可能正在相互互動。
  • 很難做出預測。
  • 小的輸入變化會對未來的狀態產生巨大的影響。

(所有這些都是太空射擊的特性)。

通過限制回滾視窗可以減少重新模擬。但是,如果達到回滾視窗時間並且沒有到達所有輸入,遊戲必須暫停或繼續,然後忽略任何遲到的輸入。

Playerchain 中的預測與回滾

預測和回滾可以在伺服器支援的網路中由中繼處理,但在 Playerchain 中,它必須由共識處理。回滾視窗的大小、暫停的決定以及要丟棄的輸入必須可預測地完成。不同的遊戲可以使用不同的演算法。下面我們逐步介紹為太空射擊遊戲開發的盡快達成最終確定性共識的演算法:

Image
Image

以下回合圖表的密鑰

回合 0. 群組組成

Image
Image

在群組組成時,所有客戶端都確定性地分配一個玩家索引,因此可以預測其未來每個區塊的總順序。

回合 1. 等待共識

Image
Image

我們,本地玩家,已經進行了輸入,但沒有收到任何其他輸入。在收到至少一個其他玩家輸入之前,不能產生任何其他區塊。(請參閱下面的調整以了解如何降低這種暫停的可能性)。

回合 2. 繼續預測

Image
Image

我們收到了「遠端 1」的回合 1 輸入。這達到了繼續並處理我們的回合 2 區塊所需的三分之二的多数。請注意,任何未收到的區塊都必須預測(點線),在本例中預測為「無輸入」。

回合 3. 回滾

我們收到了「遠端 1」的回合 2 輸入,而這是我們沒有預測到的輸入。遊戲將在我們的下一個渲染幀之前從回合 2 回放並重新模擬。

回合 4. 最終確定性

Image
Image

在本地,我們已經進展到回合 4,因為我們有回合 3 的三分之二的區塊。現在回合 1 已完成最終確定,因為我們有足夠的回合 1 輸入被我們的上一回合確認。將忽略任何未來收到的回合 1 區塊。

回合 5. 丟棄的輸入

Image
Image

我們終於收到了來自遠端 2 的一些輸入。回合 1 和 2 的輸入被忽略,因為它們錯過了回滾視窗。對於所有客戶端(包括遠端 2 客戶端本身)來說都是如此,它將丟棄自己的輸入並重新模擬以保持同步。

每個對等方都嘗試以目標遊戲計時器速率發送新的區塊,因此,只要所有對等方都在彼此之間的兩個計時器內接收所有遠端輸入,那麼遵循上述步驟的效果就是遊戲以目標幀率為每個人運行。這對網路來說是一個嚴格的約束,因此需要對一些特定於遊戲的元素進行一些調整,但特別是獲得最佳大小的回滾視窗。

平衡回滾視窗是調整具有預測和回滾的使用者體驗的关键部分。如果回滾視窗太短,並且少於三分之一的玩家落後,那麼落後者將會讓他們的輸入被丟棄,並擁有糟糕的體驗。如果超過三分之一的玩家落後,那麼其他人將會在等待至少三分之二的玩家趕上之前遊戲暫停。如果視窗太大,那麼與預測不同的遠端輸入更有可能導致每個人的視圖不穩定。平衡視窗必須考慮許多其他因素,這並不是 Playerchain 独有的。但是,增加區塊鏈中的回滾視窗是一個新的問題,我們通過交錯的回合集來解決這個問題:

Image
Image

引入區塊鏈形成的集合以增加回滾視窗。

區塊鏈傳播演算法要求回合通過要求每個對等方在創建新區塊之前等待看到上一回合的三分之二來平均進展。這相當於一個小的、兩個幀的回滾視窗。

通過增加每個本地客戶端可以提前的回合數,可以增加回滾視窗,但是該演算法要求區塊等待來自上一回合的引用。我們通過引入交錯的回合集來啟用更進一步的處理。當一個集合正在等待時,下一個集合可以繼續,直到我們用完集合(見上圖)。

Image
Image

使用 Cordial Miners 傳播的區塊鏈形成不需要等待訊息確認,因此對等方可以不受延遲限制地發送區塊,遊戲可以以高於延遲的計時器速率運行。每個新的輸入不是等待對上一個訊息的確認,而是與其他對等方的最新已知輸入的引用相結合,這些引用充當確認。

將訊息回合與遊戲計時器匹配並以固定的幀率為目標,允許以任何計時器速率為目標,包括每秒 30 次甚至 60 次計時器。在這些速率下,網路狀況不佳會導致回滾視窗頻繁被突破,因此使用者體驗不佳,因為某些玩家輸入會被丟棄或遊戲會暫停。因此,對於 Playerchain 測試版遊戲,該遊戲旨在在臨時網路環境中運行,我們將計時器速率設定為每秒 10 次計時器(請注意,渲染通常為 60fps)。

The Global Blocklace

Playerchain 測試版專案側重於展示對反應靈敏的多人遊戲階段盡快達成共識。Tashi 共識網路 [9] 實現了與之類似的架構(對實時遊戲輸入進行 DAG 共識)作為臨時側鏈。作為側鏈,可驗證的階段可以連接到公共區塊鏈,Playerchain 階段也是如此。Playerchain 的願景是它們也可以自行持久存在和連接,這就是選擇區塊鏈結構的原因。

在 Playerchain 測試版 [8] 中,每個階段為每個玩家創建一個新的密鑰對,該密鑰對在結束時將被丟棄,以及區塊鏈的任何記錄。通過引入在遊戲之間持續存在的玩家身份,每個玩家的區塊鏈及其上次階段互動也可以持續存在。當玩家加入新的群組並玩新的遊戲時,將形成一個全域區塊鏈,每個玩家都擁有跟踪其進度的部分視圖。

Image
Image

彩色補丁代表 Playerchain;群組同意在玩遊戲時一起進展的全域區塊鏈的部分視圖。

實際上,所有遊戲中所有玩家歷史的全域區塊鏈會遇到儲存問題和從不斷增長的歷史記錄中恢復狀態的時間限制。這些問題在區塊鏈領域中得到了很好的解決,例如可證明的狀態檢查點和內容可尋址儲存,但是要使全域區塊鏈成為現實,還有很多工作要做。

使用全域區塊鏈,隨著玩家和群組共享更多互動,信任也會建立起來。一個例子是來自同一遊戲的兩個 Playerchain 世界同意交易資源,因為他們可以驗證彼此對區塊鏈的部分視圖。與公共區塊鏈版本的狀態不同,不存在單體的公共視圖。全域狀態來自許多以玩家為中心的部分視圖。

為什麼要使用 Playerchain?

所提出的架構允許多人遊戲在沒有第三方基礎設施的情況下運行。從成本或維護方便的角度來看,這可能很有用。但是,Playmint 開發 Playerchain 的主要原因是為了製作用於遊玩而不是投機的去中心化遊戲。您可以在這裡 [7] 閱讀更多關於我們動機的資訊。

參考