Skip to main content

Spectating/Replays

Easel allows players to spectate live games or watch replays of past games.

Multiplayer only

A game must be in multiplayer mode to support spectating and replays, because it requires the server to record the inputs. To make your game multiplayer, set the maxHumanPlayers parameter for your game fn. Note, even if you set maxHumanPlayers=1, your game is still considered multiplayer, just with only one human player allowed to join. This is how you can make it possible to replay or spectate singleplayer games.

See Multiplayer for more details on enabling multiplayer in your game.

Live Spectating

Create a spectate button by attaching a SpectateIntent to a Button. When people click this button, they will be taken to a page that will continuously show them a feed of live games.

pub page fn owner.HomePage() {
Button(SpectateIntent) { "Spectate" }
}

Disable Spectating

Add an allowSpectators parameter to your game fn to enable or disable spectating of a particular game.

// Disable spectators by default
pub game fn World.Main(maxHumanPlayers=4, allowSpectators=false) {
// ...
}

Since allowSpectators is a function parameter, it can be set dynamically when calling game fn function. This could be used, for example, to disable spectating of tutorial games. Remember that calling a game fn does not actually execute its function body, it instead creates an intent to enter the game, which can then be attached to a Button, allow players to enter the game by clicking the button.

pub game fn World.Main(tutorial=false, maxHumanPlayers=4, allowSpectators=!tutorial) {
// ...
}
pub page fn HomePage() {
Content {
Button(Main) { "Play" }
Button(Main(tutorial=true)) { "Tutorial" }
}
}

See Game Functions for more details on game fn functions.

Replays

Easel automatically records all multiplayer games for replaying later. This is useful for reliving highlights and sharing them with others. It is also useful for debugging.

Replays capture the input sequence for the game and so are stored very efficiently, but because of this, they are generally only compatible with the latest version of the engine. When a user watches a replay, they can click the Record button to capture the game as a video, which is better for long-term storage.

To watch a replay, first you need the ID of the game you would like to replay. This can be found from the CurrentReplayId function. Of course, it is not normally very interesting to re-watch the current game that you are in, and so what you would normally want to do is persist this ID to the user's profile somewhere, and retrieve it later when they want to look back at their triumphs (or failures!).

The PublishUserEpisode and FetchUserEpisodeHistory functions allow you to persist some data about previous games to the user's profile. Store the ID of a replay in there.

You can then create a "Watch Replay" button by attaching a ReplayIntent to a Button, passing it the ID of your game.

Marking the playing phase

It is common for games to include a lobby phase before the game starts. This is not interesting to watch in a replay or for live spectators, so it is important to mark when the game has started and when it has finished. Call the CommenceGame function to mark when the game has started, and call ConcludeGame to mark when the game has finished.

Live spectators will only be shown games that have not yet concluded. Replays will automatically fast-forward to when the game commences. Recordings will begin from when the game commences and end when the game concludes.

Spectator audience

Many functions take an audience parameter to define which players should be affected. You can use the audience parameter to limit which players see a graphic, hear some audio, or which players can see a particular camera. The audience parameter can take on the special value Audience:Spectators to specifically target spectators. See Audience to learn more about audiences.