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
| Source | Field | When |
|---|---|---|
| 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
| Context | Field | Effect |
|---|---|---|
| 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"
}
}
| Field | Description |
|---|---|
current_room | ID of the room the player is currently in. |
inventory | Array of item IDs the player is carrying. |
health | Current hit points. Initialized on first combat. |
max_health | Maximum hit points. Default: 10. |
visited_rooms | Tracks rooms visited for on_enter first-visit events. |
pending_roll | Active dice roll awaiting the player to type ROLL. |
combat | Active 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:
Hidden exits that have been discovered. Once revealed, they stay revealed.
Exits with permanently_unlock: true that have been unlocked. They stay unlocked.
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:
- All player state is reset
- All room state is reset
- All flags are cleared
- All container states are reset
- The world is re-snapshotted from the original data
- The player starts back in
meta.starting_room