This document is about: QUANTUM 3
SWITCH TO

Quantum 3 Intro

概述

Photon Quantum是一個高性能的確定性ECS(實體元件系統)框架,用於以Unity製作的線上多人遊戲。

它使用一種稱為預測/復原的方法,非常適合對延遲敏感的線上遊戲,如動作RPG、體育遊戲、格鬥遊戲、FPS等更多遊戲。

Quantum幫助開發人員編寫乾淨的程式碼。它將模擬邏輯(Quantum ECS)與視圖/表示(Unity)解耦,並負責網路實作的參數(內部預測/復原+傳輸層+與遊戲無關的伺服器邏輯)。

Quantum Decoupled Architecture
Quantum引擎架構概述。遊戲程式碼與表示邏輯完全解耦。

Quantum實作了由以下部分組成的最先進的科技堆:

  • 伺服器管理的預測/復原模擬核心。
  • 稀疏集ECS記憶體模型和API。
  • 全套無狀態確定性程式庫(數學、2D和3D物理、導航等)。
  • 豐富的Unity編輯器整合和工具。

所有這些都建立在成熟且經過行業驗證的現有Photon產品和基礎設施之上(Photon Realtime傳輸層、Photon伺服器外掛程式到主機伺服器邏輯等);

沒有鎖步的確定性

在確定性系統中,遊戲客戶端只與所有客戶端上本機運行的模擬交換玩家輸入。在過去,這使用了一種鎖步方法,在這種方法中,遊戲客戶端會在更新模擬的每個刷新/幀之前等待所有其他玩家的輸入。

然而,在Quantum中,遊戲客戶端可以使用輸入預測在本機自由推進模擬,高級復原系統負責恢復遊戲狀態並重新模擬任何預測錯誤。

因為Quantum還依賴於一個泛遊戲的權威伺服器元件(Photon伺服器外掛程式)來管理輸入延遲和時鐘同步,客戶端永遠不需要等待最慢的一個來向前復原/確認模擬:

Quantum Server-Managed predict/Rollback
在Quantum中,確定性輸入交換是透過泛遊戲的伺服器邏輯進行管理的。這可以防止具有不良網路的遊戲客戶端干擾在良好網路上的玩家的體驗。

以下是Quantum遊戲的基本組建塊:

  • Quantum伺服器外掛程式:管理遊戲客戶端之間的輸入定時和傳遞,充當時鐘同步源。
    可以擴展以整合到客戶託管的後端系統(對戰配對、玩家服務等)。
  • 遊戲客戶端模擬器:與Quantum伺服器通信,運行本機模擬,執行所有輸入預測和復原。
  • 自訂遊戲遊玩程式碼:由顧客使用Quantum ECS開發為獨立的純C#模擬(與Unity解耦)。
    除了提供組織高性能程式碼的框架的方法外,Quantum的API還提供了大量可在任何遊戲中重複使用的預先組建元件(資料)和系統(邏輯),如確定性3D向量數學、2D和3D物理引擎、導航網格路徑尋找器等。

老派編碼

從所有模擬程式碼必須是開箱即用的高性能的假設開始,Quantum內部系統的設計都從一開始就考慮到了這一點。

Quantum的高性能的關鍵是使用基於指標的C#程式碼及其稀疏集ECS記憶體模型(所有基於記憶體對齊的資料結構和自訂堆集分配器-在運行時不會從模擬程式碼中收集垃圾)。

目標是將大部分CPU預算留給視圖/渲染程式碼(Unity),包括預測/復原方法固有的輸入預測錯誤引起的重新模擬:

Quantum hyper-fast predict/rollback
Quantum旨在使您的模擬程式碼盡可能快地運行,將大部分CPU預算用於渲染更新。

儘管基於指標的C#的使用是公開的(為了效能),但透過巧妙地使用自訂DSL和自動程式碼生成,開發人員可以避免掉大部分複雜性。

程式碼生成

在Quantum中,所有遊戲遊玩資料(遊戲狀態)要麼保存在稀疏集ECS資料結構(實體和元件)中,要麼保存在我們的自訂堆集分配器(動態集合和自訂資料)中,始終作為Blittable記憶體對齊C#結構。

為了定義其中的所有資料結構,開發人員使用了一種自訂的DSL(網域特定語言),使他能夠專注於遊戲概念,而不是效能方面的限制:

C#

// components define reusable game state data groups

component Resources
{
  Int32 Mana;
  FP Health;
}

// structs, c-style unions, enums, flags, etc, can be defined directly from the DSL as well
struct CustomData
{
  FP Delay;
  Boolean Active;
}

上面的程式碼片段將為特殊類型(如元件)生成相應的類型(具有顯式的記憶體對齊)、序列化程式碼和通用模版控制邏輯。

自動生成的API允許您査詢和修改遊戲狀態,並提供全面的功能來迭代、修改、創建或銷毀實體(基於組合):

C#

