## Rooms Minimal room: ```yaml id: 1 name: "Town Square" description: "Cobblestone paths lead in all directions. A fountain gurgles peacefully." exits: north: 2 west: 7 east: 3 ``` ### Inline Color Tags Room descriptions support inline color tags using `{spec}text{/}` syntax. Untagged text uses the `room_desc` color. ```yaml description: "On the table lies a {182 bold}mysterious vase{/} with a rose in it." ``` Tag spec format: `{<0-255> [bold] [dim] [underline]}text{/}` Gradients: `{g:196,82}gradient text{/}`. Multi-stop: `{g:45,39,59}three stops{/}`. ### Exits — simple vs conditional Simple exit — always passable: ```yaml exits: north: 2 ``` Conditional exit — blocked until a world flag is set: ```yaml exits: north: room: 11 condition: flag: gate_open blocked_message: "A heavy iron gate blocks the way north." ``` Conditional exit — blocked unless the PLAYER has a flag (key, permission, quest state): ```yaml exits: east: room: 12 condition: player_flag: has_vault_key blocked_message: "The vault door is locked. You need a key." ``` Conditional exit with compound condition — requires both a world flag AND a player flag: ```yaml exits: north: room: 20 condition: all_of: - flag: bridge_repaired - player_flag: paid_toll blocked_message: "The bridge is out, and the toll collector blocks the path." ``` Exit that sets flags when used — `set_flags` / `set_player_flags` are applied only when the player actually moves through the exit (not when it's blocked): ```yaml exits: north: room: 21 condition: player_flag: lined_up set_player_flags: boarded_shuttle: true # marks "left this area" on the way out ``` ### Item Spawns — ground items that respawn ```yaml item_spawns: - id: bronze_pickaxe quantity: 1 respawn_ticks: 30 # reappears 30 ticks (18 seconds) after being picked up - id: copper_ore quantity: 3 respawn_ticks: 50 ``` ### Mobs — NPCs placed in the room Simple string (no wandering): ```yaml mobs: - "newbie_trainer" - "man" ``` With wander config per-instance: ```yaml mobs: - id: man wander_interval: 10 # attempts to wander every 10 ticks - id: man wander_interval: 15 wander_rooms: [1, 4, 5] # optional — only exit to these rooms ``` Mob wander config lives in the room YAML, not in the mob definition. This keeps mobs generic so the same `man` can wander differently depending on where it's placed. Mobs wander through legal (unconditioned) room exits. If no legal exits exist, the mob stays still. Mobs with no `wander_interval` never wander. ### Objects — interactive fixtures ```yaml objects: - id: copper_rock # simple placement - id: copper_rock # second instance - id: fishing_spot wander_rooms: [7, 8, 9] # teleports between these rooms wander_interval: 12 # every 12 ticks - id: iron_gate # hidden object (see below) ``` ### On-enter scripts — messages and timed cutscenes when a player arrives Each `on_enter` step shows a `message`, optionally gated by a `condition`. Steps whose condition fails are skipped. ```yaml on_enter: - message: "The guard barks: \"State your business!\"" condition: player_flag: talked_to_guard not: true # only the first visit - message: "The guard nods. \"Back again?\"" condition: player_flag: talked_to_guard # subsequent visits ``` **Timed cutscenes.** A step may also carry a `delay` (ticks to wait before it fires) and/or set flags (`set_flags` / `set_player_flags`). If any surviving step has a delay or sets a flag, the whole sequence runs as a scheduled cutscene; plain message-only scripts still print instantly. ```yaml on_enter: - condition: { player_flag: boarded, not: true } delay: 5 message: "Some of the crowd look you up and down." - condition: { player_flag: boarded, not: true } delay: 5 message: "The pilot calls out: \"Tickets, please! Nice and orderly!\"" set_player_flags: lined_up: true # opens an exit, flips a description, etc. - condition: { player_flag: boarded, not: true } message: "The crowd forms a single-file line." ``` Notes: - `delay` counts ticks before the step fires; `delay: 0` (or omitted) fires on the next tick. - Conditions are evaluated **once** on entry, so a flag a step sets won't cancel a later step in the same sequence. - Gate a cutscene on a flag the sequence itself sets (above, `lined_up`) so it doesn't replay on a return visit. - If a player disconnects mid-cutscene it resumes on reconnect, so they can't get stuck behind an exit the cutscene was meant to open. Plain `on_enter` messages never replay on login. ### Conditional room descriptions A room can show a different description depending on the looking player's flags. `descriptions` are checked top-to-bottom; the first whose condition passes wins, otherwise the base `description` is used. ```yaml description: "A large, empty concrete pad in the middle of the ocean." descriptions: - condition: player_flag: boarded not: true text: "A concrete pad swarming with a couple dozen anxious passengers." ``` ### Hazardous rooms — environmental danger A room can reference a shared hazard by ID. The hazard rolls an attack against everyone in the room every few ticks using the combat formulas (see `hazards.md`). ```yaml id: 99999181 name: "Exposed Solar Array" hazard: solar_radiation # ID of a data/hazards/.yaml definition exits: south: 99999180 objects: - id: rock_outcrop # a safespot object shields players from the hazard mobs: - solar_panel_frame # a task worksite (see mobs.md > Task Mobs) ``` - Players are warned with a `[Y/n]` prompt before walking from a **safe** room into a **hazardous** one (unless they disable the `danger_warning` option). Moving between two hazardous rooms does not re-prompt. - A safespot object (an overhang, alcove, rock outcrop, …) shields a hidden player from **all** hazard damage — but performing a melee attack/work step forces you out of cover. - Hazards stack with mobs: an aggressive mob in a hazardous room hits you while the room hazard also rolls against you. ---