Creating a Replay System in Unity

A replay system is a great way to let players relive their best (or worst) moments of gameplay, improve their strategy, and more! In this tutorial, you’ll build a simple state-based replay system and learn about how replay systems work. By Teddy Engel.

Leave a rating/review
Download materials
Save for later
Share

A video camera captures a live event

A replay system is a great way to let players relive their best, or worst, moments of gameplay, improve their strategy and more!

You could choose to use one from the Asset Store, but I’ll assume you’re reading this wearing a red bandana and with an army knife between your teeth, ready for a challenge. :]
In this tutorial, you’ll learn:

  • What a replay system is.
  • The difference between state-based and input-based replay systems.
  • How to implement a state-based replay system from scratch.
Note: This is an advanced-level tutorial, which assumes you’ve been using Unity for a while. You should also have a solid understanding of C#. Although the sample project uses Unity 2019.3, everything in this tutorial should work in older versions.

Getting Started

Download the project files by clicking the Download Materials button at the top or bottom of this tutorial.

Screenshot of demo project showing the main character, Birdy

Go to RW/Scenes and open the Main scene. It’s already set up with a sprite, a character controller, buttons for the replay system and some catchy 8-bit music.

Credits: The upbeat music is from PlayOnLoop. The platform sprites are from the Asset Store package Free 8-Bit Pixel Pack by Super Icon Ltd. Birdy is part of the Asset Store package Sprite Pack #1 – Tap and Fly by G.E. Team.

Press the Play button and give it a go. Control Birdy by using the left and right arrows and space bar to jump.

Click the Start recording / Stop recording and Start replay / Stop replay buttons. The buttons update when you click them, but the system doesn’t actually record or replay anything yet. That’s where you’ll come in. :]

What is a Replay System?

A replay system is an in-game system that lets the player record a gameplay sequence and replay it, just like recording a video with a phone and playing it again.

For the purposes of this tutorial:

  • Record means to capture a sequence of frames rendered by the game.
  • Replay means to play back the captured sequence, in the same order, from the beginning.
  • The system will only capture one sequence at a time. Pressing Record again will overwrite the previous sequence.
  • The system will record the sequence in RAM. This tutorial doesn’t cover saving and loading a sequence from the disk.
  • Player input will still be active during the replay playback. This won’t be a big issue anyway as you’ll update the states every frame.

Choosing the Approach: State-based or Input-based

There are two popular types of replay systems: State-based and input-based. While they do the same thing, each approach has its pros and cons. SO, what’s the difference?

What is State-based Replay?

When you record with a state-based system, you capture a sequence of states. A state is a snapshot of the properties of an entity.

For example, in a Unity game, you might want to record and replay the position of the player character and their awesome boomerang weapon.

At frame 1, you’d record these positions:

  • Player character: (X:0, Y:1, Z:0)
  • Boomerang: (X:0, Y:2, Z:1)

When Unity processes the next frame of gameplay, both objects move. So, for frame two you’d store these values:

  • Player character: (X:0, Y:1, Z:1)
  • Boomerang: (X:1, Y:1, Z:1)

If the player is Object 1 and the boomerang is Object 2, the memory would look like this:

Diagram of memory slots storing position of player and boomerang GameObjects

In a state-based system, you replay the states by reading the frames in order and applying the saved values to your GameObjects.

So, if you were replaying the data above, at frame one you’d assign these positions:

  • Player character: (X:0, Y:1, Z:0)
  • Boomerang: (X:0, Y:2, Z:1)

At frame two, you’d assign these positions:

  • Player character: (X:0, Y:1, Z:1)
  • Boomerang: (X:1, Y:1, Z:1)

And so on for as many frames as you’ve saved.

Pros and Cons of State-Based Replay

The main advantages of a state-based system are:

  • Determinism: It’ll always give the same output, even if the underlying engine is non-deterministic.
  • Replay filtering: You’re able to select with great granularity what you want to record. For example, you could record and replay only the player position, while things like tree leaves and clouds still move independently.
  • Simplicity: It’s simple to implement.
  • No context needed: It’s easy to replay at anytime. You don’t have to set up a scene context first.

The main weakness is:

  • Memory footprint: If you start recording a lot of states, for example, a lot of frames, the replay’s memory usage of will skyrocket.

Time to look at the input-based approach to compare.

What is Input-based Replay?

When you record with an input-based system, you capture the initial state of your objects, then capture a sequence of inputs. Inputs might be touch gestures, joystick values or keypresses, depending on your game.

Instead of recording the state of individual GameObjects each frame, you record their state only once, in the very first frame of the game. Then you store the inputs that might alter their states.

For example, at the beginning of your game you’d store the positions of all the GameObjects you’re including in the replay. If your player moves to the right and then crouches in frame one, you’d record the information like this:

Diagram of memory slots storing input received in each frame

  1. At frame zero, which isn’t shown, you record the state of the entire scene.
  2. You record a directional input to the right and a directional input down at frame one.
  3. At frame two, you record a directional input down.
  4. You record a directional input down at frame three.

When you replay with an input-based system, first you set the entire state back to what it was at the beginning of the playback. Then, in each frame, you apply the inputs you recorded for that frame.

In this example, at frame zero, you’d reset the scene state, So, you’d read all of the states you recorded at frame zero and write the information back to your GameObjects. At frame one, you’d simulate a directional input to the right and down, at frame two a directional input down and so on for all the frames of input you’ve recorded.

Teddy Engel

Contributors

Teddy Engel

Author

Margaret Moser

Tech Editor

Aleksandra Kizevska

Illustrator

Ben MacKinnon

Final Pass Editor

Over 300 content creators. Join our team.