Super Text Adventure

Flags & State

The engine tracks game state across several structures. Global flags are the primary mechanism for tracking progress, gating content, and connecting game events.

Global Flags

Flags are named booleans stored in a global global_flags object. They're the glue that connects different parts of your game world.

// Flags are strings mapped to booleans
{
  "met_wizard": true,
  "quest_accepted": true,
  "dragon_slain": false,
  "secret_door_found": true
}

Where Flags Are Set

SourceFieldWhen
Exit sets_flag When the exit is unlocked or used
Item (on_use) on_use.sets_flag When the item is used
NPC (dialogue) dialogue.sets_flag When the player first greets the NPC
NPC (topic) topics.*.sets_flag When a dialogue topic is discussed
NPC (quest) sets_flag When the NPC accepts an item
Creature sets_flag_on_defeat When the creature is defeated
Dice Roll on_success.sets_flag / on_failure.sets_flag When a roll succeeds or fails

Where Flags Are Checked

ContextFieldEffect
Exit requires_flag Exit is blocked until the flag is true
Dialogue topic requires_flag Topic is locked until the flag is true
Container unlock_flag Container stays locked until the flag is true

Game State Structure

The full game state maintained by the engine:

{
  "world_snapshot": { /* full copy of world_data at game start */ },
  "player_states":   { /* per-player state, keyed by user ID */ },
  "room_states":     { /* per-room state tracking contents */ },
  "global_flags":    { /* named boolean flags */ },
  "container_states": { /* open/closed state and contents */ },
  "pending_restart": false
}

Player State

Each player has their own state tracked by user ID:

{
  "current_room": "tavern",
  "inventory": ["rusty_sword", "health_potion"],
  "health": 10,
  "max_health": 10,
  "visited_rooms": ["tavern", "town_square"],

  // Set when a dice roll is pending
  "pending_roll": {
    "dc": 12,
    "dice": "1d20",
    "on_success": { /* ... */ },
    "on_failure": { /* ... */ },
    "source_item": "lockpick"
  },

  // Set when in combat
  "combat": {
    "active": true,
    "creature_id": "goblin",
    "creature_health": 12,
    "creature_max_health": 15,
    "round_number": 3,
    "defending": false,
    "turn_order": "player"
  }
}
FieldDescription
current_roomID of the room the player is currently in.
inventoryArray of item IDs the player is carrying.
healthCurrent hit points. Initialized on first combat.
max_healthMaximum hit points. Default: 10.
visited_roomsTracks rooms visited for on_enter first-visit events.
pending_rollActive dice roll awaiting the player to type ROLL.
combatActive combat state. See Combat.

Room State

Each room tracks what's currently in it. This changes as players take items, creatures are defeated, etc.

{
  "items": ["rusty_sword", "torch"],
  "npcs": ["bartender"],
  "creatures": ["rat"],
  "modified": false
}

Exit & Container State

The engine also tracks persistent exit and container states:

Revealed exits

Hidden exits that have been discovered. Once revealed, they stay revealed.

Unlocked exits

Exits with permanently_unlock: true that have been unlocked. They stay unlocked.

Container states

Tracks which containers are open/closed and their current contents.

Restart

When a player types restart (or dies), the engine enters pending_restart mode and prompts for confirmation. On YES: