Quantumイントロ
概要
2.0 SDKはダウンロードしてすぐに使えます。
また、最新のバグ修正や新機能にすぐにアクセスできるように、恒久的に利用可能な "フラグ付き "バージョンにタグを設定して毎晩ビルドする、より高速なリリースの反復プロセスに移行しています: SDK のダウンロードセクションを確認してください。
Photon Quantumは、Unityで作られたオンラインマルチプレイヤーゲームのための高性能な決定論的ECS(Entity Component System)フレームワークです。
アクションRPG、スポーツゲーム、格闘ゲーム、FPSなど、レイテンシーの影響を受けやすいオンラインゲームに最適な予測/ロールバックアプローチを採用しています。
また、Quantumは、シミュレーションロジック(Quantum ECS)をビュー/プレゼンテーション(Unity)から完全に切り離して、クリーンなコードを書くのに役立ち、同時に、ネットワーク実装の仕様(内部予測/ロールバック、トランスポートレイヤー、ゲーム不可知論のサーバーロジック)も考慮しています:

Quantumは以下のような要素で構築された最先端の技術スタックを搭載しています。
・サーバーマネージド予測・ロールバックシミュレーションコア
・スパース集合ECSメモリモデルおよびAPI(SDKバージョン2で新登場)
・ステートレス決定性ライブラリ完備(マス、2Dおよび3D物理、ナビゲーションなど)
・リッチなUnityエディタ統合とツーリング
すべて、業界で証明され、成熟した既存のPhoton製品およびインフラストラクチャを加えてビルドしています(トランスポートレイヤーとしてPhoton Realtime、サーバーロジックをホストするためのPhoton Serverプラグインなど)。
SDKバージョン2での新機能
Quantum 2ではバージョン1.2で確立された、実戦で証明済みの基盤にもとづいて、主要な改善がおこなわれました。 お客様と社内の開発チームの双方が想定していた機能を実現するために、技術スタック全体の見直しと再構築を行いました。
これらは最も重要な新機能です(SDK 2.0 Alpha-1とSDK 1.2.4.1の比較)。
- スパース集合 静的なタイプのコード生成されたエンティティを置き換えるために、ダイナミックエンティティとコンポーネント(追加/削除)を持つECSメモリモデル。
- データ駆動型のエンティティプロトタイプを追加し、QuantumDBアセットとして、またはUnityシーンに直接格納できるようになりました(Map Assetにベイクイン)。
- ロールバックを完全にサポートした 動的コレクション フレームワーク (新しいカスタムヒープアロケータに格納されています)。
- DBアセットオブジェクトのスレッドセーフな 動的ローディング、決定論的なオンデマンド同期またはバックグラウンド非同期プリロード、およびランタイムメモリ消費管理の完全な廃棄を含む。
- 2Dおよび3D物理エンジン 内部コアが書き直され、完全に並列化されたブロードフェーズ、先制クエリ、その他多くのパフォーマンス改善と機能(ジョイント、入室/残留/退室コールバックなど)が追加されました。
- 新しいタスクシステムは、内部で使用され、顧客の高度な用途に使用されます(システムはタスクであり、タスクの依存関係を自由にスケジュールする機能など)。 これには、内部の*タスクプロファイラーのための包括的なUIが含まれています。
- メニューシーンのサンプルスクリプトから、PUNへの依存関係を削除しました(Quantumは、リーンなPhoton Realtime C#トランスポートレイヤーの最新バージョンを組み込むようになりました)。
ロックステップなしの決定論
決定論的なシステムでは、ゲームクライアントは、すべてのクライアント上でローカルに実行されているシミュレーションでプレーヤーの入力を交換するだけです。
過去には、ゲームクライアントがシミュレーションの各ティック/フレームを更新する前に、他のすべてのプレイヤーからの入力を待つロックステップアプローチを使用していました。
Quantumでは、ゲームクライアントは入力予測を使用してシミュレーションをローカルに自由に進めることができ、高度なロールバックシステムがゲームの状態を復元し、誤予測を再シミュレーションします。
Quantumは入力レイテンシーとクロック同期を管理するためにゲームに依存しない信頼できるサーバコンポーネント(Photonサーバープラグイン)に依存するため、クライアントは最遅のものをロールバックして前方を確認する必要はありません。

以下はQuantumゲームの基本のビルドブロックです。
Quantum Server Plugin: ゲームクライアント間の入力タイミングと配信を管理し、クロック同期ソースとして機能します。
顧客がホスティングするバックエンドシステム(マッチメイキング、プレイヤーサービスなど)と統合するために拡張することができます。Game Client Simulator: Quantumサーバーと通信し、ローカルシミュレーションを実行してすべての入力予測とロールバックを実行します。
Custom Gameplay Code: Quantum ECSを使用して、孤立した(Unityから切り離された)純粋なC#シミュレーションとして開発されました。
QuantumのAPIは、高性能なコードの編成の枠組みを提供するだけでなく、決定論的な3Dベクトル計算、2D物理エンジン、navmeshパスファインダー、アニメーターなどのあらゆるゲームで再利用できる、あらかじめ構築されたコンポーネント(データ)とシステム(ロジック)を提供します。
従来のコーディング
Quantumの内部システムは、デフォルトの状態ですべてのシミュレーションコードが高性能でなければならないという前提に基づいて、設計されています。
Quantumの高いパフォーマンスの鍵は、ポインタベースのC#コードとスパース集合ECSメモリモデルを組み合わせて使用していることです(すべてのベースとなるメモリアラインドデータ構造とカスタムヒープアロケータを使用しているため、シミュレーションコードからの実行時にガベージコレクションが発生しません)。
目標は、ビュー/レンダリングコード(Unity)のCPU割当の大部分をそのまま留めることです。ここには予測/ロールバックアプローチに固有の、入力の誤予測によって引き起こされる再シミュレーションが含まれます。

ポインタベースのC#の使用は(パフォーマンスのために)公開されていますが、カスタムDSLと自動コード生成を巧みに使用することで、開発者に複雑さを感じさせません。
コード生成
Quantumでは、すべてのゲームプレイデータ(ゲーム状態)は、スパースセットされたECSデータ構造体(エンティティとコンポーネント)か、カスタムのヒープアロケータ(動的コレクションとカスタムデータ)のいずれかに保持され、転送可能でメモリ配置された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 Resources;
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).
}
}
Systems APIゲームループの呼び出し順序、システム間通信(物理エンジンコリジョンコールバックなどのカスタムおよびプレビルドの両方)の信号、イベントおよびその他の拡張フック。
イベント
シミュレーションは、UnityのAPIを直接参照することなく純粋なC#で実装されていますが、ゲームプレイコードとレンダリングエンジンとの通信を可能にする重要な2つの機能としてイベントとアセットリンキングシステムが使用されます。
イベントは、ゲームコードがシミュレーション中に重要なことが発生したことをレンダリングエンジンに知らせるための方法です。
例えば、キャラクターにダメージを与える出来事などです。
前のセクションのステートを基にして、ダメージがキャラクタエンティティのリソースコンポーネントからHP値を減少させるのを想像してください。
Unityのレンダリングスクリプトで唯一明確になっているデータは、新しいHP値そのものです。ダメージの原因や以前のHP値などを把握することはできません。
ファイルDSL内のイベント定義:
C#
event Damage
{
entity_ref Character;
FP Amount;
}
ゲームプレイコードは、(生成された)単純なAPIコールとしてイベントを発生させます。
C#
public void ApplyDamage(Frame f, EntityRef c, FP amount)
{
// missing here, the 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 Editorからデータ駆動型シミュレーションオブジェクトを作成して編集し、シミュレーションに入力できます。
これは、ゲームプレイに最終的なバランス調整を追加するためのプロトタイプに不可欠で
開発者は、C#シミュレーションプロジェクトから適切な属性を公開するデータ駆動型クラスを作成します。
C#
public partial class CharacterClass
{
public Int32 MaxMana;
public FP MaxHealth;
}
その後、Unityレベルのデザイナーは、必要に応じてこのアセットのインスタンスを何個でも作成でき、それぞれのアセットにはUnique GUIDが自動的に割り当てられます。

そして、プログラマーはこれらのアセットからのデータをシミュレーションの内部から直接使用することができます。
C#
var data = frame.FindAsset<CharacterClass>("character_class_id");
var mana = data.MaxMana;
ステート定義DSLから、コンポーネントでこれらのアセットを直接参照することもできます。
component CharacterAbilities{
asset_ref<CharacterClass> CharacterData;
}
決定論的ライブラリ
Quantumでは、同じ入力値を使用する場合、シミュレーションはすべてのクライアントで同じ結果を計算する必要があります。
つまり決定論的であり、フロート変数や倍精度変数、ベクトル、物理エンジンなどのUnity APIのいずれも使用していないことを意味します。
ゲーム開発者がこのスタイルのゲームプレイを実現するために、Quantumには、クラス/構造体/関数のセットと、DSLでエンティティを定義するときに直接使用できるいくつかのコンポーネントの両方を含む、柔軟で拡張可能な決定論的ライブラリがバンドルされています。
以下のモジュールが利用可能です:
- 決定論的な数学ライブラリ:float/doubleの代わりとなるFP (Fixed Point) 型 (Q48.16)、FPVector2、FPVector3、FPMatrix、FPQuaternion、RNGSession、FPBounds2、および安全なキャストを含む余分な数学ユーティリティ、ネイティブタイプのパーサー。
数学ライブラリはパフォーマンスを第一の目標として実装されているため、可能な限りインライン展開、ルックアップテーブル、高速演算子を使用します。 - 2Dおよび3D物理エンジン:
静的および動的オブジェクト、コールバック、ジョイントに対応する高性能ステートレス2D・3D物理エンジン。 - NavMesh/PathFinder/Agents: 既存のUnity navmeshからのエクスポータまたはメッシュを直接操作するエディタの両方を含みます。経路探索の他に、視線確認を行うことができます。
まだまだお伝えしたいことがありますので、このドキュメントのマニュアル部分をぜひご覧ください。
次に進むべき場所
Quantumの利用を開始するには、Quantum 100シリーズから始めることを強く推奨します。このチュートリアルでは、Quantumの利用を開始するうえで必要な基本的な事項を解説しており、テキストおよび動画形式で参照できます。