フレーム
はじめに
Quantumの予測巻き戻しアーキテクチャは、レイテンシを軽減することを可能にします。Quantumは常にフレームを巻き戻し、再シミュレーションします。これは決定論を維持するために必要であり、プレイヤー入力の検証をサーバーが行うことを伴います。サーバーがプレイヤーの入力を確認するか、またはそれを上書き/置き換えた(入力が時間内にサーバーに到達しなかった場合のみ)後、特定のフレームのすべてのプレイヤーの検証済み入力がクライアントに送信されます。検証済みの入力が受信されると、最後に確認されたフレームは確定した入力を使用して進みます。
注意: プレイヤー自身の入力は、時間内にサーバーに到達しなかったり、検証できなかった場合、巻き戻されます。
フレームの種類
Quantumは、2種類のフレームを区別します:
- 確認済みフレーム(verified);
- 予測フレーム(predicted)。
確認済みフレーム
_確認済み_フレームは、_信頼できる_シミュレーションフレームです。確認済みフレームは決定論的であり、すべてのクライアントシミュレーションで同一であることが保証されています。確認済みシミュレーションは、サーバーからの確認済み入力を受信した後にのみ次の確認済みフレームをシミュレーションします。したがって、サーバーからのRTT/2に比例して進みます。
フレームが確認済みであるためには、以下の2つの条件が両方とも真である必要があります:
- このティックに対して__すべて__のプレイヤーからの入力がサーバーによって確認されている;
- それに続くすべての以前のティックも確認済みである。
サブセットのプレイヤーからの入力がサーバーによって検証された場合の部分ティック確認は、確認されたティック/フレームにはなりません。
予測フレーム
_確認済み_フレームとは対照的に、_予測_フレームはサーバーから確認された入力を必要としません。つまり、予測フレームは、シミュレーションがローカルセッションで十分なディルタルタイムを蓄積するとすぐに、予測に基づいて前進します。
Unity側のAPIは、さまざまなバージョンの予測フレームへのアクセスを提供します。以下にAPIの説明を示します。
Predicted
: 同期された時計に基づくシミュレーションの「ヘッド」。PredictedPrevious
(予測 - 1): メインクロックのエイリアス補間に使用されます(ほとんどのビューはこれを使用してスムーズに保ちます。Unityのローカル時計はメインサーバークロックからわずかにドリフトすることがあります。Quantumは、サーバークロックと同期した別の時計から実行され、スムーズに修正されます)。PreviousUpdatePredicted
: これは、Session.Update
が最後に呼び出されたときの「予測/ヘッド」であった正確なフレームです(その中には「修正」されたデータがあります)。エラー修正補間に使用されます(ほとんどの時間、エラーはありません)。
API
_確認済み_フレームと_予測_フレームの概念は、シミュレーションとビューの両方に存在しますが、APIは少し異なります。
シミュレーション
シミュレーション内では、Frame
クラスを介して現在シミュレーションされているフレームの状態にアクセスできます。
メソッド | 返り値 | 概要 |
---|---|---|
IsVerified | bool | すべてのクライアントで決定論的なフレームであり、サーバー確認済みの入力を使用している場合はtrueを返します。 |
IsPredicted | bool | ローカルで予測されたフレームの場合はtrueを返します。 |
ビュー
ビューでは、_確認済み_フレームと_予測_フレームは、QuantumRunner.Default.Game.Frames
を介して利用できます。
Method | Description |
---|---|
Verified | すべてのクライアントで同一の信頼できるシミュレーションフレーム。 |
Predicted | 同期されたQuantumクロックに基づくローカルシミュレーションの「ヘッド」。クライアントによって異なる場合があります。 |
PredictedPrevious | 予測 - 1 メインクロックのエイリアス補間に使用されます。ほとんどのビューはこれを使用してスムーズに保ちます。Unityのローカルクロックがメインサーバークロックからわずかにドリフトする可能性があるため、Quantumはサーバークロックと同期した別のクロックから実行され、スムーズに補正されます。 |
PreviousUpdatePredicted | 最後に`Session.Update`が呼び出されたときの「予測/ヘッド」フレームの再シミュレーションされたバージョンです。これは、巻き戻しが発生した場合に保持されているデータを「修正」するために必要です。ビューによる補間のエラー修正に使用されます - これは安全対策であり、ほとんど必要ありません。 |
Frame.Userの使用
Frame.User.cs
にデータを追加することで、フレームを拡張することが可能です。しかし、その際には、フレームで使用される対応する初期化、割り当て、およびシリアル化メソッドを実装する必要があります。
C#
partial void InitUser() // Initialize the Data
partial void SerializeUser(FrameSerializer serializer) // De/Serialize the Data
partial void CopyFromUser(Frame frame) // Copy to next Frame
partial void AllocUser() // Allocate space
partial void FreeUser() // Free allocated space
注意: フレームに過剰な量のデータを追加すると、パフォーマンス(デ/シリアル化)に影響を与えるだけでなく、遅延参加にも影響します。
例
これは、手動のメモリ割り当てを必要としない非常にシンプルな例です。
C#
namespace Quantum {
unsafe partial class Frame {
public byte[] Grid => _grid;
private byte[] _grid;
partial void InitUser() {
_grid = new byte[RuntimeConfig.GridSize];
}
partial void SerializeUser(FrameSerializer serializer)
{
serializer.Stream.SerializeArrayLength<Byte>(ref _grid);
for (int i = 0; i < Grid.Length; i++)
{
serializer.Stream.Serialize(ref Grid[i]);
}
}
partial void CopyFromUser(Frame frame)
{
Array.Copy(frame._grid, _grid, frame._grid.Length);
}
}
}
Back to top