Skip to content

Session lifecycle & limits

A session moves through a small set of states. Knowing them helps you host confidently — especially around pausing and reloading.

A game’s status is one of three values:

  • stopped — created but not running (pre-start), or paused. Rules don’t tick. The map can be edited.
  • started — running. Rules tick (~once a second), bots move, the clock runs.
  • ended — terminal. A win condition, countdown, or elimination finished the game. Rules don’t tick.

The typical path is stopped → started → ended. You can also stop a running game back to stopped (a pause), and start it again.

When you hit Start, the engine runs its pre-flight checklist, then:

  • runs one-shot start initializers (role assignments, dealt targets, opening countdowns),
  • spawns items declared by the game,
  • positions bots, and
  • begins the tick loop.

Pausing (stop) freezes the simulation: rules stop evaluating and the countdown clock freezes where it is. This is the safe moment to fix a mis-placed zone or wait for latecomers. Resuming rolls the deadline forward by however long you were paused, so players don’t lose game time and the visible “time remaining” doesn’t jump.

Ending finishes the session and disconnects players. Games also end on their own when:

  • a countdown (fixed duration) expires,
  • a team is eliminated, or
  • a rule fires an end-game action (a win condition).

When a game ends, everyone gets a game-over event.

Reloading the GM console mid-game is safe. The console remembers the active session and reconnects on load, replaying the current world so you’re right back where you were. You won’t lose a game by refreshing the browser.

Players reconnect the same way — rejoining with the code resyncs them to the live state.

The live game state always runs in the engine’s memory — that’s the source of truth while a game is in play, and it survives reloads and brief disconnects because the server keeps holding it.

When the engine is configured with a database (Supabase), it also persists sessions durably behind the scenes:

  • Each session — its game, settings, and latest world snapshot — is saved under your account and survives an engine restart. After a restart it’s rehydrated from storage the next time it’s opened; a game that was mid-play comes back paused, ready for you to resume.
  • A replay history is recorded as the game runs (one frame per tick while it’s live), so finished games can be played back later. See the saved-sessions library and replay viewer.
  • This persistence is best-effort and only active when the database is configured. On a plain local engine with no database, sessions stay purely in memory exactly as before — they don’t survive a restart and there’s no replay history.
  • Idle sessions are still freed. After a long stretch with no activity (on the order of an hour), a live session is dropped from memory to free resources. With persistence enabled this just evicts it — the session stays in your library and rehydrates the next time you open it. Without a database, an idle session is gone for good; a code that “stopped working” is usually one that was reaped, so just create a new one.

Each session gets a unique four-letter, pronounceable join code (SHON, ZOOT, NONA). They’re designed to be easy to say aloud and type, and they’re case-insensitive. There are enough of them to comfortably cover many simultaneous sessions. More on how codes are generated.