Luna Replay supports the use of
System.Random in your game.
In order to ensure that there is consistent behaviour between your captures and associated replays, Luna stores the initial Random seed value at the time of capture, and uses this for the replay.
In the above diagram, you can see that by storing this seed value, the Replay can return the same random value when it is required.
However, imagine the following when the random numbers are requested out of order.
In this example,
value3 are being assigned random values in the capture by using
UnityEngine.Random and the initial seed value.
In the replay, the order in which the values are assigned has changed. Therefore, the values they are assigned will differ, even though the initial seed value is identical.
So why can this happen? Let's take a look and outline what you can do in each scenario.
When using asynchronous loading in your game, frames can occur out of order, and this may be the cause of your random numbers being assigned in a different order between the capture and replay.
Single Async Events
If your game uses a single async event, for example a preloader or loading of a scene, then you may wish to ensure that the random order is maintained.
To do this, you can use a Barrier which will save and restore the random seed at this point.
Multiple Async Events
If there are many separate events, such as loading multiple assets, and these events use random values, then it is possible that the order of these events can change between capture and replays.
You may use a Checkpoint after each event, before randoms are used, in order to save and restore the random seed at this point.
- If the random values are not gameplay critical, for example in a particle system, or an object's colour, then you may replace
System.Randominstead of adding a checkpoint.
- If randoms are used for calculations its possible to save and restore those calculations, instead of the random value itself. You can do this using the DataPrefs API.
Replay can patch some of the asynchronous operations and make them synchronous. To do so please consider using
Load Synchronously section on the Capture tab.
If these checkboxes are on then async operations will always complete on the next frame.
Adding/removing random values from the sequence
You may use logic in your game which varies the use of randoms via Creative Suite fields.
For example, you could have a boolean Creative Suite field that enables "Random colour mode" in your game. Doing this (whilst causing great visual results) will cause differences between your capture and replays.
You can use a Checkpoint in such scenarios. An example is included here.
Luna Replay prints a warning message to console (on both Unity and Linux builds) which notifies you when the order of randoms has changed between capture and replays.
The Random.state differs from the state during the capture. If it causes issues please make sure you have set barriers after asynchronous operations. See documentation for more details (https://docs.lunalabs.io/docs/replay/replay-api/barriers).
In order to help debug this, Luna provides a debug option in the Capture and Replay UI in Unity. See more details here.