カスタムサーバープラグイン
はじめに
QuantumのサーバーロジックはPhoton Server's HivePlugin SDKの拡張版として実行されています。
予測セッション(プラグインで制御されたルームに接続したクライアントマシン内のQuantumシミュレーション)は、クライアントの1人がQuantum Join メッセージを送信した後に開始されます。(既に発生しているPhotonのルーム参加コマンドと混同しないためです)。
そして、他の接続済みのクライアントも参加手順に従い、同期済みの 時間 および 入力 交換をトリガーして開始しクライアントのシミュレーションを引き起こします。
重要:このドキュメントでは、Quantumゲームにサーバーオーソリテーティブチェックを実装するのに便利なエントリポイントである、Quantum特有のサーバーサイドコールバックについて説明しています。
インストール上の注意 と カスタムプラグインサンプル パッケージのトラブルシューティングについては、パッケージ内の /docs フォルダを確認してください。
基本の受信コールバック
Quantumプラグインのカスタムバージョンでは、セッションの大部分においてスタートアップ手順およびランタイムループがオーソリテーティブに受信されます。
予測Joinセッション
Quantumセッションに参加する全てのプレイヤーに向けて、プロトコル/SDKバージョン、使用可能なプレイヤースロットなど基本のチェックが整っています。このコールバックを使ってカスタムチェックを追加できます。joinData に含まれる ID はクライアントから送信されたGUIDです。
C#
public virtual Boolean OnDeterministicClientJoinSession(DeterministicPluginClient client, Join joinData) {
return true;
}
DeterministicSessionConfig と RuntimeConfig
デフォルトで、Quantumプラグインはサーバーに届く最初のクライアントメッセージとして送られる設定を値として使用します。これら2つの呼び出しを受信することで、全クライアントで設定値をオーソリテーティブに強制することが可能になります。
DeterministicSessionConfig については、'configData*内で受け渡された構造体の値を交換します。
C#
public virtual void OnDeterministicSessionConfig(DeterministicPluginClient client, SessionConfig configData) {
// overriding here you can modify the session config to be used (called once per session)
}
RuntimeConfig については、データはbyte[]として受け渡され、quantum.state DLLとして参照されることで(ゲーム特有の)RuntimeConfig としてデシリアライズ化されます。変更された値はシリアライズ化され、元の受け渡された設定を交換します。
public virtual void OnDeterministicRuntimeConfig(DeterministicPluginClient client, RuntimeConfig configData) {
// overriding here you can modify the runtime config (byte[]) to be used (called once per session)
}
これら2つは、ルームの開始時に(Photonプラグインの基本コールバックから)前もって以下のメソッドとともに設定されています。
C#
public void SetDeterministicSessionConfig(DeterministicSessionConfig config);
public void SetDeterministicRuntimeConfig(Byte[] configData);
RuntimePlayerデータ
同じようなコールバックとセッターが RuntimePlayer 向けに存在します。このコールバックはUnityクライアントから QuantumGame.SetPlayerData() へおこなわれた全ての呼び出しを受信しますので、オーソリテーティブコードを呼び出しを無視して、クライアントがデータを受信しないようにするために使うこともできます(サーバーサイド保護)。以下を参照してください。
C#
public virtual Boolean OnDeterministicPlayerDataSet(DeterministicPluginClient client, SetPlayerData playerData) {
// returning false would cause this data to be ignored and not passed to clients
return true;
}
セッターを使用すると開発者は新しい値を(あらゆるプレイヤーの) RuntimePlayer インスタンスに、セッション中のいつでも挿入できるようになります。
C#
public void SetDeterministicPlayerData(DeterministicPluginClient client, SetPlayerData playerData);
RuntimeConfig と同じように、RuntimePlayer もまたユーザー定義プロパティとシリアライゼーションコードを含んでおり、データはコールバックにbyte[]として受け渡されます。quantum.state DLL を使用して、使えるクラスとシリアライザーを参照するのと同じアプローチです。
高度なコールバック
基本のコールバックでは、開発者は設定とプレイヤーデータオブジェクトをクライアントに転送される前に受信および変更することが可能でした。高度なコールバックは、ライブ入力の制御やサーバー上でのシミュレーションの実行、遅い参加の最適化、再接続、再同期に使用できます。
シミュレーションの実行
シミュレーションをサーバーで実行するには、以下の3つのコールバックの実装が必要です。
- public virtual void OnDeterministicStartSession() は、FP math LUTや Quantum DB(他のルームによって初期化されていない場合)などの初期化に使用します。;
- public virtual void OnDeterministicInputConfirmed(DeterministicPluginClient client, Int32 tick, Int32 playerIndex, DeterministicTickInput input)
は、確認済み(サーバー調整済み)の入力データをサーバーが生きている状態でのシミュレーションに挿入するのに使用されます。; - public virtual void OnDeterministicUpdate() は、Quantum SDKセッションのサーバーコピーからゲームループのアップデートを呼び出します。;
カスタムプラグインサンプルには、上記の手順を全ておこなうのに必要な基本の実装が含まれています。サーバーベースのシミュレーションは、そのコードの大部分をQuantumのスタンドアロン.NETコンソールランナーと共有しているので、はじめに試しておくことをお勧めします。
スナップショットベースの再接続
Quantum SDK 1.2.1から始まって、QuantumクライアントSDKでは、シミュレーションの既存のゲームステートからの(再)接続をサポートしています。シミュレーションがサーバー上で実行されている場合、public virtual void OnDeterministicLateStart(DeterministicPluginClient client, SimulationStart startData) を実装するとスナップショットベースの再接続もしくは遅い参加に対するターンキーソリューションとなります。
以下にあげるのものがそのコードスニペットです。このコードスニペットでは、シミュレーションを session container (.NETコンソールランナーと共有のツール)から実行されているものとみなしています。完全なサンプルはカスタムプラグインサンプル内にあります。
C#
// [optional] snapshot-based reconnects/late joins
public override void OnDeterministicLateStart(DeterministicPluginClient client, SimulationStart startData)
{
if (container.session.FramePredicted == null) {
// Too early for snapshots.
return;
}
// Overwrite the input by only sending relevant input (omitting inputs in the far past)
client.ReconnectInputs = GetLateJoinInputs(container.session.FramePredicted.Number);
// cross platform (code generated) serialization of the full frame.
var data = container.session.FramePredicted.Serialize();
// encoding the frame data into several FrameSnapshot protocol messages (they have an internal max size)
var snapshotPacks = FrameSnapshot.Encode(container.session.FramePredicted.Number, data);
foreach (var pack in snapshotPacks)
{
// enqueuing the snapshot data here, ensues it will arrive on the client BEFORE it receives his session start command,
// so this frame will be used as the starting point for the sim
client.ProtocolSendQueue.Enqueue(pack);
}
}
入力を他のサーバーに転送する
OnDeterministicInputConfirmed(DeterministicPluginClient client, Int32 tick, Int32 playerIndex, DeterministicTickInput input)、もしくは通常の予測アップデートコールバックのどちらからでも、HTTPで入力を他のサーバーに送信することができます。
細かいHTTP送信の頻度が高まるのを防ぐため、入力する価値のあるティックのみバッチすることをお勧めします。(5~10秒ごとの送信で十分です)。HTTPデータの安全な送信については、公式のPhotonプラグインマニュアルを参照してください。
Back to top