var es = frame.Filter<Transform3D, Resources>();
// Next fills in copies of each of the components + the EntityRef
while (es.NextUnsafe(out var entity, out var transform, out var resources)) {
  transform->Position += FPVector3.Forward * frame.DeltaTime;
}

無狀態系統

雖然Quantum的DSL涵蓋了實體、元件及輔助結構(結構、結局、聯合、位元集、集合等)等概念的遊戲狀態資料定義,但需要有一種方法來組織將更新此遊戲狀態的自訂遊戲邏輯。

您可以透過實作系統來編寫自訂邏輯,這些系統是無狀態的邏輯片段,Quantum的客戶端模擬迴圈將在每個刷新更新時執行它:

C#

public unsafe class LogicSystem : SystemMainThread
{
  public override void Update(Frame f)
  {
    // your game logic here (f is a reference for the generated game state container).
  }
}

系統API遊戲迴圈調用順序、系統內部通信信號(包括自訂和預先組建的信號,如物理引擎碰撞回調)、事件和其他幾個擴展掛鉤。

事件

雖然模擬是在純C#中實作的,沒有直接參照Unity的API,但有兩個重要功能可以讓遊戲遊玩程式碼與渲染引擎進行通信:事件和資產連結系統。

事件是遊戲程式碼通知渲染引擎在模擬過程中發生的重要事情的一種管道。
一個很好的例子是,某些事情會對角色造成傷害。

以上一節中的狀態為基礎,想像一下,傷害會降低角色實體資源元件的健康值。
從Unity渲染指令碼中,唯一值得注意的資料將是新的健康值本身,無法知道造成傷害的原因,以及之前的健康值等。

DSL檔案中的事件定義:

C#

event Damage
{
    entity_ref Character;
    FP Amount;
}

遊戲遊玩程式碼將事件作為一個簡單的API調用(生成):

C#

public void ApplyDamage(Frame f, EntityRef c, FP amount)
{
  // logic to apply damage to the character itself

  // this sends an event to the "view" (Unity)
  f.Events.Damage(amount, c);
}

Quantum的事件處理器將在刷新更新完成後處理所有生成的事件,處理需要伺服器確認輸入的事件、事件重複,以及在模擬復原發生時取消/確認的事件。

然後,從模擬程式碼中引發的事件可以在運行時從Unity指令碼中創建的回調中使用:

C#

public void OnDamage(DamageEvent dmg)
{
  // instantiate and show floating damage number above the target character, etc
}

資產連結

Unity以其靈活的編輯器和流暢的資源管路而聞名。
資產連結系統允許遊戲和關卡設計師從Unity編輯器創建和編輯資料驅動的模擬物件,然後將其輸入模擬。
這對於原型製作和為遊戲遊玩增加最終的平衡點至關重要。

從C#模擬專案中,開發人員創建了一個資料驅動的類別,公開了所需的屬性:

C#

public partial class CharacterSpec
{
    public FP MaxHealth;
    public int MaxMana;
}

然後,從Unity中,關卡設計者可以根據需要創建此資產的任意多個執行個體,每個執行個體都會自動分配一個唯一的GUID:

Character Classes - Asset Linking
資產連結系統示例:直接從Unity編輯器創建/修改資料驅動的角色規格資產容器。

然後,程式人員可以直接在模擬中使用這些資產中的資料:

C#

var data = frame.FindAsset<CharacterClass>("character_class_id");
var mana = data.MaxMana;

也可以在狀態定義DSL的元件中直接參照這些資產:

C#

component CharacterAbilities
{
    asset_ref<CharacterSpec> CharacterSpec;
}

確定性程式庫

在Quantum中,模擬需要在所有客戶端上計算相同的結果,前提是它們使用相同的輸入值。
這意味著它必須是確定性的,這意味著既不使用任何浮點或雙精度變數,也不使用Unity API中的任何東西,如向量、物理引擎等。

為了幫助遊戲開發人員實作這種遊戲遊玩風格,Quantum附帶了一個靈活且可擴展的確定性程式庫,既有一組類別/結構/函數,也有一些在使用DSL定義實體時可以直接使用的元件。

以下模組可用:

  • 確定性數學程式庫:FP(定點)類型(Q48.16)用於替換浮點數/雙精度數、FPVector2、FPVector3、FPMatrix、FPQuaternion、RNGSession、FPBounds2以及所有額外的數學工具,包括安全強制轉換和來自原生類型的解析器。
    數學程式庫的實作以效能為主要目標,因此我們盡可能地大量使用內嵌、查找表和快速運算器。
  • 2D和3D物理引擎:高性能無狀態2D/3D物理引擎,支持靜態和動態物件、回調、關節等。
  • 導航網格/路徑尋找器/代理:包括現有Unity導航網格的匯出器或直接操縱網格的編輯器。還包括行業標準的HRVO防撞、漏斗路徑和更多功能。

下一步去哪裡

要開始使用Quantum,我們強烈建議從Asteroids教學開始。本教學將教導您開始使用Quantum所需的所有基礎知識。它有文字和影片格式。

Back to top