VerseBuilderDocs

Docs/Core concepts/State & persistence

State & persistence

Everything your rules remember — coins, inventories, current phase — is state. Some survives disconnects, some resets every round. Choosing right matters.

Last updated 2026-06-06

Three kinds of state

  • Live state — Variables you read/write. Coins, level, current_zone.
  • Container state — Inventories holding items. Backpack, hotbar.
  • Phase state — Which named stage the game is in. Lobby, game, ending. Always exactly one current phase per device.

Configs and Messages are not state — Configs are tweakable constants set in UEFN editor, Messages are fixed text. They never change at runtime.

Persistence

Per-player variables with Persist on survive disconnects and rejoins. When the player comes back next session, their value is restored. Without persistence, the value resets to Default every time they join.

💡 Tip

Persistence is implemented via Fortnite's player-data system. The Composer emits a persistable class and accessor helpers — you don't see any of that, you just tick the box.
  • Persist ON — progression. Coins, level, XP, prestige.
  • Persist OFF — temporary state. kill_count (resets each round), current_zone, boss_spawned.

Scope: per-player vs. global

Every variable belongs to one of two scopes:

  • player — each player has their own copy. Use for stats, inventory, quest progress.
  • global — one shared value across the whole island. Use for round number, wave count, boss spawned flag.

Patterns

Player progression

Currency + level + XP, all per-player, all persistent. Use increment_variable on earn events and compare_variable in IF for level-up gates.

Round counters

Per-player without persistence — kill_count, damage_taken. Reset to 0 on the round-start event via set_variable.

Global flag

boss_spawned (bool, global, persist OFF) — one rule sets it to true on spawn, other rules read it to gate behavior. Resets every round.

Gotchas

⚠️ Watch out

Persistent schema is forever. Once your island is published with a persistent variable, removing or renaming it can leak save data or break old clients. Treat persistent state like a database migration.

⚠️ Watch out

Global scope ≠ per-player. A global coins would be shared by everyone — they'd all spend the same wallet. This is the most common scope mistake.

📌 Note

State you don't declare doesn't exist. The composer never invents variables for you — if a rule needs to remember something, add it in Game Data first.

What gets generated?

Per-player persistent state compiles to a persistable player-data class with typed fields, plus get/set helpers on the device. Round-only state stays in a regular weak_map. Global state becomes a plain device field with a default value.

# Persistent per-player
te_player_stats := class<final><persistable>:
    Version:int = 0
    Coins:int = 0
    Level:int = 1

# Round-only per-player
PlayerKills:weak_map(agent, int) = map{}

# Global
var BossSpawned:logic = false

See also