This document is about: QUANTUM 3
SWITCH TO

フレーム

はじめに

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