This document is about: QUANTUM 2
SWITCH TO

Replays

Introduction

This documentation explores ways of saving and playing back deterministic Quantum simulation replays. Every part of the system comes in source code form. The implementation can be inspected, use it as-is or tweak it to serve project requirements in a better way.
Replays are an unaltered compiled application that re-runs the game simulation with the exact same user input and game assets, from a recorded session. Also, it can be used to run a second runner besides the default runner to perform, for instance, a killcam replay. The compiled application does not need to be the same one or even run on the same platform, e.g. Android, Unity Editor, Windows exe or a custom game server, but it has to be built with the same quantum dlls.

Running a Quantum replay requires four parts:

  1. An application build with the same version of Quantum libraries
  • PhotonDeterministic.dll and quantum.core.dll
  • The custom quantum.code.dll
  1. The game assets
  • The Quantum asset database (DB)
  • The LUT files (FP look-up tables for math, usually never changes)
  1. The game session specific configuration files
  • SimulationConfig
  • RuntimeConfig
  1. The game session specific input history

Replay Files

Replay Files Image

Asset DB

To play-back a replay Quantum requires the exact same versions of all game assets that the replay was recorded with. It has to be started with a versioned Quantum asset db. The db can be exported from Unity into a Json file (db.json).

C#

var serializer = new QuantumUnityJsonSerializer();
var data = serializer.SerializeAssets(UnityDB.DefaultResourceManager.LoadAllAssets(true));
File.WriteAllBytes(“db.json”, data);

Configuration Files And Input History

For convenience the default replay format used by the API and scripts consists of one class which is serialized and saved as a file using Json (replay.json). This format contains (3) and (4) of the required parts and additionally can store an optional frame to start from (Frame, InitialFrame, InitialFrameData).

If size and performance are a consideration, any binary serialization can be added. The required classes (e.g. DeterministicTickInputSet) are fairly simple. We also provide snippets for this.

Related class: quantum.code/Replay/ReplayFile.cs

ReplayFile Class Image

C#

var serializer = new QuantumUnityJsonSerializer();
var replay = QuantumRunner.Default.Game.GetRecordedReplay();
var data = serializer.serializer.SerializeReplay(replay);
File.WriteAllBytes(“db.json”, data);

Checksums

If frame checksums are enabled in the SessionConfig they can be captured and saved into a file. When playing back a replay, the newly generated checksums are then verified against the recorded ones to validate that the simulation is correct. Because checksums are expensive to calculate this is only regarded as a development feature.

Related class: quantum.code/Replay/ChecksumFile.cs

C#

var serializer = new QuantumUnityJsonSerializer();
var data = serializer.SerializeChecksum(QuantumRunner.Default.Game.RecordedChecksums);
File.WriteAllBytes(“db.json”, data);

Saving A Replay In Unity

Set RecordingFlags

When starting a Quantum game, set the desired RecordingFlags in the start parameters QuantumRunner.StartParameters.RecordingFlags.

The QuantumRunnerLocalDebug script has a toggleable member for this. When starting from custom menu classes it has to be set explicitly in code.

C#

[Flags]
public enum RecordingFlags {
  None = 0,
  Input = 1 << 0,
  Checksums = 1 << 1,
  Default = Input | Checksums,
  All = 0xFF
}

Exporting A Replay

Use the Unity Editor menu Quantum > Export > Replay (JSON) and select a destination folder for the files.

Search for the method ReplayMenu.ExportDialogReplayAndDB() to look at the code required to export the db and replay file.

Exporting Replay Image

Replay API

Apart from the StartParameters and serializer the QuantumGame class holds the rest of the relevant replay methods.

C#

public class QuantumGame : IDeterministicGame {
  public InputProvider RecordedInputs { get; }
  public ChecksumFile RecordedChecksums { get; }
  public ReplayFile GetRecordedReplay();
  public void StartRecordingInput(Int32? startFrame = null);
  public void StartRecordingChecksums();
  public void StartRecordingInstantReplaySnapshots();
  public void StartVerifyingChecksums(ChecksumFile checksums);
}

Another key part is the InputProvider class. It is designed to work as an adapter between the Quantum input system and something read- and save-able.

It is used to record the input (QuantumGame.RecordedInputs and InjectInput()), save and load (ImportFromList() and ExportToList()) and to play back input for the simulation (StartParameters.ReplayProvider).

Playback A Replay In Unity

Similar to the script to start a local game (QuantumRunnerLocalDebug) the QuantumRunnerLocalReplay script starts and plays the game from a replay file.

Drag and drop the replay.json file onto the replay runner script in a field named Replay File. The other files for db and optional checksums are then assigned automatically. If not, drag the two files into their respective fields. The DatabasePath field is not used anymore.

Quantum Runner Local Replay

Find the QuantumRunnerLocalReplay.cs script to research all required actions to start a game with a replay file.

Deserialize The Replay Files

C#

var serializer = new QuantumUnityJsonSerializer();
var replayFile = serializer.DeserializeReplay(ReplayFile.bytes);
var assets = serializer.DeserializeAssets(DatabaseFile.bytes);
var checksums = serializer.DeserializeChecksum(ChecksumFile.bytes);

Configure The Start Parameters

  • Set SessionConfig and RuntimeConfig from the replay file.
  • Set the ReplayProvider by creating a new instance of the InputProvider with the loaded and deserialized input history.
  • Set GameMode to Replay.
  • Set PlayerCount and LocalPlayerCount from set SessionConfig. In this mode all players are considered local.
  • Optionally set InitialFrame and FrameData.
  • Set ResourceManageOverride to a new instance using the deserialized asset db.

C#

var param = new QuantumRunner.StartParameters {
  RuntimeConfig = replayFile.RuntimeConfig,
  DeterministicConfig = replayFile.DeterministicConfig,
  ReplayProvider = new InputProvider(replayFile.InputHistory),
  GameMode = Photon.Deterministic.DeterministicGameMode.Replay,
  RunnerId = "Replay",
  PlayerCount = replayFile.DeterministicConfig.PlayerCount,
  LocalPlayerCount = replayFile.DeterministicConfig.PlayerCount,
  InstantReplayConfig = InstantReplayConfig,
  InitialFrame = replayFile.InitialFrame,
  FrameData = replayFile.InitialFrameData,
  ResourceManagerOverride = new ResourceManagerStatic(assets, new QuantumUnityNativeAllocator())
};

Start the Quantum game.

C#

var runner = QuantumRunner.StartGame("Replay", param);

Optionally start verifying the checksums while playing back the replay.

C#

runner.Game.StartVerifyingChecksums(checksums);

Console Runner

The console runner is distributed with the SDK and is a simple Dotnet console application that can run a Quantum simulation from a replay outside of Unity.

The quantum.console.runner project can be added to the quantum_code solution. By default it references the Quantum dlls in the assemblies folder and the code solution.

Quantum Console Runner

Either select the project as the start-up project and run debugging with F5 where the following StartArguments are set for debugging the project. It expects the replay files to be located under quantum_unity/Assets/Resources/replay.

    <StartArguments>../../../../quantum_unity/Assets/Photon/Quantum/Resources/LUT ../../../../quantum_unity/Assets/Resources/replay/db.json ../../../../quantum_unity/Assets/Resources/replay/replay.json ../../../../quantum_unity/Assets/Resources/replay/checksum.json</StartArguments>

Or compile the console app and run with the following parameters.

C#

console.runner.exe [folder path to LUT files] [file path to database] [file path to replay] ([file path to checksums])

Caveat: The replay runner requires the exact set of libraries, db, configs and input that was discussed in the introduction to work properly.

Caveat: When still encountering verification errors it may be because of platform compatibility. The recorded checksums in Unity are not compatible with the ones generated in the Dotnet runner. Activate ChecksumCrossPlatformDeterminism in the SessionConfig and record the replay again to fix the errors.

Instant Replays

We provide a script which demonstrates how to do instant replays, like killcam replays which happen during the game, in an auxiliary QuantumRunner, and then gets back to the default runner once the instant replay is over.
To use it, you just need to add the component called QuantumInstantReplayDemo, do the setup (set playback speed, replay length, etc) and then, during gameplay, you can just hit the Start and Stop buttons.

Instant Replay Image
Back to top