aboutsummaryrefslogtreecommitdiff
path: root/WORLDBUILDING.md
diff options
context:
space:
mode:
authorhistoria <[not public]>2026-06-16 23:37:50 -0400
committerhistoria <[not public]>2026-06-16 23:37:50 -0400
commit389e307f205f9b7edf604fb9f86e1038ead736ef (patch)
tree595095b5877cc2b0513d31fb126303d8796cc311 /WORLDBUILDING.md
parent085e728d22a3369bd110b77409914cfbe9ebe611 (diff)
downloadthehouseoficarus-389e307f205f9b7edf604fb9f86e1038ead736ef.tar.gz
feat: major xterm256 color overhaul, see worldbuilding docs.
Diffstat (limited to 'WORLDBUILDING.md')
-rw-r--r--WORLDBUILDING.md975
1 files changed, 0 insertions, 975 deletions
diff --git a/WORLDBUILDING.md b/WORLDBUILDING.md
deleted file mode 100644
index 93c40aa..0000000
--- a/WORLDBUILDING.md
+++ /dev/null
@@ -1,975 +0,0 @@
-# World Building Guide
-
-Third Collapse is data-driven. Everything — rooms, items, mobs, objects, behaviors — is defined in YAML files under `data/`. No code changes needed to build a world.
-
-## Quick Reference
-
-| What you want | Where to put it |
-|---|---|
-| A room | `data/rooms/<id>.yaml` |
-| An item (sword, ore, key) | `data/items/<id>.yaml` |
-| A mob (NPC, monster) | `data/mobs/<id>.yaml` |
-| An interactive object (rock, lever, door) | `data/objects/<id>.yaml` |
-| A behavior (mining, dialog, toggle) | `data/behaviors/<id>.yaml` |
-| A shared drop table | `data/drops/<id>.yaml` |
-
-## State: World vs Player
-
-**World flags** (`set_flags`, checked with `flag`) are shared by every player on the server. A door opened by one player is open for everyone. A lever pulled once changes the world for all.
-
-**Player flags** (`set_player_flags`, checked with `player_flag`) are per-character. Quest progress, "has read the sign," "paid the toll" — these are different for each player. Saved to the character YAML and persist across logins.
-
----
-
-## 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
-```
-
-### 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
- value: true
- 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
- value: true
- 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
- value: true
- - player_flag: paid_toll
- value: true
- blocked_message: "The bridge is out, and the toll collector blocks the path."
-```
-
-### Spawns — ground items that respawn
-
-```yaml
-spawns:
- - item_id: bronze_pickaxe
- quantity: 1
- respawn_ticks: 30 # reappears 30 ticks (18 seconds) after being picked up
- - item_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 when a player arrives
-
-```yaml
-on_enter:
- - message: "The guard barks: \"State your business!\""
- condition:
- player_flag: talked_to_guard
- not: true # only first visit
-
- - message: "The guard nods. \"Back again?\""
- condition:
- player_flag: talked_to_guard
- value: true # subsequent visits
-```
-
----
-
-## Items
-
-```yaml
-id: bronze_pickaxe
-name: bronze pickaxe
-aliases: ["pick", "pickaxe"]
-description: "A sturdy bronze pickaxe."
-value: 10
-stackable: false
-equip_slot: main_hand # optional — where it equips
-weapon_type: melee # optional — melee or ranged
-stats: # optional — combat bonuses
- attack_bonus: 2
- strength_bonus: 1
-speed: 5 # ticks between attacks
-tool_type: pickaxe # used by gather behaviors that require "tool: pickaxe"
-tool_speed: 2 # reduces gather wait time
-```
-
-Key item (quest token, not equippable):
-```yaml
-id: pass_stub
-name: pass stub
-description: "A crumpled slip of paper stamped with the guard's seal."
-value: 0
-stackable: false
-```
-
----
-
-## Mobs
-
-Basic combat mob:
-```yaml
-id: "man"
-name: "man"
-description: "A shabby-looking man."
-attack: 1
-strength: 1
-defense: 1
-hp: 7
-speed: 5
-aggressive: false
-respawn_ticks: 30
-drops:
- remains: "bones" # always dropped on death
- loot:
- - item_id: "credits"
- weight: 98
- quantity: 10
- - item_id: "credits"
- weight: 2
- quantity: 150
-idle_descriptions:
- - "scribbles something in a small notebook"
- - "gazes skyward at the clouds"
-combat_descriptions:
- - "is engaged in a fight to the death with %s"
-```
-
-Mob with a behavior — can be talked to, toggled, etc:
-```yaml
-id: "guard"
-name: "Guard"
-behavior: guard_talk # links to data/behaviors/guard_talk.yaml
-unique: true # displays as "Guard" not "a guard"
-protected: true # cannot be attacked
-attack: 5
-strength: 5
-defense: 5
-hp: 30
-speed: 5
-aggressive: false
-respawn_ticks: 60
-idle_descriptions:
- - "scans the area with a watchful eye"
- - "adjusts the grip on his weapon"
-```
-
-Note: `wander_rooms` and `wander_interval` are NOT set on the mob definition. Wander config
-is per-instance in the room YAML (see Rooms > Mobs section above).
-
----
-
-## Objects
-
-Object defined — links to a behavior:
-```yaml
-id: copper_rock
-name: copper rock
-behavior: mine_copper
-```
-
-Tree object:
-```yaml
-id: oak_tree
-name: oak tree
-behavior: chop_oak
-```
-
-Hidden object — doesn't appear in room's object list, only discoverable via description or experimentation:
-```yaml
-id: iron_gate
-name: iron gate
-behavior: iron_gate_toggle
-hidden: true
-props:
- description: "A heavy iron gate set into the north wall."
-```
-
-Decorative object (no behavior):
-```yaml
-id: lumby_fountain
-name: town fountain
-behavior: ""
-props:
- description: "Clear water sparkles in the sunlight."
-```
-
----
-
-## Behaviors
-
-### Gather (mining, fishing, woodcutting)
-
-Mining — per-drop depletion:
-```yaml
-id: mine_copper
-type: gather
-skill: mining
-level: 1
-xp: 17 # XP awarded per successful gather
-base_wait: 8 # ticks between attempts
-tool: pickaxe # requires item with tool_type: pickaxe
-success:
- base: 0.40 # 40% base chance
- per_level: 0.01 # +1% per level above requirement
- cap: 0.95 # 95% max
-gather_message: "You swing your pickaxe at the rock..."
-fail_message: "You chip away but get nothing useful."
-drops:
- - item_id: copper_ore
- weight: 90 # 90% chance when roll succeeds
- depletes: true # rock becomes depleted after this drop
- message: "You manage to mine some copper ore."
- - table: gem_table # reference a shared drop table
- weight: 10
- depletes: false # gem drops don't deplete the rock
- message: "You spot a glint of something valuable!"
-respawn_timer: 50 # ticks until rock respawns
-respawn_message: "You see more ore in the rock."
-respawn_broadcast: "A glint of copper catches your eye from some {name}."
-```
-
-Non-depleting gather (fishing):
-```yaml
-id: fish_trout
-type: gather
-skill: fishing
-level: 1
-xp: 10
-base_wait: 4
-tool: fishing_rod
-success:
- base: 0.30
- per_level: 0.01
- cap: 0.90
-gather_message: "You cast your line into the water..."
-fail_message: "Nothing seems to bite."
-drops:
- - item_id: raw_trout
- weight: 100
- depletes: false # never depletes
- message: "You catch a trout!"
-```
-
-Woodcutting with shared depletion and bird's nests:
-```yaml
-id: chop_oak
-type: gather
-skill: woodcutting
-level: 15
-xp: 37
-base_wait: 6
-tool: axe
-success:
- base: 0.40
- per_level: 0.01
- cap: 0.90
-gather_message: "You swing your axe at the oak tree..."
-fail_message: "You swing but get no logs."
-drops:
- - item_id: oak_logs
- weight: 100
- depletes: false # depletion is timer-based (deplete_timer)
- message: "You get some oak logs."
-respawn_timer: 14 # ticks until tree respawns after being cut down
-deplete_timer: 45 # max ticks before next gather depletes (counts down while chopping)
-nest_chance: 256 # 1/256 chance for a bird's nest on each successful gather
-respawn_message: "A new oak sapling grows in its place."
-respawn_broadcast: "An {name} grows back."
-```
-
-Regular tree — always depletes on first gather, no shared timer, no nests:
-```yaml
-id: chop_tree
-type: gather
-skill: woodcutting
-level: 1
-xp: 25
-base_wait: 4
-tool: axe
-success:
- base: 0.50
- per_level: 0.01
- cap: 0.95
-gather_message: "You swing your axe at the tree..."
-fail_message: "You swing but get no logs."
-drops:
- - item_id: logs
- weight: 100
- depletes: true # regular tree depletes on first successful gather
- message: "You get some logs."
-respawn_timer: 80
-respawn_message: "A new tree grows in its place."
-respawn_broadcast: "A {name} grows back."
-```
-
-#### Shared depletion explained
-
-When `deplete_timer > 0`, the tree has a shared despawn timer:
-- The timer starts at `deplete_timer` max when the first player begins chopping.
-- Each tick, if anyone is chopping, the timer counts down.
-- When the timer reaches 0, the NEXT successful gather depletes the tree.
-- If no one is chopping and the tree isn't depleted, the timer ticks back UP.
-- All players chopping the same tree are interrupted when it depletes.
-
-Use `deplete_timer` for trees. Use `depletes: true` on individual drops for rocks.
-
-#### Bird's nests
-
-When `nest_chance > 0`, each successful gather has a 1/N independent chance to also drop
-a bird's nest. The nest goes to inventory (or to the ground if inventory is full).
-Use the `search` command to open nests — they roll on the `birds_nest_drop` table.
-
-#### XP drops
-
-When `xp > 0`, the gather awards XP on each successful drop. If the player's `xpdrops`
-toggle is on, the output includes the XP gain: `(+37xp wct)`.
-
-### Talk (dialog trees)
-
-Full conversation with conditions, actions, and player flag tracking:
-```yaml
-id: guard_talk
-type: talk
-nodes:
- start:
- message: "\"Halt! This area is restricted.\""
- options:
- - text: "\"What's behind that gate?\""
- goto: about_gate
- - text: "\"I have copper ore.\"" # only shows if player has ore
- goto: trade_ore
- condition:
- has_item: copper_ore
- - text: "\"I have a pass.\"" # only shows if player earned a pass
- goto: has_pass
- condition:
- player_flag: got_pass
- value: true
- - text: "\"Goodbye.\""
- end: true
-
- about_gate:
- message: "\"Bring me some copper ore and I'll stamp you a pass.\""
- action:
- set_player_flags: # player-local: only this player
- talked_to_guard: true
- options:
- - text: "\"I'll be back.\""
- end: true
- - text: "\"I have some right here.\""
- goto: trade_ore
- condition:
- has_item: copper_ore
-
- trade_ore:
- message: "\"Good quality ore.\" He stamps a pass and hands it to you."
- action:
- take_item: copper_ore # removes 1 copper ore
- give_item: pass_stub # gives pass stub
- set_player_flags:
- got_pass: true # player now "has a pass"
- options:
- - text: "\"Thanks.\""
- end: true
-
- has_pass:
- message: "\"Alright, I'll open the gate for you.\""
- action:
- set_flags: # WORLD flag: gate opens for everyone
- gate_open: true
- options:
- - text: "\"Thanks.\""
- end: true
-```
-
-#### Node action reference
-
-| Field | Effect |
-|---|---|
-| `set_flags` | Sets world flags (global, shared by all players) |
-| `set_player_flags` | Sets player-local flags (per-character, quest progress) |
-| `give_item` | Gives an item to the player's inventory |
-| `take_item` | Removes an item from the player's inventory |
-| `teleport` | Moves the player to a room ID |
-| `heal` | Restores that many hitpoints |
-
-All fields in a single action are processed together — you can give an item, take an item, set flags, and heal all in one node.
-
-Example — quest completion:
-```yaml
-action:
- take_item: dragon_head
- give_item: dragon_slayer_medal
- set_player_flags:
- dragon_quest: complete
- dragon_slain: true
- heal: 99
- teleport: 1 # return to town
-```
-
-### Toggle (levers, switches, gates)
-
-Simple toggle that sets a world flag:
-```yaml
-id: iron_gate_toggle
-type: toggle
-message: "You push the heavy iron gate open."
-set_flags:
- gate_open: true
-check: # only works when gate is closed
- flag: gate_open
- value: true
- not: true
-```
-
-Lever that toggles between two states:
-```yaml
-id: bridge_lever
-type: toggle
-message: "You pull the lever. Mechanisms groan somewhere in the distance."
-set_flags:
- bridge_extended: true
-check:
- flag: bridge_extended
- value: true
- not: true
-```
-
-### Use (crafting stations)
-
-```yaml
-id: smelt_copper
-type: use
-message: "You place the ore in the furnace..."
-wait: 4 # ticks between crafts
-consume: # items consumed per craft
- copper_ore: 1
-reward: # item produced
- item_id: copper_bar
- quantity: 1
-fail_message: "The ore crumbles to dust."
-success:
- base: 0.60
- per_level: 0.01
- cap: 0.95
-skill: smithing
-level: 1
-xp: 15 # XP awarded per successful craft
-```
-
----
-
-## Conditions Reference
-
-Conditions are used in talk options, exit gates, on-enter scripts, and toggle checks.
-
-### Simple conditions
-
-```yaml
-# Check a world flag
-condition:
- flag: gate_open
- value: true
-
-# Check a world flag is NOT set
-condition:
- flag: gate_open
- not: true
-
-# Check a player flag
-condition:
- player_flag: finished_tutorial
- value: true
-
-# Check if player has an item
-condition:
- has_item: bronze_key
-
-# Check if player does NOT have an item
-condition:
- has_item: bronze_key
- not: true
-```
-
-### Compound conditions
-
-All must pass:
-```yaml
-condition:
- all_of:
- - flag: gate_open
- value: true
- - has_item: pass_stub
-```
-
-Any one must pass:
-```yaml
-condition:
- any_of:
- - has_item: bronze_key
- - has_item: iron_key
- - player_flag: master_of_unlocking
- value: true
-```
-
-Nested compounds:
-```yaml
-condition:
- all_of:
- - player_flag: quest_started
- value: true
- - any_of:
- - has_item: wolf_pelt
- - has_item: bear_pelt
-```
-
----
-
-## Drop Tables
-
-Shared drop tables can be referenced by multiple behaviors:
-```yaml
-# data/drops/gem_table.yaml
-id: gem_table
-drops:
- - item_id: uncut_sapphire
- weight: 47
- - item_id: uncut_emerald
- weight: 16
- - item_id: uncut_ruby
- weight: 4
- - item_id: uncut_diamond
- weight: 1
-```
-
-Bird's nest drop table:
-```yaml
-# data/drops/birds_nest_drop.yaml
-id: birds_nest_drop
-drops:
- - item_id: credits
- weight: 50
- quantity: 200
- - item_id: credits
- weight: 30
- quantity: 500
- - item_id: credits
- weight: 15
- quantity: 1000
- - item_id: credits
- weight: 4
- quantity: 3000
- - item_id: credits
- weight: 1
- quantity: 10000
-```
-
-Referenced from a gather behavior:
-```yaml
-drops:
- - item_id: copper_ore
- weight: 90
- depletes: true
- - table: gem_table # pulls from data/drops/gem_table.yaml
- weight: 10
- depletes: false
-```
-
----
-
-## Global vs Player State: Door Examples
-
-### Example A: Door with a button in another room (GLOBAL)
-
-A button in room 3 opens a door in room 7. Anyone can press it. Once pressed, the door is open for everyone.
-
-**Button object** (`data/objects/door_button.yaml`):
-```yaml
-id: door_button
-name: stone button
-behavior: button_toggle
-hidden: true
-```
-
-**Button behavior** (`data/behaviors/button_toggle.yaml`):
-```yaml
-id: button_toggle
-type: toggle
-message: "You press the stone button. You hear grinding stone in the distance."
-set_flags:
- secret_door_open: true # WORLD flag
-check:
- flag: secret_door_open
- not: true # only works when door is closed
-```
-
-**Room 3** — contains the button:
-```yaml
-id: 3
-name: "Button Chamber"
-description: "A small stone chamber. A button protrudes from the east wall."
-exits:
- south: 1
-objects:
- - id: door_button
-```
-
-**Room 7** — contains the door:
-```yaml
-id: 7
-name: "Hidden Passage"
-description: "A dusty corridor. A heavy stone door blocks the way north."
-exits:
- south: 2
- north:
- room: 8
- condition:
- flag: secret_door_open # checks WORLD flag
- value: true
- blocked_message: "A heavy stone door blocks the way."
-objects:
- - id: stone_door
- hidden: true
-```
-
-### Example B: Key-locked door (PLAYER-LOCAL)
-
-A locked door that only opens for a player carrying the key. Each player must find their own key.
-
-**Key item** (`data/items/rusty_key.yaml`):
-```yaml
-id: rusty_key
-name: rusty key
-description: "An old iron key, still functional."
-value: 0
-stackable: false
-```
-
-**Room 5** — locked door:
-```yaml
-id: 5
-name: "Locked Storage"
-description: "A small storage room. The way east is blocked by a locked iron door."
-exits:
- west: 2
- east:
- room: 6
- condition:
- has_item: rusty_key # checks PLAYER inventory
- blocked_message: "The iron door is locked. You need a key."
-objects:
- - id: iron_door
- hidden: true
-```
-
-**Room 6** — the other side (no key needed to exit):
-```yaml
-id: 6
-name: "Storage Closet"
-description: "Shelves of dusty crates."
-exits:
- west: 5 # exit back — no condition
-spawns:
- - item_id: uncut_ruby
- quantity: 1
- respawn_ticks: 500
-```
-
-Key difference: the button door uses `flag` (shared state — one player presses, everyone benefits), the key door uses `has_item` (per-player inventory check — each player needs their own key).
-
----
-
-## Complete Quest Example: "Clear the Rats"
-
-### 1. Quest giver mob (`data/mobs/quest_giver.yaml`)
-```yaml
-id: "quest_giver"
-name: "Elder"
-behavior: rat_quest_talk
-unique: true
-protected: true
-attack: 1
-strength: 1
-defense: 1
-hp: 20
-speed: 5
-aggressive: false
-idle_descriptions:
- - "mutters about the rat infestation"
-```
-
-### 2. Dialog behavior (`data/behaviors/rat_quest_talk.yaml`)
-```yaml
-id: rat_quest_talk
-type: talk
-nodes:
- start:
- message: "\"Rats! Rats everywhere in the cellar. Clear them out and I'll reward you.\""
- options:
- - text: "\"I'll handle it.\""
- goto: accept_quest
- condition:
- player_flag: rat_quest
- not: true
- - text: "\"I killed the rats.\""
- goto: turn_in
- condition:
- player_flag: rat_quest
- value: started
- - text: "\"Goodbye.\""
- end: true
-
- accept_quest:
- message: "\"Good lad. The cellar is west of here. Come back when they're dead.\""
- action:
- set_player_flags:
- rat_quest: started
- options:
- - text: "\"On my way.\""
- end: true
-
- turn_in:
- message: "\"You did it! The village owes you a debt. Here — take this.\""
- action:
- give_item: rusty_sword
- set_player_flags:
- rat_quest: complete
- heal: 10
- options:
- - text: "\"Thanks!\""
- end: true
-```
-
-### 3. Rat mobs (`data/mobs/rat.yaml`)
-```yaml
-id: "rat"
-name: "giant rat"
-attack: 2
-strength: 1
-defense: 1
-hp: 3
-speed: 4
-aggressive: true
-respawn_ticks: 60
-drops:
- remains: "rat bones"
-```
-
-### 4. Cellar room (`data/rooms/20.yaml`)
-```yaml
-id: 20
-name: "Cellar"
-description: "A damp, dark cellar. The floor scuttles with movement."
-exits:
- east: 1
-mobs:
- - "rat"
- - "rat"
- - "rat"
- - "rat"
- - "rat"
-```
-
-### 5. Room 1 with quest giver (`data/rooms/1.yaml`)
-```yaml
-id: 1
-name: "Town Square"
-description: "Cobblestone paths lead in all directions. The Elder stands near the fountain."
-exits:
- west: 20
- north: 2
-mobs:
- - "quest_giver"
-objects:
- - id: lumby_fountain
-```
-
----
-
-## Wandering Objects
-
-Fishing spots that move between rooms:
-```yaml
-# data/objects/fishing_spot.yaml
-id: fishing_spot
-name: fishing spot
-behavior: fish_trout
-```
-
-```yaml
-# In a room:
-objects:
- - id: fishing_spot
- wander_rooms: [7, 8, 9]
- wander_interval: 12
-```
-
-Objects teleport between rooms in their `wander_rooms` list. Players gathering from a
-wandering object are silently interrupted when it moves.
-
----
-
-## Wandering Mobs
-
-Mob wandering is configured per-instance in the room YAML, not on the mob definition:
-```yaml
-# In a room:
-mobs:
- - id: man
- wander_interval: 10 # attempt to wander every 10 ticks
- - id: man
- wander_interval: 15
- wander_rooms: [5, 6, 7] # optional — restrict which rooms via exits
-```
-
-Mobs wander through legal (unconditioned) room exits. When the wander interval expires,
-the mob picks a random exit with no conditions and moves through it. If `wander_rooms`
-is set, only exits leading to those room IDs are legal. Mobs without `wander_interval`
-never wander. Mobs stop wandering while in combat. Dead mobs respawn at their home room.
-
----
-
-## Player Toggles
-
-Players can toggle personal settings with the `toggle` command:
-
-| Toggle | Effect |
-|---|---|
-| `description` | Show full room description when moving |
-| `tiny_map` | Mini-map display: `off`/`right`/`left` |
-| `xp_drops` | Show XP gained in gather/craft/combat messages |
-| `exits` | Show exit destinations inline in look output |
-| `mob_enter` | Notify when a mob enters the room |
-| `mob_leave` | Notify when a mob leaves the room |
-| `mob_spawn` | Notify when a mob spawns in the area |
-| `reserve` | Show full reserved item details in look |
-| `depletion` | Show depletion and despawn timers on objects |
-
----
-
-## The `search` Command
-
-Used to open searchable items in your inventory (bird's nests, etc.):
-```
-Usage: search <item>
-
-Example: search nest
- search birds nest
-```
-
-Searches your inventory for the named item. If found, removes it and rolls on a drop table.
-Currently only bird's nests are searchable.
-
----
-
-## Hidden Objects
-
-Objects with `hidden: true` don't appear in the room's object listing. Players discover them by reading room descriptions or trying commands. The object is still fully interactable — `push gate`, `look gate`, etc.
-
-```yaml
-# data/objects/secret_lever.yaml
-id: secret_lever
-name: stone lever
-behavior: secret_toggle
-hidden: true
-props:
- description: "A cleverly concealed lever behind a loose stone."
-```
-
-Room description hints at it:
-```yaml
-description: "A dusty corridor. One of the wall stones looks slightly out of place."
-```
-
----
-
-## Tips
-
-1. **Use player flags for quest progress, world flags for environmental state.** If a bridge is repaired, that's world state. If a player has read a sign, that's player state.
-
-2. **Conditions on enter scripts** make rooms feel alive. A guard who only barks the first time, a room that changes after a quest completes.
-
-3. **Hidden objects** keep room descriptions clean. Mention them in the room's description text instead of auto-listing them.
-
-4. **Drop tables** are shareable. The `gem_table` is used by copper rocks AND mob loot. Define once, reference everywhere.
-
-5. **Objects are for fixtures, mobs are for living things.** If it has HP and can die, it's a mob. If it's a rock, lever, door, or crafting station, it's an object. Both can have behaviors.
-
-6. **The `behavior` field on mobs** lets you talk to them directly — `talk guard` finds the guard mob, no duplicate object entry needed.
-
-7. **Exits accept both `int` and `map` formats.** `north: 2` is shorthand for `north: {room: 2}`. Add `condition` and `blocked_message` only when needed. Mob room entries accept both `"man"` and `{id: man, ...}`.
-
-8. **Live editing works.** Room, item, mob, object, and behavior YAML files are read from disk on each access. Change a room description or dialog and it takes effect immediately — no restart needed.
-
-9. **Shared depletion vs per-drop depletion.** Use `deplete_timer` for trees — the timer counts down while being chopped and regens when left alone. Use `depletes: true` on individual drops for rocks — they deplete on first successful gather.
-
-10. **Mob wander config goes in the room YAML**, not the mob definition. This lets the same `man` wander differently in different rooms.