From fbe5090ac3325ff8ea6989cdf4515c7f077c975b Mon Sep 17 00:00:00 2001 From: historia <[not public]> Date: Wed, 1 Jul 2026 03:21:52 -0400 Subject: feat: item messaging standardized, custom messages for production paths implemented --- building_guide/admin.md | 69 +++++++++--- building_guide/behaviors.md | 2 +- building_guide/hazards.md | 1 - building_guide/items.md | 120 ++++++++++++--------- building_guide/recipes.md | 24 ++--- building_guide/rooms.md | 18 ++-- data/.admin_history.json | 2 +- data/items/ammo/headless_arrow.yaml | 2 +- data/items/consumables/bread.yaml | 2 +- data/items/consumables/bread_dough.yaml | 2 +- data/items/consumables/guam_potion_unf.yaml | 2 +- data/items/consumables/pie_dish.yaml | 2 +- data/items/materials/ball_of_wool.yaml | 2 +- data/items/materials/bowstring.yaml | 2 +- data/items/materials/diamond.yaml | 2 +- data/items/materials/emerald.yaml | 2 +- data/items/materials/mahogany_planks.yaml | 2 +- data/items/materials/oak_planks.yaml | 2 +- data/items/materials/planks.yaml | 2 +- data/items/materials/ruby.yaml | 2 +- data/items/materials/sapphire.yaml | 2 +- data/items/materials/teak_planks.yaml | 2 +- data/items/tools/empty_pot.yaml | 2 +- data/items/tools/plant_pot.yaml | 2 +- data/items/tools/unfired_pie_dish.yaml | 2 +- data/items/tools/unfired_plant_pot.yaml | 2 +- data/items/tools/unfired_pot.yaml | 2 +- data/objects/adamantite_rock.yaml | 2 +- data/objects/anglerfish_spot.yaml | 2 +- data/objects/bait_fishing_spot.yaml | 6 +- data/objects/cage_fishing_spot.yaml | 2 +- data/objects/clay_rock.yaml | 2 +- data/objects/coal_rock.yaml | 2 +- data/objects/copper_rock.yaml | 4 +- data/objects/fly_fishing_spot.yaml | 6 +- data/objects/gold_rock.yaml | 2 +- data/objects/harpoon_fishing_spot.yaml | 6 +- data/objects/iron_rock.yaml | 2 +- data/objects/magic_tree.yaml | 2 +- data/objects/mahogany_tree.yaml | 2 +- data/objects/maple_tree.yaml | 2 +- data/objects/mithril_rock.yaml | 2 +- data/objects/net_fishing_spot.yaml | 10 +- data/objects/oak_tree.yaml | 2 +- data/objects/redwood_tree.yaml | 2 +- data/objects/runite_rock.yaml | 2 +- data/objects/sacred_eel_spot.yaml | 2 +- data/objects/scrap_pile.yaml | 2 +- data/objects/sheep.yaml | 2 +- data/objects/silver_rock.yaml | 2 +- data/objects/swamp_fishing_spot.yaml | 4 +- data/objects/teak_tree.yaml | 2 +- data/objects/tin_rock.yaml | 2 +- data/objects/tree.yaml | 2 +- data/objects/willow_tree.yaml | 2 +- data/objects/yew_tree.yaml | 2 +- data/rooms/intro/2001.yaml | 4 +- internal/admin/static/itemeditor.js | 48 +++++++-- internal/behavior/behavior.go | 26 +++-- internal/behavior/store.go | 8 +- internal/behavior/types.go | 47 ++++++--- internal/game/act.go | 10 +- internal/game/act_clean.go | 2 +- internal/game/act_combine.go | 157 ++++++++++++++++++++++++++++ internal/game/act_fletch.go | 2 +- internal/game/act_gather.go | 25 +++-- internal/game/act_state.go | 8 +- internal/game/act_use.go | 28 ++++- internal/game/act_use_interaction.go | 23 ++++ internal/game/cmd_use.go | 32 ++++-- internal/game/core_production.go | 7 -- internal/game/production_engine.go | 31 ++---- internal/item/item.go | 4 +- 73 files changed, 569 insertions(+), 251 deletions(-) create mode 100644 internal/game/act_combine.go create mode 100644 internal/game/act_use_interaction.go diff --git a/building_guide/admin.md b/building_guide/admin.md index 1c7db93..fbe15d5 100644 --- a/building_guide/admin.md +++ b/building_guide/admin.md @@ -40,7 +40,7 @@ etc.) and they receive a notification. Case-insensitive name matching. ``` dig [name] ``` -Creates a new room in the given direction (north/south/east/west/up/down) from your +Creates a new room in the given direction (north/south/east/west/ne/nw/se/sw/up/down) from your current room. The new room ID is auto-generated as the lowest available integer at-or-above the minimum room ID in the same directory as your current room's YAML file. @@ -61,7 +61,7 @@ Examples: undig ``` Deletes the room in the given direction and removes all exits leading to it from -every room. Requires confirmation — type `UNDIG ` to proceed, anything +every room. Requires confirmation — type `y`/`yes` to proceed, anything else to cancel. The target room's name and ID are shown before deletion. A warning is displayed if deleting the room would create orphaned (unreachable) rooms. @@ -196,21 +196,62 @@ Dumps detailed diagnostic information about your current room: - Connected players in the room - Live mob instances with HP +### Web Admin GUI + +The server includes a browser-based admin panel for managing all game data visually. It runs alongside +the game server and is configured in `config.yaml` under `admin_http` (plain HTTP) or `admin_https` +(TLS with auto-generated self-signed certificate). + +#### Setup + +1. Ensure your account YAML has `admin: true` (same as in-game admin). +2. Configure the admin server in `config.yaml`: + ```yaml + admin_http: ":8080" # listens on port 8080, HTTP + # or for HTTPS: + admin_https: ":8443" + ``` +3. Start the game server. The admin panel is available at `http://:8080` (or `https://:8443`). +4. Log in with your account name and password (same credentials as in-game). + +#### Features + +| Page | URL | Description | +|------|-----|-------------| +| Map | `/` | Interactive SVG map showing rooms on a 3D grid. Zoom/pan, click rooms to edit, create/delete rooms and exits, relink exits. Up/down links shown alongside horizontal connections. | +| Items | `/editor/items` | Full CRUD editor with sections for equipment (type/slot/attack/defense/other), tool, craft (type/level/XP/ingredients/stations/tool/steps), firemaking, farming, potions, and requirements. Undo/redo supported. | +| Objects | `/editor/objects` | CRUD editor with sections for gather (tools/drops/success formula), use (message/wait/consumes), talk (visual talk tree editor), safespot, steal, use_interactions, and on_look. | +| Mobs | `/editor/mobs` | CRUD for mob definitions — stats, drops, talk, behavior, assassin/steal/task fields. | +| Drops | `/editor/drops` | CRUD for shared drop tables (gem tables, bird's nests, etc.). | +| Hazards | `/editor/hazards` | CRUD for hazard definitions. | +| Techs | `/editor/techs` | CRUD for technology definitions (buffs, drain rates, categories). | +| Courses | `/editor/courses` | CRUD for agility courses (obstacle sequences, XP, fail damage). | +| Modules | `/editor/modules` | CRUD for science modules (combat/utility/transport/enchant/processing). | +| Players | `/editor/players` | Browse character YAML files and view player state. | +| Flags | `/editor/flags` | View and edit world flags in real time. | +| Files | `/editor/files` | Raw file tree browser for all YAML files under `data/`. | + +All CRUD editors support undo/redo (persisted to `data/.admin_history.json`), so changes can be reverted +even across sessions. + +#### Map Interface + +The map page (`/`) is the main navigation hub: +- Rooms are displayed as colored nodes on a 3D grid, connected by links (bars for two-way, arrows for one-way, X for blocked). +- Click a room node to edit its properties (name, description, color, exits, objects, mobs, spawns). +- Drag connections between rooms to create or relink exits. +- Right-click (or long-press) a room to delete it or access advanced options. +- The map uses the same BFS-based grid layout as the in-game map, showing all rooms on the current z-plane. +- Up/down links are shown with special glyphs when connecting rooms on different z-levels. + ### Workflow The typical admin worldbuilding workflow: -1. **Lay out rooms:** Use `dig` to create connected rooms quickly. If `dig` would create a - grid overlap, a two-way link is created instead — no duplicate rooms. Use `room insert` - to place a new room between two already-connected rooms without breaking the map grid. -2. **Flesh out rooms:** Use `room` commands to set names, descriptions, add objects/mobs/spawns - directly from inside the game. For deeper edits, edit the YAML files directly in - `data/rooms/` to add on-enter scripts, triggers, hazards, etc. -3. **Rearrange:** Use `swapid` to renumber rooms and `undig` to delete rooms you no longer want - (with full exit cleanup). Use `close` to remove individual exits. +1. **Lay out rooms:** Use `dig` to create connected rooms quickly, or use the web map to create and link rooms visually. If `dig` would create a grid overlap, a two-way link is created instead — no duplicate rooms. Use `room insert` to place a new room between two already-connected rooms without breaking the map grid. +2. **Flesh out rooms:** Use `room` commands to set names, descriptions, add objects/mobs/spawns directly from inside the game. Use the web admin editors for richer CRUD with undo/redo. For deeper edits, edit the YAML files directly in `data/rooms/` to add on-enter scripts, triggers, hazards, etc. +3. **Rearrange:** Use `swapid` to renumber rooms and `undig` to delete rooms you no longer want (with full exit cleanup). Use `close` to remove individual exits. 4. **Reload:** Run `reload` to pick up YAML changes without restarting (rooms auto-reload). 5. **Test:** Use `goto` to jump around while debugging room connections and content. -6. **God mode:** Use `god` to test dangerous areas safely — full stats, no aggro, pass through - blocked exits. `ungod` restores normal state. -7. **Debug:** Use `setflag` / `setplayerflag` to test quest logic and conditional content. - Use `inspect` to check room state, flags, and triggers. +6. **God mode:** Use `god` to test dangerous areas safely — full stats, no aggro, pass through blocked exits. `ungod` restores normal state. +7. **Debug:** Use `setflag` / `setplayerflag` to test quest logic and conditional content. Use `inspect` to check room state, flags, and triggers. diff --git a/building_guide/behaviors.md b/building_guide/behaviors.md index 0fc6516..3d35036 100644 --- a/building_guide/behaviors.md +++ b/building_guide/behaviors.md @@ -510,7 +510,7 @@ Item-specific interaction: ```yaml name: bookshelf use_interactions: - - item: dusty_tome + - item_id: dusty_tome message: "The bookshelf slides aside, revealing a secret passage!" action: set_flags: diff --git a/building_guide/hazards.md b/building_guide/hazards.md index 26fdccc..5db7ceb 100644 --- a/building_guide/hazards.md +++ b/building_guide/hazards.md @@ -33,7 +33,6 @@ required_item: "" # optional: an equipped item that NEGATES the haza | Field | Description | |---|---| -| `id` | Unique identifier (matches the filename) | | `name` | Display name used in warnings and default messages | | `description` | Flavour text (for a future `examine`) | | `attack_type` | `stab`/`slash`/`crush`/`ranged`/`science` — selects which player defense bonus applies and which protection tech reduces the damage (empty = `crush`) | diff --git a/building_guide/items.md b/building_guide/items.md index eefdf9c..e03622d 100644 --- a/building_guide/items.md +++ b/building_guide/items.md @@ -5,6 +5,10 @@ put an `id:` field in the file — it is ignored. Anything that references this item (drop tables, craft `ingredients`, room `item_spawns`) uses that filename. +### Equipment & Tool Blocks + +Combat and equipment stats go under an `equipment:` block. Tool stats go under a `tool:` block. + ```yaml name: bronze pickaxe color: "B2" # xterm-256 color index (00-FF) @@ -12,88 +16,108 @@ 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, ranged, or science -attack_type: stab # stab/slash/crush/ranged/science — determines accuracy type -stats: # optional — per-type combat bonuses - stab_attack: 4 - slash_attack: -2 - crush_attack: 2 - strength_bonus: 3 -speed: 5 # ticks between attacks -tool_type: pickaxe # used by gather behaviors that require "tool: pickaxe" -tool_speed: 2 # reduces gather wait time +equipment: # optional — combat/equip behavior + type: melee_weapon # melee_weapon / ranged_weapon / tech_weapon / armor / ammo / tool + slot: main_hand # head / neck / torso / legs / hands / feet / back / + # ammo / main_hand / off_hand / ring + attack_type: stab # stab/slash/crush/ranged/science — determines accuracy type + speed: 5 # ticks between attacks + attack: # accuracy bonuses per type + stab: 4 + slash: -2 + crush: 2 + other: + strength: 3 # melee max hit bonus +tool: # optional — tool behavior + type: pickaxe # used by gather behaviors that require "tool: pickaxe" + speed: 2 # reduces gather wait time requirements: # optional — skill levels needed to equip accuracy: 1 ``` -### Equipment Stats (ItemStats) - -Weapons have per-type **attack bonuses** — these determine accuracy based on the weapon's `attack_type`: +### Equipment Block Fields | Field | Description | |---|---| -| `stab_attack` | Accuracy bonus for stab attacks | -| `slash_attack` | Accuracy bonus for slash attacks | -| `crush_attack` | Accuracy bonus for crush attacks | -| `science_attack` | Accuracy bonus for science attacks | -| `ranged_attack` | Accuracy bonus for ranged attacks | - -Armor has per-type **defense bonuses** — the mob's `attack_type` determines which defense is used: - -| Field | Description | +| `type` | Equipment type: `melee_weapon` / `ranged_weapon` / `tech_weapon` / `armor` / `ammo` / `tool` | +| `slot` | Equip slot (see below) | +| `attack_type` | `stab` / `slash` / `crush` / `ranged` / `science` — determines which defense the target uses | +| `speed` | Ticks between attacks | +| `junk` | Junk type this item gives when recycled (for Science decks) | +| `attack` | Attack bonuses (accuracy) — sub-fields: `stab`, `slash`, `crush`, `ranged`, `science` | +| `defense` | Defense bonuses — sub-fields: `stab`, `slash`, `crush`, `ranged`, `science` | +| `other` | Other bonuses — `strength` (melee max hit), `ranged` (ranged max hit on ammo), `science` (science max hit), `technology` (reduces tech battery drain) | + +### Equipment Slots + +| Slot | Description | |---|---| -| `stab_defense` | Defense vs stab attacks | -| `slash_defense` | Defense vs slash attacks | -| `crush_defense` | Defense vs crush attacks | -| `science_defense` | Defense vs science attacks (negative on metal armor) | -| `ranged_defense` | Defense vs ranged attacks | - -Other damage/utility bonuses: - -| Field | Description | -|---|---| -| `strength_bonus` | Melee max hit bonus | -| `ranged_strength` | Ranged max hit bonus (on ammo) | -| `science_damage` | Science max hit bonus | -| `technology_bonus` | Reduces tech battery drain rate | +| `head` | Helmets, hats | +| `neck` | Amulets, necklaces | +| `torso` | Platebodies, chest armor | +| `legs` | Platelegs, chaps | +| `hands` | Gloves, vambraces | +| `feet` | Boots | +| `back` | Capes, back items | +| `ammo` | Arrows, bolts | +| `main_hand` | Weapons, tools, shields | +| `off_hand` | Shields, secondary items | +| `ring` | Rings | ### Attack Type -Weapons should always set `attack_type`. Common mappings: +`attack_type` determines which defense stat the target rolls against: -| Category | attack_type | +| Weapon | attack_type | |---|---| | Swords | slash | | Daggers | stab | | Axes | slash | | Pickaxes | stab | | Bows | ranged | +| Science decks | science | | Unarmed | crush (default) | -### Equipment Requirements +### Requirements Higher-tier equipment requires skill levels to equip: ```yaml requirements: accuracy: 20 # melee weapons - defense: 20 # armor - ranged: 30 # ranged weapons/armor + defense: 20 # armor + ranged: 30 # ranged weapons/armor ``` Standard tiers: bronze/iron (none), steel (5), black (10), mithril (20), adamant (30), rune (40), dragon (60). ### Ranged Ammo -Arrows and bolts use `ranged_strength` for damage. Accuracy comes from the bow: +Arrows and bolts use `other.ranged` for damage. Accuracy comes from the bow: ```yaml name: iron arrow stackable: true -equip_slot: ammo -stats: - ranged_strength: 10 +equipment: + other: + ranged: 10 + slot: ammo + type: ammo +``` + +### Science Decks + +Decks use `tech_weapon` type and `science` attack_type: + +```yaml +name: basic deck +equipment: + type: tech_weapon + slot: main_hand + attack_type: science + speed: 5 + attack: + science: 5 ``` ### Color @@ -102,8 +126,8 @@ The `color` field accepts xterm-256 palette indices (00-FF, hex) with optional m ```yaml color: "B2" # bronze/gold -color: "4B bold" # bold steel blue -color: "g:C4,D0,E2" # gradient red → orange → gold +color: "4B bold" # bold steel blue +color: "g:C4,D0,E2" # gradient red → orange → gold ``` In ANSI mode, extended colors (10-FF) automatically downgrade to the nearest ANSI color. Use `colortable` in-game to see all 256 colors. diff --git a/building_guide/recipes.md b/building_guide/recipes.md index e865fa6..96bf0f9 100644 --- a/building_guide/recipes.md +++ b/building_guide/recipes.md @@ -18,7 +18,7 @@ Crafting information lives on the **output item's YAML file** via the `craft:` b | `ingredients` | []IngredientEntry | Ingredients consumed (see below) | | `output_qty` | int | Quantity produced (default 1, for stackables) | | `fail` | string | ItemID produced on failure (optional) | -| `message` | string | Success message per cycle (optional, see message defaults) | +| `success_message` | string | Success message per cycle (optional, see message defaults) | | `fail_message` | string | Failure message (optional, empty = silent fail) | | `start_message`| string | Message when action begins (optional, see message defaults) | | `end_message` | string | Message when action completes (optional, see message defaults) | @@ -29,7 +29,7 @@ The output is the item itself — no `output` field needed. The item ID IS the c ### Message Variables -All message fields (`message`, `fail_message`, `start_message`, `end_message`, and `steps[].message`) support variables that expand to colorized item names: +All message fields (`success_message`, `fail_message`, `start_message`, `end_message`, and `steps[].message`) support variables that expand to colorized item names: | Variable | Expands to | | -------- | ----------------------------------------------- | @@ -47,7 +47,7 @@ Variables work alongside inline color tags (`{C4}text{/}`) which are expanded af If a message field is omitted from the YAML, the game uses a skill-level default based on the craft `type`: -| Type | Default `message` | Default `start_message` | +| Type | Default `success_message` | Default `start_message` | |------|-------------------|------------------------| | `cooking` | `"Cooked to perfection. %n looks great!"` | `"You start cooking %i1."` | | `smelt` | `"You remove a white hot %n!"` | `"You place the %i1 into the furnace."` | @@ -81,7 +81,7 @@ craft: message: "You try to puzzle how the pieces fit together." - tick: 3 message: "Aha, this edge lines up here!" - message: "You assemble the map!" + success_message: "You assemble the map!" ``` ### IngredientEntry — Multi-Item Ingredient Slots @@ -120,7 +120,7 @@ craft: quantity: 1 - items: [eye_of_newt] quantity: 1 - message: "You mix a %n." # %n expands to "stim potion" colored + success_message: "You mix a %n." # %n expands to "stim potion" colored ``` ### Station-Based Production @@ -139,8 +139,8 @@ craft: quantity: 1 - items: [tin_ore] quantity: 1 - message: "You smelt a %n." # default is "You remove a white hot %n!" - # overridden here for simpler flavor + success_message: "You smelt a %n." # default is "You remove a white hot %n!" + # overridden here for simpler flavor ``` ```yaml @@ -154,7 +154,7 @@ craft: ingredients: - items: [bronze_bar] quantity: 1 - # message omitted — uses default "You smith a %n." + # success_message omitted — uses default "You smith a %n." ``` For stackable outputs, use `output_qty`: @@ -171,7 +171,7 @@ craft: - items: [bronze_bar] quantity: 1 output_qty: 15 - # message omitted — uses default "You smith a %n." + # success_message omitted — uses default "You smith a %n." ``` ### Tool-Based Production @@ -206,7 +206,7 @@ craft: byproducts: [empty_vial, empty_jug] - items: [empty_bucket] quantity: 1 - message: "You pour the %i1 into the %i2." # %i1 = water source, %i2 = bucket + success_message: "You pour the %i1 into the %i2." # %i1 = water source, %i2 = bucket ``` ### Multi-Piece Assembly (3+ items → 1) @@ -227,7 +227,7 @@ craft: message: "You try to puzzle how the pieces fit together." - tick: 3 message: "Aha, this edge lines up here!" - message: "You assemble the %n." + success_message: "You assemble the %n." ``` ### Clean Recipes @@ -245,7 +245,7 @@ craft: ingredients: - items: [grimy_guam] quantity: 1 - # message omitted — uses default "You clean the %i1." + # success_message omitted — uses default "You clean the %i1." # %i1 expands to the grimy herb name with its color ``` diff --git a/building_guide/rooms.md b/building_guide/rooms.md index 0211c33..d3412de 100644 --- a/building_guide/rooms.md +++ b/building_guide/rooms.md @@ -42,6 +42,8 @@ Simple exit — always passable: ```yaml exits: north: 2 + ne: 3 # ne/nw/se/sw also work + southeast: 4 ``` Conditional exit — blocked until a world flag is set: @@ -90,10 +92,11 @@ exits: ### Map grid & one-way exits -Horizontal exits (north/south/east/west) must form a consistent 2D grid: from any -starting room, walking N/S/E/W should never land two different rooms on the same -spot, and a given room must always resolve to the same spot. Up/down don't move on -the grid — they lead to a separate plane (floor) that is laid out on its own. +All exits (north/south/east/west/ne/nw/se/sw) must form a consistent 3D grid: from +any starting room, walking horizontal directions should never land two different +rooms on the same 3D coordinate, and a given room must always resolve to the same +spot. Up/down move on the z-axis within this same grid (different floors share the +same x/y coordinate space). Startup validation enforces this, starting from `startup_validation.root_rooms` (see config.yaml). It reports an **overlap** (two rooms on one grid cell) or a @@ -101,9 +104,10 @@ Startup validation enforces this, starting from `startup_validation.root_rooms` Exits don't have to be reciprocal. A one-way link (e.g. room 2001 has `east: 2006` but 2006 has no `west` back) renders on the map as a directional arrow -(`← ↑ → ↓`, or `< ^ > v` in ASCII) instead of a two-way bar. If a link is open in -one direction but blocked (failing condition) in the other, the open direction's -arrow is shown; only a link with no traversable direction shows the blocked `X`. +(`← ↑ → ↓`, or `< ^ > v` in ASCII, with `↗↖↘↙` for diagonal) instead of a +two-way bar. If a link is open in one direction but blocked (failing condition) in +the other, the open direction's arrow is shown; only a link with no traversable +direction shows the blocked `X`. Blocked up/down exits also show the blocked `X`. ### Item Spawns — ground items that respawn diff --git a/data/.admin_history.json b/data/.admin_history.json index 8519fc5..4bdaf10 100644 --- a/data/.admin_history.json +++ b/data/.admin_history.json @@ -1 +1 @@ -{"history":[{"time":"2026-06-30T14:29:37-04:00","description":"delete room 1014 (cleaned 0 exits)","file_path":"data/rooms/intro/1014.yaml","old_content":"id: 1014\nname: 'Room #1014'\ncolor: D5\ndescription: []\nexits:\n southwest:\n room: 1013\nobjects: []\nitem_spawns: []\nmobs: []\non_enter: []\nhazard: \"\"\nblock_transport: false\ntriggers: []\n","new_content":"","is_delete":true,"is_create":false},{"time":"2026-06-30T14:29:37-04:00","description":"delete room 1016 (cleaned 0 exits)","file_path":"data/rooms/intro/1016.yaml","old_content":"id: 1016\nname: New Room\ncolor: \"97\"\ndescription:\n - text: A featureless room.\nexits:\n down:\n room: 1017\n south:\n room: 1009\n southwest:\n room: 1005\nobjects: []\nitem_spawns: []\nmobs: []\non_enter: []\nhazard: \"\"\nblock_transport: false\ntriggers: []\n","new_content":"","is_delete":true,"is_create":false},{"time":"2026-06-30T14:29:38-04:00","description":"delete room 1015 (cleaned 0 exits)","file_path":"data/rooms/intro/1015.yaml","old_content":"id: 1015\nname: 'Room #1015'\ncolor: 0C\ndescription: []\nexits:\n northwest:\n room: 1018\nobjects: []\nitem_spawns: []\nmobs: []\non_enter: []\nhazard: \"\"\nblock_transport: false\ntriggers: []\n","new_content":"","is_delete":true,"is_create":false},{"time":"2026-06-30T14:29:39-04:00","description":"delete room 1017 (cleaned 0 exits)","file_path":"data/rooms/intro/1017.yaml","old_content":"id: 1017\nname: New Room\ncolor: \"\"\ndescription:\n - text: A featureless room.\nexits: {}\nobjects: []\nitem_spawns: []\nmobs: []\non_enter: []\nhazard: \"\"\nblock_transport: false\ntriggers: []\n","new_content":"","is_delete":true,"is_create":false},{"time":"2026-06-30T14:29:40-04:00","description":"delete room 1018 (cleaned 0 exits)","file_path":"data/rooms/intro/1018.yaml","old_content":"id: 1018\nname: 'Room #1018'\ncolor: D0\ndescription: []\nexits: {}\nobjects: []\nitem_spawns: []\nmobs: []\non_enter: []\nhazard: \"\"\nblock_transport: false\ntriggers: []\n","new_content":"","is_delete":true,"is_create":false},{"time":"2026-06-30T14:29:40-04:00","description":"delete room 1019 (cleaned 0 exits)","file_path":"data/rooms/intro/1019.yaml","old_content":"id: 1019\nname: 'Room #1019'\ncolor: \"\"\ndescription: []\nexits: {}\nobjects: []\nitem_spawns: []\nmobs: []\non_enter: []\nhazard: \"\"\nblock_transport: false\ntriggers: []\n","new_content":"","is_delete":true,"is_create":false},{"time":"2026-06-30T14:29:41-04:00","description":"delete room 1020 (cleaned 0 exits)","file_path":"data/rooms/intro/1020.yaml","old_content":"id: 1020\nname: 'Room #1020'\ncolor: \"\"\ndescription: []\nexits: {}\nobjects: []\nitem_spawns: []\nmobs: []\non_enter: []\nhazard: \"\"\nblock_transport: false\ntriggers: []\n","new_content":"","is_delete":true,"is_create":false},{"time":"2026-06-30T14:30:45-04:00","description":"delete room 1013 (cleaned 1 exits)","file_path":"data/rooms/intro/1013.yaml","old_content":"id: 1013\nname: 'Room #1013'\ncolor: \"72\"\ndescription: []\nexits:\n west:\n room: 1007\nobjects: []\nitem_spawns: []\nmobs: []\non_enter: []\nhazard: \"\"\nblock_transport: false\ntriggers: []\n","new_content":"","is_delete":true,"is_create":false},{"time":"2026-06-30T14:30:49-04:00","description":"delete room 1009 (cleaned 0 exits)","file_path":"data/rooms/intro/1009.yaml","old_content":"id: 1009\nname: New Room\ncolor: \"27\"\ndescription:\n - text: A featureless room.\nexits:\n northwest:\n room: 8\n southwest:\n room: 1006\n west:\n room: 1005\nobjects: []\nitem_spawns: []\nmobs:\n - id: man\n - id: man\non_enter: []\nhazard: \"\"\nblock_transport: false\ntriggers: []\n","new_content":"","is_delete":true,"is_create":false},{"time":"2026-06-30T14:30:51-04:00","description":"delete room 1007 (cleaned 1 exits)","file_path":"data/rooms/intro/1007.yaml","old_content":"id: 1007\nname: 'Room #1007'\ncolor: \"\"\ndescription: []\nexits:\n west:\n room: 2004\nobjects: []\nitem_spawns: []\nmobs: []\non_enter: []\nhazard: \"\"\nblock_transport: false\ntriggers: []\n","new_content":"","is_delete":true,"is_create":false},{"time":"2026-06-30T14:30:53-04:00","description":"delete room 1006 (cleaned 4 exits)","file_path":"data/rooms/intro/1006.yaml","old_content":"id: 1006\nname: New Room\ncolor: E2\ndescription:\n - text: A featureless room.\nexits:\n north:\n room: 1005\n northwest:\n room: 1008\n up:\n room: 1010\n west:\n room: 2003\nobjects: []\nitem_spawns: []\nmobs: []\non_enter: []\nhazard: \"\"\nblock_transport: false\ntriggers: []\n","new_content":"","is_delete":true,"is_create":false},{"time":"2026-06-30T14:30:59-04:00","description":"delete room 1010 (cleaned 1 exits)","file_path":"data/rooms/intro/1010.yaml","old_content":"id: 1010\nname: New Room\ncolor: \"\"\ndescription:\n - text: A featureless room.\nexits:\n north:\n room: 1011\nobjects: []\nitem_spawns: []\nmobs: []\non_enter: []\nhazard: \"\"\nblock_transport: false\ntriggers: []\n","new_content":"","is_delete":true,"is_create":false},{"time":"2026-06-30T14:31:00-04:00","description":"delete room 1011 (cleaned 0 exits)","file_path":"data/rooms/intro/1011.yaml","old_content":"id: 1011\nname: New Room\ncolor: \"\"\ndescription:\n - text: A featureless room.\nexits:\n east:\n room: 1012\nobjects: []\nitem_spawns: []\nmobs: []\non_enter: []\nhazard: \"\"\nblock_transport: false\ntriggers: []\n","new_content":"","is_delete":true,"is_create":false},{"time":"2026-06-30T14:31:01-04:00","description":"delete room 1012 (cleaned 0 exits)","file_path":"data/rooms/intro/1012.yaml","old_content":"id: 1012\nname: New Room\ncolor: \"\"\ndescription:\n - text: A featureless room.\nexits: {}\nobjects: []\nitem_spawns: []\nmobs: []\non_enter: []\nhazard: \"\"\nblock_transport: false\ntriggers: []\n","new_content":"","is_delete":true,"is_create":false},{"time":"2026-06-30T14:31:02-04:00","description":"delete room 1005 (cleaned 2 exits)","file_path":"data/rooms/intro/1005.yaml","old_content":"id: 1005\nname: New Room\ncolor: CC\ndescription:\n - text: A featureless room.\nexits:\n southwest:\n room: 2003\n west:\n room: 1008\nobjects: []\nitem_spawns: []\nmobs: []\non_enter: []\nhazard: \"\"\nblock_transport: false\ntriggers: []\n","new_content":"","is_delete":true,"is_create":false},{"time":"2026-06-30T14:31:03-04:00","description":"delete room 1008 (cleaned 1 exits)","file_path":"data/rooms/intro/1008.yaml","old_content":"id: 1008\nname: New Room\ncolor: A9\ndescription:\n - text: A featureless room.\nexits:\n north:\n room: 7\n south:\n room: 2003\nobjects: []\nitem_spawns: []\nmobs: []\non_enter: []\nhazard: \"\"\nblock_transport: false\ntriggers: []\n","new_content":"","is_delete":true,"is_create":false},{"time":"2026-06-30T14:32:29-04:00","description":"update room 2003 (add exit north to 1005)","file_path":"data/rooms/intro/2003.yaml","old_content":"id: 2003\nname: Test Room\ncolor: \"\"\ndescription:\n - text: It's a test room\nexits:\n south:\n room: 2004\n southwest:\n room: 2005\n west:\n room: 2002\nobjects: []\nitem_spawns: []\nmobs: []\non_enter: []\nhazard: \"\"\nblock_transport: false\ntriggers: []\n","new_content":"id: 2003\nname: Test Room\ncolor: \"\"\ndescription:\n - text: It's a test room\nexits:\n north:\n room: 1005\n south:\n room: 2004\n southwest:\n room: 2005\n west:\n room: 2002\nobjects: []\nitem_spawns: []\nmobs: []\non_enter: []\nhazard: \"\"\nblock_transport: false\ntriggers: []\n","is_delete":false,"is_create":false},{"time":"2026-06-30T14:32:29-04:00","description":"create room 1005","file_path":"data/rooms/intro/1005.yaml","old_content":"","new_content":"exits:\n south: 2003\nid: 1005\nname: 'Room #1005'\n","is_delete":false,"is_create":true},{"time":"2026-06-30T14:32:30-04:00","description":"update room 1005 (add exit east to 1006)","file_path":"data/rooms/intro/1005.yaml","old_content":"exits:\n south: 2003\nid: 1005\nname: 'Room #1005'\n","new_content":"id: 1005\nname: 'Room #1005'\ncolor: \"\"\ndescription: []\nexits:\n east:\n room: 1006\n south:\n room: 2003\nobjects: []\nitem_spawns: []\nmobs: []\non_enter: []\nhazard: \"\"\nblock_transport: false\ntriggers: []\n","is_delete":false,"is_create":false},{"time":"2026-06-30T14:32:30-04:00","description":"create room 1006","file_path":"data/rooms/intro/1006.yaml","old_content":"","new_content":"exits:\n west: 1005\nid: 1006\nname: 'Room #1006'\n","is_delete":false,"is_create":true},{"time":"2026-06-30T14:32:31-04:00","description":"update room 1006 (add exit south to 1007)","file_path":"data/rooms/intro/1006.yaml","old_content":"exits:\n west: 1005\nid: 1006\nname: 'Room #1006'\n","new_content":"id: 1006\nname: 'Room #1006'\ncolor: \"\"\ndescription: []\nexits:\n south:\n room: 1007\n west:\n room: 1005\nobjects: []\nitem_spawns: []\nmobs: []\non_enter: []\nhazard: \"\"\nblock_transport: false\ntriggers: []\n","is_delete":false,"is_create":false},{"time":"2026-06-30T14:32:31-04:00","description":"create room 1007","file_path":"data/rooms/intro/1007.yaml","old_content":"","new_content":"exits:\n north: 1006\nid: 1007\nname: 'Room #1007'\n","is_delete":false,"is_create":true},{"time":"2026-06-30T14:32:32-04:00","description":"update room 1007 (add exit east to 1008)","file_path":"data/rooms/intro/1007.yaml","old_content":"exits:\n north: 1006\nid: 1007\nname: 'Room #1007'\n","new_content":"id: 1007\nname: 'Room #1007'\ncolor: \"\"\ndescription: []\nexits:\n east:\n room: 1008\n north:\n room: 1006\nobjects: []\nitem_spawns: []\nmobs: []\non_enter: []\nhazard: \"\"\nblock_transport: false\ntriggers: []\n","is_delete":false,"is_create":false},{"time":"2026-06-30T14:32:32-04:00","description":"create room 1008","file_path":"data/rooms/intro/1008.yaml","old_content":"","new_content":"exits:\n west: 1007\nid: 1008\nname: 'Room #1008'\n","is_delete":false,"is_create":true},{"time":"2026-06-30T14:32:32-04:00","description":"update room 1008 (add exit north to 1009)","file_path":"data/rooms/intro/1008.yaml","old_content":"exits:\n west: 1007\nid: 1008\nname: 'Room #1008'\n","new_content":"id: 1008\nname: 'Room #1008'\ncolor: \"\"\ndescription: []\nexits:\n north:\n room: 1009\n west:\n room: 1007\nobjects: []\nitem_spawns: []\nmobs: []\non_enter: []\nhazard: \"\"\nblock_transport: false\ntriggers: []\n","is_delete":false,"is_create":false},{"time":"2026-06-30T14:32:32-04:00","description":"create room 1009","file_path":"data/rooms/intro/1009.yaml","old_content":"","new_content":"exits:\n south: 1008\nid: 1009\nname: 'Room #1009'\n","is_delete":false,"is_create":true},{"time":"2026-06-30T14:32:33-04:00","description":"update room 1009 (add exit north to 1010)","file_path":"data/rooms/intro/1009.yaml","old_content":"exits:\n south: 1008\nid: 1009\nname: 'Room #1009'\n","new_content":"id: 1009\nname: 'Room #1009'\ncolor: \"\"\ndescription: []\nexits:\n north:\n room: 1010\n south:\n room: 1008\nobjects: []\nitem_spawns: []\nmobs: []\non_enter: []\nhazard: \"\"\nblock_transport: false\ntriggers: []\n","is_delete":false,"is_create":false},{"time":"2026-06-30T14:32:33-04:00","description":"create room 1010","file_path":"data/rooms/intro/1010.yaml","old_content":"","new_content":"exits:\n south: 1009\nid: 1010\nname: 'Room #1010'\n","is_delete":false,"is_create":true},{"time":"2026-06-30T14:32:33-04:00","description":"update room 1010 (add exit east to 1011)","file_path":"data/rooms/intro/1010.yaml","old_content":"exits:\n south: 1009\nid: 1010\nname: 'Room #1010'\n","new_content":"id: 1010\nname: 'Room #1010'\ncolor: \"\"\ndescription: []\nexits:\n east:\n room: 1011\n south:\n room: 1009\nobjects: []\nitem_spawns: []\nmobs: []\non_enter: []\nhazard: \"\"\nblock_transport: false\ntriggers: []\n","is_delete":false,"is_create":false},{"time":"2026-06-30T14:32:33-04:00","description":"create room 1011","file_path":"data/rooms/intro/1011.yaml","old_content":"","new_content":"exits:\n west: 1010\nid: 1011\nname: 'Room #1011'\n","is_delete":false,"is_create":true},{"time":"2026-06-30T14:32:34-04:00","description":"update room 1011 (add exit south to 1012)","file_path":"data/rooms/intro/1011.yaml","old_content":"exits:\n west: 1010\nid: 1011\nname: 'Room #1011'\n","new_content":"id: 1011\nname: 'Room #1011'\ncolor: \"\"\ndescription: []\nexits:\n south:\n room: 1012\n west:\n room: 1010\nobjects: []\nitem_spawns: []\nmobs: []\non_enter: []\nhazard: \"\"\nblock_transport: false\ntriggers: []\n","is_delete":false,"is_create":false},{"time":"2026-06-30T14:32:34-04:00","description":"create room 1012","file_path":"data/rooms/intro/1012.yaml","old_content":"","new_content":"exits:\n north: 1011\nid: 1012\nname: 'Room #1012'\n","is_delete":false,"is_create":true},{"time":"2026-06-30T14:32:34-04:00","description":"update room 1012 (add exit south to 1013)","file_path":"data/rooms/intro/1012.yaml","old_content":"exits:\n north: 1011\nid: 1012\nname: 'Room #1012'\n","new_content":"id: 1012\nname: 'Room #1012'\ncolor: \"\"\ndescription: []\nexits:\n north:\n room: 1011\n south:\n room: 1013\nobjects: []\nitem_spawns: []\nmobs: []\non_enter: []\nhazard: \"\"\nblock_transport: false\ntriggers: []\n","is_delete":false,"is_create":false},{"time":"2026-06-30T14:32:34-04:00","description":"create room 1013","file_path":"data/rooms/intro/1013.yaml","old_content":"","new_content":"exits:\n north: 1012\nid: 1013\nname: 'Room #1013'\n","is_delete":false,"is_create":true},{"time":"2026-06-30T14:32:35-04:00","description":"delete room 1013 (cleaned 1 exits)","file_path":"data/rooms/intro/1013.yaml","old_content":"exits:\n north: 1012\nid: 1013\nname: 'Room #1013'\n","new_content":"","is_delete":true,"is_create":false},{"time":"2026-06-30T14:32:36-04:00","description":"delete room 1012 (cleaned 1 exits)","file_path":"data/rooms/intro/1012.yaml","old_content":"id: 1012\nname: 'Room #1012'\ncolor: \"\"\ndescription: []\nexits:\n north:\n room: 1011\nobjects: []\nitem_spawns: []\nmobs: []\non_enter: []\nhazard: \"\"\nblock_transport: false\ntriggers: []\n","new_content":"","is_delete":true,"is_create":false},{"time":"2026-06-30T14:32:37-04:00","description":"delete room 1011 (cleaned 1 exits)","file_path":"data/rooms/intro/1011.yaml","old_content":"id: 1011\nname: 'Room #1011'\ncolor: \"\"\ndescription: []\nexits:\n west:\n room: 1010\nobjects: []\nitem_spawns: []\nmobs: []\non_enter: []\nhazard: \"\"\nblock_transport: false\ntriggers: []\n","new_content":"","is_delete":true,"is_create":false},{"time":"2026-06-30T14:32:37-04:00","description":"delete room 1010 (cleaned 1 exits)","file_path":"data/rooms/intro/1010.yaml","old_content":"id: 1010\nname: 'Room #1010'\ncolor: \"\"\ndescription: []\nexits:\n south:\n room: 1009\nobjects: []\nitem_spawns: []\nmobs: []\non_enter: []\nhazard: \"\"\nblock_transport: false\ntriggers: []\n","new_content":"","is_delete":true,"is_create":false},{"time":"2026-06-30T14:32:38-04:00","description":"delete room 1009 (cleaned 1 exits)","file_path":"data/rooms/intro/1009.yaml","old_content":"id: 1009\nname: 'Room #1009'\ncolor: \"\"\ndescription: []\nexits:\n south:\n room: 1008\nobjects: []\nitem_spawns: []\nmobs: []\non_enter: []\nhazard: \"\"\nblock_transport: false\ntriggers: []\n","new_content":"","is_delete":true,"is_create":false},{"time":"2026-06-30T14:32:39-04:00","description":"delete room 1008 (cleaned 1 exits)","file_path":"data/rooms/intro/1008.yaml","old_content":"id: 1008\nname: 'Room #1008'\ncolor: \"\"\ndescription: []\nexits:\n west:\n room: 1007\nobjects: []\nitem_spawns: []\nmobs: []\non_enter: []\nhazard: \"\"\nblock_transport: false\ntriggers: []\n","new_content":"","is_delete":true,"is_create":false},{"time":"2026-06-30T14:32:40-04:00","description":"delete room 1007 (cleaned 1 exits)","file_path":"data/rooms/intro/1007.yaml","old_content":"id: 1007\nname: 'Room #1007'\ncolor: \"\"\ndescription: []\nexits:\n north:\n room: 1006\nobjects: []\nitem_spawns: []\nmobs: []\non_enter: []\nhazard: \"\"\nblock_transport: false\ntriggers: []\n","new_content":"","is_delete":true,"is_create":false},{"time":"2026-06-30T14:32:40-04:00","description":"delete room 1006 (cleaned 1 exits)","file_path":"data/rooms/intro/1006.yaml","old_content":"id: 1006\nname: 'Room #1006'\ncolor: \"\"\ndescription: []\nexits:\n west:\n room: 1005\nobjects: []\nitem_spawns: []\nmobs: []\non_enter: []\nhazard: \"\"\nblock_transport: false\ntriggers: []\n","new_content":"","is_delete":true,"is_create":false},{"time":"2026-06-30T14:32:41-04:00","description":"delete room 1005 (cleaned 1 exits)","file_path":"data/rooms/intro/1005.yaml","old_content":"id: 1005\nname: 'Room #1005'\ncolor: \"\"\ndescription: []\nexits:\n south:\n room: 2003\nobjects: []\nitem_spawns: []\nmobs: []\non_enter: []\nhazard: \"\"\nblock_transport: false\ntriggers: []\n","new_content":"","is_delete":true,"is_create":false},{"time":"2026-06-30T15:05:42-04:00","description":"update room 1001","file_path":"data/rooms/intro/1001.yaml","old_content":"id: 1001\nname: Inside Transport Shuttle\ncolor: \"\"\ndescription:\n - text: |-\n A dim, windowless shuttle interior with a few uncomfortable rows of steel seats facing forward. A large framed sign hangs next to the closed cockpit door. The piston-powered staircase is firmly closed at the rear of the craft.\n\n A dim, windowless shuttle interior with a few uncomfortable rows of steel seats facing forward. A large {11}framed sign{/} hangs next to the closed cockpit door. A piston-powered staircase leads down out the back of the small craft with a smiling attendant ready to help disembark.\nexits:\n down:\n room: 1002\n condition:\n flag: \"\"\n value: null\n not: false\n player_flag: 1001_touchdown\n has_item: \"\"\n min_credits: 0\n all_of: []\n any_of: []\n blocked_message: The piston-powered staircase is firmly closed.\n east:\n room: 2001\nobjects:\n - name: framed sign\n hidden: true\n description:\n - text: \"We hope you enjoy your trip on our shuttle! Your pilot is [TYLER].\\n\\nWhen you arrive at your final destination, please be aware of the following basic commands:\\n\\n{0B bold}Movement:{/} {0A}north{/}, {0A}south{/}, {0A}east{/}, {0A}west{/}, {0A}up{/}, {0A}down{/}\\n{0B bold}Look:{/} {0A}look{/}, {0A}look \u003citem/object/mob\u003e{/}, and {0A}map{/}\\n{0B bold}Items:{/} {0A}inv{/} to see your 28-slot inventory\\n {0A}get \u003citem\u003e{/}, {0A}drop \u003citem\u003e{/}, {0A}wear \u003citem\u003e{/}, {0A}remove \u003citem\u003e{/}\\n {0A}use \u003citem\u003e on \u003citem/object\u003e{/}\\n {0A}eq{/} for equiped gear\\n{0B bold}Comms:{/} {0A}talk \u003cmob\u003e{/} for NPC chat\\n {0A}say \u003cmsg\u003e{/} and {0A}global \u003cmsg\u003e{/} for human chat\\n{0B bold}Character:{/} {0A}score{/} and {0A}skills{/} for stats. \\n{0B bold}Combat{/} {0A}attack \u003cmob\u003e{/}\\n{0B bold}Skills{/} Many skills have shortcuts like {0A}mine{/}, {0A}fish{/}, or {0A}chop{/}\\n{0B bold}Options{/} {0A}options{/} for a list of account options\\n {0A}options \u003copt\u003e \u003cvalue\u003e{/} to change an option\\n\\nType {0C bold}what{/} for a list of possible common actions\\n\\nMake sure to check the {0A}help{/} pages, especially {0A}help newplayer{/}!\"\n on_look:\n set_flags: {}\n set_player_flags:\n 1001_look_sign: true\n give_item: \"\"\n take_item: \"\"\n teleport: 0\n heal: 0\n cost: 0\n shop: null\n assign_task: false\n skip_task: false\n extend_task: false\n reputation_cost: 0\n sawmill: false\n aps_node: false\n - name: door\n hidden: true\n description:\n - text: A sturdy, locked steel door that keeps passengers out of the cockpit. There is a tiny, thin window at eye level.\n - name: window\n hidden: true\n description:\n - text: A thick trim with rounded bolt heads frames the tiny window. It looks like it was cut into the door at some point, potentially as a simple replacement to computerized security systems. Inside the cockpit there's a pilot finishing up landing procedures on a large panel of analog instruments.\n - name: instrument panel\n aliases:\n - cockpit\n hidden: true\n description:\n - text: The cramped cockpit is surrounded by buttons, swiches, dials, and analog gauges. The parts are a mix of technologies from the last century. Part of the panel is obscured by a draped cloth as if to hide it from view. Odd.\n - name: pilot\n hidden: true\n description:\n - text: That's the guy who took you from the Passenger Barge Denali down here to Vesta. A middle-aged man in a neat white jumpsuit with a matching white sort of conductor's hat. He's following a written procedure checklist and seems to take his job seriously.\nitem_spawns: []\nmobs:\n - id: flight_attendant\non_enter:\n - message: '{0B bold}Welcome to The House of Icarus{/}'\n condition:\n flag: \"\"\n value: null\n not: true\n player_flag: 1001_welcome\n has_item: \"\"\n min_credits: 0\n all_of: []\n any_of: []\n delay: 5\n set_flags: {}\n set_player_flags: {}\n broadcast: \"\"\n broadcast_global: \"\"\n spawn_mob: null\n despawn_mob: \"\"\n give_item: \"\"\n take_item: \"\"\n teleport: 0\n heal: 0\n - message: '{0B}Type{/} {0A}look sign{/} {0B}or{/} {0A}talk attendant{/} {0B}to get started{/}'\n condition:\n flag: \"\"\n value: null\n not: true\n player_flag: 1001_welcome\n has_item: \"\"\n min_credits: 0\n all_of: []\n any_of: []\n delay: 7\n set_flags: {}\n set_player_flags:\n 1001_welcome: true\n broadcast: \"\"\n broadcast_global: \"\"\n spawn_mob: null\n despawn_mob: \"\"\n give_item: \"\"\n take_item: \"\"\n teleport: 0\n heal: 0\n - message: '{0B}Type{/} {0A}help newplayer{/} {0B}for the new player''s guide. That''s it. Explore and have fun.{/}'\n condition:\n flag: \"\"\n value: null\n not: true\n player_flag: 1001_welcome\n has_item: \"\"\n min_credits: 0\n all_of: []\n any_of: []\n delay: 7\n set_flags: {}\n set_player_flags: {}\n broadcast: \"\"\n broadcast_global: \"\"\n spawn_mob: null\n despawn_mob: \"\"\n give_item: \"\"\n take_item: \"\"\n teleport: 0\n heal: 0\nhazard: \"\"\nblock_transport: true\ntriggers:\n - id: \"\"\n on_player_flag: 1001_look_sign\n on_flag: \"\"\n value: null\n room: 0\n steps:\n - delay: 5\n message: The cabin shakes as the small craft touches down\n broadcast: \"\"\n broadcast_global: \"\"\n set_flags: {}\n set_player_flags: {}\n spawn_mob: null\n give_item: \"\"\n take_item: \"\"\n teleport: 0\n heal: 0\n despawn_mob: \"\"\n - delay: 5\n message: The pistons hiss as the rear staircase opens\n broadcast: \"\"\n broadcast_global: \"\"\n set_flags: {}\n set_player_flags: {}\n spawn_mob: null\n give_item: \"\"\n take_item: \"\"\n teleport: 0\n heal: 0\n despawn_mob: \"\"\n - delay: 0\n message: \"\"\n broadcast: \"\"\n broadcast_global: \"\"\n set_flags: {}\n set_player_flags:\n 1001_touchdown: true\n spawn_mob: null\n give_item: \"\"\n take_item: \"\"\n teleport: 0\n heal: 0\n despawn_mob: \"\"\n","new_content":"block_transport: true\ncolor: \"\"\ndescription:\n - text: |-\n A dim, windowless shuttle interior with a few uncomfortable rows of steel seats facing forward. A large framed sign hangs next to the closed cockpit door. The piston-powered staircase is firmly closed at the rear of the craft.\n\n A dim, windowless shuttle interior with a few uncomfortable rows of steel seats facing forward. A large {11}framed sign{/} hangs next to the closed cockpit door. A piston-powered staircase leads down out the back of the small craft with a smiling attendant ready to help disembark.\nexits:\n down:\n blocked_message: The piston-powered staircase is firmly closed.\n condition:\n all_of: []\n any_of: []\n flag: \"\"\n has_item: \"\"\n min_credits: 0\n not: false\n player_flag: 1001_touchdown\n value: null\n room: 1002\n east:\n room: 2001\nhazard: \"\"\nid: 1001\nitem_spawns: []\nmobs:\n - id: flight_attendant\nname: Inside Transport Shuttle\nobjects:\n - description:\n - text: \"We hope you enjoy your trip on our shuttle! Your pilot is [TYLER].\\n\\nWhen you arrive at your final destination, please be aware of the following basic commands:\\n\\n{0B bold}Movement:{/} {0A}north{/}, {0A}south{/}, {0A}east{/}, {0A}west{/}, {0A}up{/}, {0A}down{/}\\n{0B bold}Look:{/} {0A}look{/}, {0A}look \u003citem/object/mob\u003e{/}, and {0A}map{/}\\n{0B bold}Items:{/} {0A}inv{/} to see your 28-slot inventory\\n {0A}get \u003citem\u003e{/}, {0A}drop \u003citem\u003e{/}, {0A}wear \u003citem\u003e{/}, {0A}remove \u003citem\u003e{/}\\n {0A}use \u003citem\u003e on \u003citem/object\u003e{/}\\n {0A}eq{/} for equiped gear\\n{0B bold}Comms:{/} {0A}talk \u003cmob\u003e{/} for NPC chat\\n {0A}say \u003cmsg\u003e{/} and {0A}global \u003cmsg\u003e{/} for human chat\\n{0B bold}Character:{/} {0A}score{/} and {0A}skills{/} for stats. \\n{0B bold}Combat{/} {0A}attack \u003cmob\u003e{/}\\n{0B bold}Skills{/} Many skills have shortcuts like {0A}mine{/}, {0A}fish{/}, or {0A}chop{/}\\n{0B bold}Options{/} {0A}options{/} for a list of account options\\n {0A}options \u003copt\u003e \u003cvalue\u003e{/} to change an option\\n\\nType {0C bold}what{/} for a list of possible common actions\\n\\nMake sure to check the {0A}help{/} pages, especially {0A}help newplayer{/}!\"\n hidden: true\n name: framed sign\n on_look:\n aps_node: false\n assign_task: false\n cost: 0\n extend_task: false\n give_item: \"\"\n heal: 0\n reputation_cost: 0\n sawmill: false\n set_flags: {}\n set_player_flags:\n 1001_look_sign: true\n shop: null\n skip_task: false\n take_item: \"\"\n teleport: 0\n - description:\n - text: A sturdy, locked steel door that keeps passengers out of the cockpit. There is a tiny, thin window at eye level.\n hidden: true\n name: door\n - description:\n - text: A thick trim with rounded bolt heads frames the tiny window. It looks like it was cut into the door at some point, potentially as a simple replacement to computerized security systems. Inside the cockpit there's a pilot finishing up landing procedures on a large panel of analog instruments.\n hidden: true\n name: window\n - aliases:\n - cockpit\n description:\n - text: The cramped cockpit is surrounded by buttons, swiches, dials, and analog gauges. The parts are a mix of technologies from the last century. Part of the panel is obscured by a draped cloth as if to hide it from view. Odd.\n hidden: true\n name: instrument panel\n - aliases: []\n description:\n - text: That's the guy who took you from the Passenger Barge Denali down here to Vesta. A middle-aged man in a neat white jumpsuit with a matching white sort of conductor's hat. He's following a written procedure checklist and seems to take his job seriously.\n hidden: false\n name: pilot\non_enter:\n - broadcast: \"\"\n broadcast_global: \"\"\n condition:\n all_of: []\n any_of: []\n flag: \"\"\n has_item: \"\"\n min_credits: 0\n not: true\n player_flag: 1001_welcome\n value: null\n delay: 5\n despawn_mob: \"\"\n give_item: \"\"\n heal: 0\n message: '{0B bold}Welcome to The House of Icarus{/}'\n set_flags: {}\n set_player_flags: {}\n spawn_mob: null\n take_item: \"\"\n teleport: 0\n - broadcast: \"\"\n broadcast_global: \"\"\n condition:\n all_of: []\n any_of: []\n flag: \"\"\n has_item: \"\"\n min_credits: 0\n not: true\n player_flag: 1001_welcome\n value: null\n delay: 7\n despawn_mob: \"\"\n give_item: \"\"\n heal: 0\n message: '{0B}Type{/} {0A}look sign{/} {0B}or{/} {0A}talk attendant{/} {0B}to get started{/}'\n set_flags: {}\n set_player_flags:\n 1001_welcome: true\n spawn_mob: null\n take_item: \"\"\n teleport: 0\n - broadcast: \"\"\n broadcast_global: \"\"\n condition:\n all_of: []\n any_of: []\n flag: \"\"\n has_item: \"\"\n min_credits: 0\n not: true\n player_flag: 1001_welcome\n value: null\n delay: 7\n despawn_mob: \"\"\n give_item: \"\"\n heal: 0\n message: '{0B}Type{/} {0A}help newplayer{/} {0B}for the new player''s guide. That''s it. Explore and have fun.{/}'\n set_flags: {}\n set_player_flags: {}\n spawn_mob: null\n take_item: \"\"\n teleport: 0\ntriggers:\n - id: \"\"\n on_flag: \"\"\n on_player_flag: 1001_look_sign\n room: 0\n steps:\n - broadcast: \"\"\n broadcast_global: \"\"\n delay: 5\n despawn_mob: \"\"\n give_item: \"\"\n heal: 0\n message: The cabin shakes as the small craft touches down\n set_flags: {}\n set_player_flags: {}\n spawn_mob: null\n take_item: \"\"\n teleport: 0\n - broadcast: \"\"\n broadcast_global: \"\"\n delay: 5\n despawn_mob: \"\"\n give_item: \"\"\n heal: 0\n message: The pistons hiss as the rear staircase opens\n set_flags: {}\n set_player_flags: {}\n spawn_mob: null\n take_item: \"\"\n teleport: 0\n - broadcast: \"\"\n broadcast_global: \"\"\n delay: 0\n despawn_mob: \"\"\n give_item: \"\"\n heal: 0\n message: \"\"\n set_flags: {}\n set_player_flags:\n 1001_touchdown: true\n spawn_mob: null\n take_item: \"\"\n teleport: 0\n value: null\n","is_delete":false,"is_create":false},{"time":"2026-06-30T15:05:43-04:00","description":"update room 1001","file_path":"data/rooms/intro/1001.yaml","old_content":"block_transport: true\ncolor: \"\"\ndescription:\n - text: |-\n A dim, windowless shuttle interior with a few uncomfortable rows of steel seats facing forward. A large framed sign hangs next to the closed cockpit door. The piston-powered staircase is firmly closed at the rear of the craft.\n\n A dim, windowless shuttle interior with a few uncomfortable rows of steel seats facing forward. A large {11}framed sign{/} hangs next to the closed cockpit door. A piston-powered staircase leads down out the back of the small craft with a smiling attendant ready to help disembark.\nexits:\n down:\n blocked_message: The piston-powered staircase is firmly closed.\n condition:\n all_of: []\n any_of: []\n flag: \"\"\n has_item: \"\"\n min_credits: 0\n not: false\n player_flag: 1001_touchdown\n value: null\n room: 1002\n east:\n room: 2001\nhazard: \"\"\nid: 1001\nitem_spawns: []\nmobs:\n - id: flight_attendant\nname: Inside Transport Shuttle\nobjects:\n - description:\n - text: \"We hope you enjoy your trip on our shuttle! Your pilot is [TYLER].\\n\\nWhen you arrive at your final destination, please be aware of the following basic commands:\\n\\n{0B bold}Movement:{/} {0A}north{/}, {0A}south{/}, {0A}east{/}, {0A}west{/}, {0A}up{/}, {0A}down{/}\\n{0B bold}Look:{/} {0A}look{/}, {0A}look \u003citem/object/mob\u003e{/}, and {0A}map{/}\\n{0B bold}Items:{/} {0A}inv{/} to see your 28-slot inventory\\n {0A}get \u003citem\u003e{/}, {0A}drop \u003citem\u003e{/}, {0A}wear \u003citem\u003e{/}, {0A}remove \u003citem\u003e{/}\\n {0A}use \u003citem\u003e on \u003citem/object\u003e{/}\\n {0A}eq{/} for equiped gear\\n{0B bold}Comms:{/} {0A}talk \u003cmob\u003e{/} for NPC chat\\n {0A}say \u003cmsg\u003e{/} and {0A}global \u003cmsg\u003e{/} for human chat\\n{0B bold}Character:{/} {0A}score{/} and {0A}skills{/} for stats. \\n{0B bold}Combat{/} {0A}attack \u003cmob\u003e{/}\\n{0B bold}Skills{/} Many skills have shortcuts like {0A}mine{/}, {0A}fish{/}, or {0A}chop{/}\\n{0B bold}Options{/} {0A}options{/} for a list of account options\\n {0A}options \u003copt\u003e \u003cvalue\u003e{/} to change an option\\n\\nType {0C bold}what{/} for a list of possible common actions\\n\\nMake sure to check the {0A}help{/} pages, especially {0A}help newplayer{/}!\"\n hidden: true\n name: framed sign\n on_look:\n aps_node: false\n assign_task: false\n cost: 0\n extend_task: false\n give_item: \"\"\n heal: 0\n reputation_cost: 0\n sawmill: false\n set_flags: {}\n set_player_flags:\n 1001_look_sign: true\n shop: null\n skip_task: false\n take_item: \"\"\n teleport: 0\n - description:\n - text: A sturdy, locked steel door that keeps passengers out of the cockpit. There is a tiny, thin window at eye level.\n hidden: true\n name: door\n - description:\n - text: A thick trim with rounded bolt heads frames the tiny window. It looks like it was cut into the door at some point, potentially as a simple replacement to computerized security systems. Inside the cockpit there's a pilot finishing up landing procedures on a large panel of analog instruments.\n hidden: true\n name: window\n - aliases:\n - cockpit\n description:\n - text: The cramped cockpit is surrounded by buttons, swiches, dials, and analog gauges. The parts are a mix of technologies from the last century. Part of the panel is obscured by a draped cloth as if to hide it from view. Odd.\n hidden: true\n name: instrument panel\n - aliases: []\n description:\n - text: That's the guy who took you from the Passenger Barge Denali down here to Vesta. A middle-aged man in a neat white jumpsuit with a matching white sort of conductor's hat. He's following a written procedure checklist and seems to take his job seriously.\n hidden: false\n name: pilot\non_enter:\n - broadcast: \"\"\n broadcast_global: \"\"\n condition:\n all_of: []\n any_of: []\n flag: \"\"\n has_item: \"\"\n min_credits: 0\n not: true\n player_flag: 1001_welcome\n value: null\n delay: 5\n despawn_mob: \"\"\n give_item: \"\"\n heal: 0\n message: '{0B bold}Welcome to The House of Icarus{/}'\n set_flags: {}\n set_player_flags: {}\n spawn_mob: null\n take_item: \"\"\n teleport: 0\n - broadcast: \"\"\n broadcast_global: \"\"\n condition:\n all_of: []\n any_of: []\n flag: \"\"\n has_item: \"\"\n min_credits: 0\n not: true\n player_flag: 1001_welcome\n value: null\n delay: 7\n despawn_mob: \"\"\n give_item: \"\"\n heal: 0\n message: '{0B}Type{/} {0A}look sign{/} {0B}or{/} {0A}talk attendant{/} {0B}to get started{/}'\n set_flags: {}\n set_player_flags:\n 1001_welcome: true\n spawn_mob: null\n take_item: \"\"\n teleport: 0\n - broadcast: \"\"\n broadcast_global: \"\"\n condition:\n all_of: []\n any_of: []\n flag: \"\"\n has_item: \"\"\n min_credits: 0\n not: true\n player_flag: 1001_welcome\n value: null\n delay: 7\n despawn_mob: \"\"\n give_item: \"\"\n heal: 0\n message: '{0B}Type{/} {0A}help newplayer{/} {0B}for the new player''s guide. That''s it. Explore and have fun.{/}'\n set_flags: {}\n set_player_flags: {}\n spawn_mob: null\n take_item: \"\"\n teleport: 0\ntriggers:\n - id: \"\"\n on_flag: \"\"\n on_player_flag: 1001_look_sign\n room: 0\n steps:\n - broadcast: \"\"\n broadcast_global: \"\"\n delay: 5\n despawn_mob: \"\"\n give_item: \"\"\n heal: 0\n message: The cabin shakes as the small craft touches down\n set_flags: {}\n set_player_flags: {}\n spawn_mob: null\n take_item: \"\"\n teleport: 0\n - broadcast: \"\"\n broadcast_global: \"\"\n delay: 5\n despawn_mob: \"\"\n give_item: \"\"\n heal: 0\n message: The pistons hiss as the rear staircase opens\n set_flags: {}\n set_player_flags: {}\n spawn_mob: null\n take_item: \"\"\n teleport: 0\n - broadcast: \"\"\n broadcast_global: \"\"\n delay: 0\n despawn_mob: \"\"\n give_item: \"\"\n heal: 0\n message: \"\"\n set_flags: {}\n set_player_flags:\n 1001_touchdown: true\n spawn_mob: null\n take_item: \"\"\n teleport: 0\n value: null\n","new_content":"block_transport: true\ncolor: \"\"\ndescription:\n - text: |-\n A dim, windowless shuttle interior with a few uncomfortable rows of steel seats facing forward. A large framed sign hangs next to the closed cockpit door. The piston-powered staircase is firmly closed at the rear of the craft.\n\n A dim, windowless shuttle interior with a few uncomfortable rows of steel seats facing forward. A large {11}framed sign{/} hangs next to the closed cockpit door. A piston-powered staircase leads down out the back of the small craft with a smiling attendant ready to help disembark.\nexits:\n down:\n blocked_message: The piston-powered staircase is firmly closed.\n condition:\n all_of: []\n any_of: []\n flag: \"\"\n has_item: \"\"\n min_credits: 0\n not: false\n player_flag: 1001_touchdown\n value: null\n room: 1002\n east:\n room: 2001\nhazard: \"\"\nid: 1001\nitem_spawns: []\nmobs:\n - id: flight_attendant\nname: Inside Transport Shuttle\nobjects:\n - description:\n - text: \"We hope you enjoy your trip on our shuttle! Your pilot is [TYLER].\\n\\nWhen you arrive at your final destination, please be aware of the following basic commands:\\n\\n{0B bold}Movement:{/} {0A}north{/}, {0A}south{/}, {0A}east{/}, {0A}west{/}, {0A}up{/}, {0A}down{/}\\n{0B bold}Look:{/} {0A}look{/}, {0A}look \u003citem/object/mob\u003e{/}, and {0A}map{/}\\n{0B bold}Items:{/} {0A}inv{/} to see your 28-slot inventory\\n {0A}get \u003citem\u003e{/}, {0A}drop \u003citem\u003e{/}, {0A}wear \u003citem\u003e{/}, {0A}remove \u003citem\u003e{/}\\n {0A}use \u003citem\u003e on \u003citem/object\u003e{/}\\n {0A}eq{/} for equiped gear\\n{0B bold}Comms:{/} {0A}talk \u003cmob\u003e{/} for NPC chat\\n {0A}say \u003cmsg\u003e{/} and {0A}global \u003cmsg\u003e{/} for human chat\\n{0B bold}Character:{/} {0A}score{/} and {0A}skills{/} for stats. \\n{0B bold}Combat{/} {0A}attack \u003cmob\u003e{/}\\n{0B bold}Skills{/} Many skills have shortcuts like {0A}mine{/}, {0A}fish{/}, or {0A}chop{/}\\n{0B bold}Options{/} {0A}options{/} for a list of account options\\n {0A}options \u003copt\u003e \u003cvalue\u003e{/} to change an option\\n\\nType {0C bold}what{/} for a list of possible common actions\\n\\nMake sure to check the {0A}help{/} pages, especially {0A}help newplayer{/}!\"\n hidden: true\n name: framed sign\n on_look:\n aps_node: false\n assign_task: false\n cost: 0\n extend_task: false\n give_item: \"\"\n heal: 0\n reputation_cost: 0\n sawmill: false\n set_flags: {}\n set_player_flags:\n 1001_look_sign: true\n shop: null\n skip_task: false\n take_item: \"\"\n teleport: 0\n - description:\n - text: A sturdy, locked steel door that keeps passengers out of the cockpit. There is a tiny, thin window at eye level.\n hidden: true\n name: door\n - description:\n - text: A thick trim with rounded bolt heads frames the tiny window. It looks like it was cut into the door at some point, potentially as a simple replacement to computerized security systems. Inside the cockpit there's a pilot finishing up landing procedures on a large panel of analog instruments.\n hidden: true\n name: window\n - aliases:\n - cockpit\n description:\n - text: The cramped cockpit is surrounded by buttons, swiches, dials, and analog gauges. The parts are a mix of technologies from the last century. Part of the panel is obscured by a draped cloth as if to hide it from view. Odd.\n hidden: true\n name: instrument panel\n - aliases: []\n description:\n - text: That's the guy who took you from the Passenger Barge Denali down here to Vesta. A middle-aged man in a neat white jumpsuit with a matching white sort of conductor's hat. He's following a written procedure checklist and seems to take his job seriously.\n hidden: true\n name: pilot\non_enter:\n - broadcast: \"\"\n broadcast_global: \"\"\n condition:\n all_of: []\n any_of: []\n flag: \"\"\n has_item: \"\"\n min_credits: 0\n not: true\n player_flag: 1001_welcome\n value: null\n delay: 5\n despawn_mob: \"\"\n give_item: \"\"\n heal: 0\n message: '{0B bold}Welcome to The House of Icarus{/}'\n set_flags: {}\n set_player_flags: {}\n spawn_mob: null\n take_item: \"\"\n teleport: 0\n - broadcast: \"\"\n broadcast_global: \"\"\n condition:\n all_of: []\n any_of: []\n flag: \"\"\n has_item: \"\"\n min_credits: 0\n not: true\n player_flag: 1001_welcome\n value: null\n delay: 7\n despawn_mob: \"\"\n give_item: \"\"\n heal: 0\n message: '{0B}Type{/} {0A}look sign{/} {0B}or{/} {0A}talk attendant{/} {0B}to get started{/}'\n set_flags: {}\n set_player_flags:\n 1001_welcome: true\n spawn_mob: null\n take_item: \"\"\n teleport: 0\n - broadcast: \"\"\n broadcast_global: \"\"\n condition:\n all_of: []\n any_of: []\n flag: \"\"\n has_item: \"\"\n min_credits: 0\n not: true\n player_flag: 1001_welcome\n value: null\n delay: 7\n despawn_mob: \"\"\n give_item: \"\"\n heal: 0\n message: '{0B}Type{/} {0A}help newplayer{/} {0B}for the new player''s guide. That''s it. Explore and have fun.{/}'\n set_flags: {}\n set_player_flags: {}\n spawn_mob: null\n take_item: \"\"\n teleport: 0\ntriggers:\n - id: \"\"\n on_flag: \"\"\n on_player_flag: 1001_look_sign\n room: 0\n steps:\n - broadcast: \"\"\n broadcast_global: \"\"\n delay: 5\n despawn_mob: \"\"\n give_item: \"\"\n heal: 0\n message: The cabin shakes as the small craft touches down\n set_flags: {}\n set_player_flags: {}\n spawn_mob: null\n take_item: \"\"\n teleport: 0\n - broadcast: \"\"\n broadcast_global: \"\"\n delay: 5\n despawn_mob: \"\"\n give_item: \"\"\n heal: 0\n message: The pistons hiss as the rear staircase opens\n set_flags: {}\n set_player_flags: {}\n spawn_mob: null\n take_item: \"\"\n teleport: 0\n - broadcast: \"\"\n broadcast_global: \"\"\n delay: 0\n despawn_mob: \"\"\n give_item: \"\"\n heal: 0\n message: \"\"\n set_flags: {}\n set_player_flags:\n 1001_touchdown: true\n spawn_mob: null\n take_item: \"\"\n teleport: 0\n value: null\n","is_delete":false,"is_create":false},{"time":"2026-06-30T16:34:21-04:00","description":"update room 2001","file_path":"data/rooms/intro/2001.yaml","old_content":"block_transport: false\ncolor: \"\"\ndescription:\n - text: It's a test room\nexits:\n east:\n room: 2002\n south:\n room: 2006\n southeast:\n room: 2005\n west:\n room: 1001\nhazard: \"\"\nid: 2001\nitem_spawns: []\nmobs: []\nname: Test Room\nobjects: []\non_enter: []\ntriggers: []\n","new_content":"block_transport: false\ncolor: \"\"\ndescription:\n - text: It's a test room\nexits:\n east:\n room: 2002\n south:\n room: 2006\n southeast:\n room: 2005\n west:\n room: 1001\nhazard: \"\"\nid: 2001\nitem_spawns: []\nmobs: []\nname: Test Room\nobjects:\n - id: tree\non_enter: []\ntriggers: []\n","is_delete":false,"is_create":false},{"time":"2026-06-30T16:35:02-04:00","description":"update room 2001","file_path":"data/rooms/intro/2001.yaml","old_content":"block_transport: false\ncolor: \"\"\ndescription:\n - text: It's a test room\nexits:\n east:\n room: 2002\n south:\n room: 2006\n southeast:\n room: 2005\n west:\n room: 1001\nhazard: \"\"\nid: 2001\nitem_spawns: []\nmobs: []\nname: Test Room\nobjects:\n - id: tree\non_enter: []\ntriggers: []\n","new_content":"block_transport: false\ncolor: \"\"\ndescription:\n - text: It's a test room\nexits:\n east:\n room: 2002\n south:\n room: 2006\n southeast:\n room: 2005\n west:\n room: 1001\nhazard: \"\"\nid: 2001\nitem_spawns:\n - id: bronze_axe\n quantity: 1\n respawn_ticks: 0\nmobs: []\nname: Test Room\nobjects:\n - id: tree\non_enter: []\ntriggers: []\n","is_delete":false,"is_create":false},{"time":"2026-06-30T16:35:15-04:00","description":"update room 2001","file_path":"data/rooms/intro/2001.yaml","old_content":"block_transport: false\ncolor: \"\"\ndescription:\n - text: It's a test room\nexits:\n east:\n room: 2002\n south:\n room: 2006\n southeast:\n room: 2005\n west:\n room: 1001\nhazard: \"\"\nid: 2001\nitem_spawns:\n - id: bronze_axe\n quantity: 1\n respawn_ticks: 0\nmobs: []\nname: Test Room\nobjects:\n - id: tree\non_enter: []\ntriggers: []\n","new_content":"block_transport: false\ncolor: \"\"\ndescription:\n - text: It's a test room\nexits:\n east:\n room: 2002\n south:\n room: 2006\n southeast:\n room: 2005\n west:\n room: 1001\nhazard: \"\"\nid: 2001\nitem_spawns:\n - id: bronze_axe\n quantity: 1\n respawn_ticks: 1\nmobs: []\nname: Test Room\nobjects:\n - id: tree\non_enter: []\ntriggers: []\n","is_delete":false,"is_create":false},{"time":"2026-06-30T17:43:28-04:00","description":"Update object copper_rock","file_path":"data/objects/copper_rock.yaml","old_content":"color: \"B2\"\ngather:\n depleted_message: You don't see any ore in this rock.\n drops:\n - depletes: true\n item_id: copper_ore\n level: 1\n message: You manage to mine some {B2}copper ore{/}.\n weight: 90\n xp: 17\n - depletes: false\n message: You spot a glint of something valuable!\n table: gem_table\n weight: 10\n fail_message: You chip away but get nothing useful.\n gather_message: You swing your pickaxe at the rock...\n respawn_broadcast: A glint of copper catches your eye from some {name}.\n respawn_timer: 50\n skill: mining\n success:\n base: 0.5\n cap: 0.95\n per_level: 0.01\n tools:\n - pickaxe\nname: copper rock\n","new_content":"aliases: []\ncolor: B2\ndescription: \"\"\ngather:\n bait: \"\"\n deplete_timer: 0\n depleted_message: You don't see any ore in this rock.\n drops:\n - depletes: true\n item_id: copper_ore\n level: 1\n message: You manage to mine some {B2}copper ore{/}.\n quantity: 0\n table: \"\"\n weight: 90\n xp: 17\n - depletes: false\n item_id: \"\"\n level: 0\n message: You spot a glint of something valuable!\n quantity: 0\n table: gem_table\n weight: 10\n xp: 0\n exhausted_message: \"\"\n fail_message: You chip away but get nothing useful.\n gather_message: You swing your pickaxe at the rock...\n nest_chance: 0\n respawn_broadcast: A glint of copper catches your eye from some {name}.\n respawn_timer: 50\n skill: mining\n success:\n base: 0.5\n cap: 0.95\n per_level: 0.01\n tools:\n - pickaxe\nhidden: false\nid: copper_rock\ninroom_description: \"\"\nname: copper rock\nremoval_item: \"\"\n","is_delete":false,"is_create":false},{"time":"2026-06-30T23:48:18-04:00","description":"update room 2001","file_path":"data/rooms/intro/2001.yaml","old_content":"block_transport: false\ncolor: \"\"\ndescription:\n - text: It's a test room\nexits:\n east:\n room: 2002\n south:\n room: 2006\n southeast:\n room: 2005\n west:\n room: 1001\nhazard: \"\"\nid: 2001\nitem_spawns:\n - id: bronze_axe\n quantity: 1\n respawn_ticks: 1\nmobs: []\nname: Test Room\nobjects:\n - id: tree\non_enter: []\ntriggers: []\n","new_content":"block_transport: false\ncolor: \"\"\ndescription:\n - text: It's a test room\nexits:\n east:\n room: 2002\n south:\n room: 2006\n southeast:\n room: 2005\n west:\n room: 1001\nhazard: \"\"\nid: 2001\nitem_spawns:\n - id: bronze_axe\n quantity: 1\n respawn_ticks: 1\n - id: pot_of_flour\n quantity: 1\n respawn_ticks: 0\nmobs: []\nname: Test Room\nobjects:\n - id: tree\non_enter: []\ntriggers: []\n","is_delete":false,"is_create":false},{"time":"2026-06-30T23:48:23-04:00","description":"update room 2001","file_path":"data/rooms/intro/2001.yaml","old_content":"block_transport: false\ncolor: \"\"\ndescription:\n - text: It's a test room\nexits:\n east:\n room: 2002\n south:\n room: 2006\n southeast:\n room: 2005\n west:\n room: 1001\nhazard: \"\"\nid: 2001\nitem_spawns:\n - id: bronze_axe\n quantity: 1\n respawn_ticks: 1\n - id: pot_of_flour\n quantity: 1\n respawn_ticks: 0\nmobs: []\nname: Test Room\nobjects:\n - id: tree\non_enter: []\ntriggers: []\n","new_content":"block_transport: false\ncolor: \"\"\ndescription:\n - text: It's a test room\nexits:\n east:\n room: 2002\n south:\n room: 2006\n southeast:\n room: 2005\n west:\n room: 1001\nhazard: \"\"\nid: 2001\nitem_spawns:\n - id: bronze_axe\n quantity: 1\n respawn_ticks: 1\n - id: pot_of_flour\n quantity: 1\n respawn_ticks: 0\n - id: bucket_of_water\n quantity: 1\n respawn_ticks: 0\nmobs: []\nname: Test Room\nobjects:\n - id: tree\non_enter: []\ntriggers: []\n","is_delete":false,"is_create":false},{"time":"2026-06-30T23:53:08-04:00","description":"Update item bread_dough","file_path":"data/items/consumables/bread_dough.yaml","old_content":"color: \"DE\"\ncraft:\n type: combine\n consume:\n - byproducts:\n - empty_pot\n items:\n - pot_of_flour\n quantity: 1\n - byproducts:\n - empty_bucket\n - empty_jug\n items:\n - bucket_of_water\n - jug_of_water\n quantity: 1\n wait: 2\ndescription: A ball of uncooked bread dough. It needs to be baked.\nname: bread dough\nstackable: false\nvalue: 3\n","new_content":"color: DE\ncraft:\n - consume:\n - byproducts:\n - empty_pot\n items:\n - pot_of_flour\n quantity: 1\n - byproducts:\n - empty_bucket\n - empty_jug\n items:\n - bucket_of_water\n - jug_of_water\n quantity: 1\n end_message: testend\n fail: \"\"\n level: 0\n message: testmsg\n output_qty: 0\n start_message: teststart\n station: []\n subtype: \"\"\n tool: \"\"\n type: combine\n wait: 2\n xp: 0\ndescription: A ball of uncooked bread dough. It needs to be baked.\nid: bread_dough\nmax_quality: 0\nname: bread dough\nquality: 0\nstackable: false\nvalue: 3\n","is_delete":false,"is_create":false},{"time":"2026-07-01T00:23:04-04:00","description":"Update item bread_dough","file_path":"data/items/consumables/bread_dough.yaml","old_content":"color: DE\ncraft:\n - consume:\n - byproducts:\n - empty_pot\n items:\n - pot_of_flour\n quantity: 1\n - byproducts:\n - empty_bucket\n - empty_jug\n items:\n - bucket_of_water\n - jug_of_water\n quantity: 1\n end_message: testend\n fail: \"\"\n level: 0\n message: testmsg\n output_qty: 0\n start_message: teststart\n station: []\n subtype: \"\"\n tool: \"\"\n type: combine\n wait: 2\n xp: 0\ndescription: A ball of uncooked bread dough. It needs to be baked.\nid: bread_dough\nmax_quality: 0\nname: bread dough\nquality: 0\nstackable: false\nvalue: 3\n","new_content":"color: DE\ncraft:\n - consume:\n - byproducts:\n - empty_pot\n items:\n - pot_of_flour\n quantity: 1\n - byproducts:\n - empty_bucket\n - empty_jug\n items:\n - bucket_of_water\n - jug_of_water\n quantity: 1\n end_message: testend\n fail: \"\"\n level: 0\n message: testmsg\n output_qty: 0\n start_message: teststart\n station: []\n subtype: \"\"\n tool: \"\"\n type: combine\n wait: 2\n xp: 0\ndescription: A ball of uncooked bread dough. It needs to be baked.\nid: bread_dough\nmax_quality: 0\nname: bread dough\nquality: 0\nstackable: false\nvalue: 3\n","is_delete":false,"is_create":false},{"time":"2026-07-01T01:22:55-04:00","description":"update room 1001","file_path":"data/rooms/intro/1001.yaml","old_content":"block_transport: true\ncolor: \"\"\ndescription:\n - text: |-\n A dim, windowless shuttle interior with a few uncomfortable rows of steel seats facing forward. A large framed sign hangs next to the closed cockpit door. The piston-powered staircase is firmly closed at the rear of the craft.\n\n A dim, windowless shuttle interior with a few uncomfortable rows of steel seats facing forward. A large {11}framed sign{/} hangs next to the closed cockpit door. A piston-powered staircase leads down out the back of the small craft with a smiling attendant ready to help disembark.\nexits:\n down:\n blocked_message: The piston-powered staircase is firmly closed.\n condition:\n all_of: []\n any_of: []\n flag: \"\"\n has_item: \"\"\n min_credits: 0\n not: false\n player_flag: 1001_touchdown\n value: null\n room: 1002\n east:\n room: 2001\nhazard: \"\"\nid: 1001\nitem_spawns: []\nmobs:\n - id: flight_attendant\nname: Inside Transport Shuttle\nobjects:\n - description:\n - text: \"We hope you enjoy your trip on our shuttle! Your pilot is [TYLER].\\n\\nWhen you arrive at your final destination, please be aware of the following basic commands:\\n\\n{0B bold}Movement:{/} {0A}north{/}, {0A}south{/}, {0A}east{/}, {0A}west{/}, {0A}up{/}, {0A}down{/}\\n{0B bold}Look:{/} {0A}look{/}, {0A}look \u003citem/object/mob\u003e{/}, and {0A}map{/}\\n{0B bold}Items:{/} {0A}inv{/} to see your 28-slot inventory\\n {0A}get \u003citem\u003e{/}, {0A}drop \u003citem\u003e{/}, {0A}wear \u003citem\u003e{/}, {0A}remove \u003citem\u003e{/}\\n {0A}use \u003citem\u003e on \u003citem/object\u003e{/}\\n {0A}eq{/} for equiped gear\\n{0B bold}Comms:{/} {0A}talk \u003cmob\u003e{/} for NPC chat\\n {0A}say \u003cmsg\u003e{/} and {0A}global \u003cmsg\u003e{/} for human chat\\n{0B bold}Character:{/} {0A}score{/} and {0A}skills{/} for stats. \\n{0B bold}Combat{/} {0A}attack \u003cmob\u003e{/}\\n{0B bold}Skills{/} Many skills have shortcuts like {0A}mine{/}, {0A}fish{/}, or {0A}chop{/}\\n{0B bold}Options{/} {0A}options{/} for a list of account options\\n {0A}options \u003copt\u003e \u003cvalue\u003e{/} to change an option\\n\\nType {0C bold}what{/} for a list of possible common actions\\n\\nMake sure to check the {0A}help{/} pages, especially {0A}help newplayer{/}!\"\n hidden: true\n name: framed sign\n on_look:\n aps_node: false\n assign_task: false\n cost: 0\n extend_task: false\n give_item: \"\"\n heal: 0\n reputation_cost: 0\n sawmill: false\n set_flags: {}\n set_player_flags:\n 1001_look_sign: true\n shop: null\n skip_task: false\n take_item: \"\"\n teleport: 0\n - description:\n - text: A sturdy, locked steel door that keeps passengers out of the cockpit. There is a tiny, thin window at eye level.\n hidden: true\n name: door\n - description:\n - text: A thick trim with rounded bolt heads frames the tiny window. It looks like it was cut into the door at some point, potentially as a simple replacement to computerized security systems. Inside the cockpit there's a pilot finishing up landing procedures on a large panel of analog instruments.\n hidden: true\n name: window\n - aliases:\n - cockpit\n description:\n - text: The cramped cockpit is surrounded by buttons, swiches, dials, and analog gauges. The parts are a mix of technologies from the last century. Part of the panel is obscured by a draped cloth as if to hide it from view. Odd.\n hidden: true\n name: instrument panel\n - aliases: []\n description:\n - text: That's the guy who took you from the Passenger Barge Denali down here to Vesta. A middle-aged man in a neat white jumpsuit with a matching white sort of conductor's hat. He's following a written procedure checklist and seems to take his job seriously.\n hidden: true\n name: pilot\non_enter:\n - broadcast: \"\"\n broadcast_global: \"\"\n condition:\n all_of: []\n any_of: []\n flag: \"\"\n has_item: \"\"\n min_credits: 0\n not: true\n player_flag: 1001_welcome\n value: null\n delay: 5\n despawn_mob: \"\"\n give_item: \"\"\n heal: 0\n message: '{0B bold}Welcome to The House of Icarus{/}'\n set_flags: {}\n set_player_flags: {}\n spawn_mob: null\n take_item: \"\"\n teleport: 0\n - broadcast: \"\"\n broadcast_global: \"\"\n condition:\n all_of: []\n any_of: []\n flag: \"\"\n has_item: \"\"\n min_credits: 0\n not: true\n player_flag: 1001_welcome\n value: null\n delay: 7\n despawn_mob: \"\"\n give_item: \"\"\n heal: 0\n message: '{0B}Type{/} {0A}look sign{/} {0B}or{/} {0A}talk attendant{/} {0B}to get started{/}'\n set_flags: {}\n set_player_flags:\n 1001_welcome: true\n spawn_mob: null\n take_item: \"\"\n teleport: 0\n - broadcast: \"\"\n broadcast_global: \"\"\n condition:\n all_of: []\n any_of: []\n flag: \"\"\n has_item: \"\"\n min_credits: 0\n not: true\n player_flag: 1001_welcome\n value: null\n delay: 7\n despawn_mob: \"\"\n give_item: \"\"\n heal: 0\n message: '{0B}Type{/} {0A}help newplayer{/} {0B}for the new player''s guide. That''s it. Explore and have fun.{/}'\n set_flags: {}\n set_player_flags: {}\n spawn_mob: null\n take_item: \"\"\n teleport: 0\ntriggers:\n - id: \"\"\n on_flag: \"\"\n on_player_flag: 1001_look_sign\n room: 0\n steps:\n - broadcast: \"\"\n broadcast_global: \"\"\n delay: 5\n despawn_mob: \"\"\n give_item: \"\"\n heal: 0\n message: The cabin shakes as the small craft touches down\n set_flags: {}\n set_player_flags: {}\n spawn_mob: null\n take_item: \"\"\n teleport: 0\n - broadcast: \"\"\n broadcast_global: \"\"\n delay: 5\n despawn_mob: \"\"\n give_item: \"\"\n heal: 0\n message: The pistons hiss as the rear staircase opens\n set_flags: {}\n set_player_flags: {}\n spawn_mob: null\n take_item: \"\"\n teleport: 0\n - broadcast: \"\"\n broadcast_global: \"\"\n delay: 0\n despawn_mob: \"\"\n give_item: \"\"\n heal: 0\n message: \"\"\n set_flags: {}\n set_player_flags:\n 1001_touchdown: true\n spawn_mob: null\n take_item: \"\"\n teleport: 0\n value: null\n","new_content":"block_transport: true\ncolor: \"\"\ndescription:\n - text: |-\n A dim, windowless shuttle interior with a few uncomfortable rows of steel seats facing forward. A large framed sign hangs next to the closed cockpit door. The piston-powered staircase is firmly closed at the rear of the craft.\n\n A dim, windowless shuttle interior with a few uncomfortable rows of steel seats facing forward. A large {11}framed sign{/} hangs next to the closed cockpit door. A piston-powered staircase leads down out the back of the small craft with a smiling attendant ready to help disembark.\nexits:\n down:\n blocked_message: The piston-powered staircase is firmly closed.\n condition:\n all_of: []\n any_of: []\n flag: \"\"\n has_item: \"\"\n min_credits: 0\n not: false\n player_flag: 1001_touchdown\n value: null\n room: 1002\n east:\n room: 2001\nhazard: \"\"\nid: 1001\nitem_spawns: []\nmobs:\n - id: flight_attendant\nname: Inside Transport Shuttle\nobjects:\n - description:\n - text: \"We hope you enjoy your trip on our shuttle! Your pilot is [TYLER].\\n\\nWhen you arrive at your final destination, please be aware of the following basic commands:\\n\\n{0B bold}Movement:{/} {0A}north{/}, {0A}south{/}, {0A}east{/}, {0A}west{/}, {0A}up{/}, {0A}down{/}\\n{0B bold}Look:{/} {0A}look{/}, {0A}look \u003citem/object/mob\u003e{/}, and {0A}map{/}\\n{0B bold}Items:{/} {0A}inv{/} to see your 28-slot inventory\\n {0A}get \u003citem\u003e{/}, {0A}drop \u003citem\u003e{/}, {0A}wear \u003citem\u003e{/}, {0A}remove \u003citem\u003e{/}\\n {0A}use \u003citem\u003e on \u003citem/object\u003e{/}\\n {0A}eq{/} for equiped gear\\n{0B bold}Comms:{/} {0A}talk \u003cmob\u003e{/} for NPC chat\\n {0A}say \u003cmsg\u003e{/} and {0A}global \u003cmsg\u003e{/} for human chat\\n{0B bold}Character:{/} {0A}score{/} and {0A}skills{/} for stats. \\n{0B bold}Combat{/} {0A}attack \u003cmob\u003e{/}\\n{0B bold}Skills{/} Many skills have shortcuts like {0A}mine{/}, {0A}fish{/}, or {0A}chop{/}\\n{0B bold}Options{/} {0A}options{/} for a list of account options\\n {0A}options \u003copt\u003e \u003cvalue\u003e{/} to change an option\\n\\nType {0C bold}what{/} for a list of possible common actions\\n\\nMake sure to check the {0A}help{/} pages, especially {0A}help newplayer{/}!\"\n hidden: true\n name: framed sign\n on_look:\n aps_node: false\n assign_task: false\n cost: 0\n extend_task: false\n give_item: \"\"\n heal: 0\n reputation_cost: 0\n sawmill: false\n set_flags: {}\n set_player_flags:\n 1001_look_sign: true\n shop: null\n skip_task: false\n take_item: \"\"\n teleport: 0\n - description:\n - text: A sturdy, locked steel door that keeps passengers out of the cockpit. There is a tiny, thin window at eye level.\n hidden: true\n name: door\n - description:\n - text: A thick trim with rounded bolt heads frames the tiny window. It looks like it was cut into the door at some point, potentially as a simple replacement to computerized security systems. Inside the cockpit there's a pilot finishing up landing procedures on a large panel of analog instruments.\n hidden: true\n name: window\n - aliases:\n - cockpit\n description:\n - text: The cramped cockpit is surrounded by buttons, swiches, dials, and analog gauges. The parts are a mix of technologies from the last century. Part of the panel is obscured by a draped cloth as if to hide it from view. Odd.\n hidden: true\n name: instrument panel\n - aliases: []\n description:\n - text: That's the guy who took you from the Passenger Barge Denali down here to Vesta. A middle-aged man in a neat white jumpsuit with a matching white sort of conductor's hat. He's following a written procedure checklist and seems to take his job seriously.\n hidden: true\n name: pilot\non_enter:\n - broadcast: \"\"\n broadcast_global: \"\"\n condition:\n all_of: []\n any_of: []\n flag: \"\"\n has_item: \"\"\n min_credits: 0\n not: true\n player_flag: 1001_welcome\n value: null\n delay: 5\n despawn_mob: \"\"\n give_item: \"\"\n heal: 0\n message: '{0B bold}Welcome to The House of Icarus{/}'\n set_flags: {}\n set_player_flags: {}\n spawn_mob: null\n take_item: \"\"\n teleport: 0\n - broadcast: \"\"\n broadcast_global: \"\"\n condition:\n all_of: []\n any_of: []\n flag: \"\"\n has_item: \"\"\n min_credits: 0\n not: true\n player_flag: 1001_welcome\n value: null\n delay: 7\n despawn_mob: \"\"\n give_item: \"\"\n heal: 0\n message: '{0B}Type{/} {0A}look sign{/} {0B}or{/} {0A}talk attendant{/} {0B}to get started{/}'\n set_flags: {}\n set_player_flags:\n 1001_welcome: true\n spawn_mob: null\n take_item: \"\"\n teleport: 0\n - broadcast: \"\"\n broadcast_global: \"\"\n condition:\n all_of: []\n any_of: []\n flag: \"\"\n has_item: \"\"\n min_credits: 0\n not: true\n player_flag: 1001_welcome\n value: null\n delay: 7\n despawn_mob: \"\"\n give_item: \"\"\n heal: 0\n message: '{0B}Type{/} {0A}help newplayer{/} {0B}for the new player''s guide. That''s it. Explore and have fun.{/}'\n set_flags: {}\n set_player_flags: {}\n spawn_mob: null\n take_item: \"\"\n teleport: 0\ntriggers:\n - id: \"\"\n on_flag: \"\"\n on_player_flag: 1001_look_sign\n room: 0\n steps:\n - broadcast: \"\"\n broadcast_global: \"\"\n delay: 5\n despawn_mob: \"\"\n give_item: \"\"\n heal: 0\n message: The cabin shakes as the small craft touches down\n set_flags: {}\n set_player_flags: {}\n spawn_mob: null\n take_item: \"\"\n teleport: 0\n - broadcast: \"\"\n broadcast_global: \"\"\n delay: 5\n despawn_mob: \"\"\n give_item: \"\"\n heal: 0\n message: The pistons hiss as the rear staircase opens\n set_flags: {}\n set_player_flags: {}\n spawn_mob: null\n take_item: \"\"\n teleport: 0\n - broadcast: \"\"\n broadcast_global: \"\"\n delay: 0\n despawn_mob: \"\"\n give_item: \"\"\n heal: 0\n message: \"\"\n set_flags: {}\n set_player_flags:\n 1001_touchdown: true\n spawn_mob: null\n take_item: \"\"\n teleport: 0\n value: null\n","is_delete":false,"is_create":false}],"redo":null} \ No newline at end of file +{"history":[{"time":"2026-06-30T14:29:37-04:00","description":"delete room 1014 (cleaned 0 exits)","file_path":"data/rooms/intro/1014.yaml","old_content":"id: 1014\nname: 'Room #1014'\ncolor: D5\ndescription: []\nexits:\n southwest:\n room: 1013\nobjects: []\nitem_spawns: []\nmobs: []\non_enter: []\nhazard: \"\"\nblock_transport: false\ntriggers: []\n","new_content":"","is_delete":true,"is_create":false},{"time":"2026-06-30T14:29:37-04:00","description":"delete room 1016 (cleaned 0 exits)","file_path":"data/rooms/intro/1016.yaml","old_content":"id: 1016\nname: New Room\ncolor: \"97\"\ndescription:\n - text: A featureless room.\nexits:\n down:\n room: 1017\n south:\n room: 1009\n southwest:\n room: 1005\nobjects: []\nitem_spawns: []\nmobs: []\non_enter: []\nhazard: \"\"\nblock_transport: false\ntriggers: []\n","new_content":"","is_delete":true,"is_create":false},{"time":"2026-06-30T14:29:38-04:00","description":"delete room 1015 (cleaned 0 exits)","file_path":"data/rooms/intro/1015.yaml","old_content":"id: 1015\nname: 'Room #1015'\ncolor: 0C\ndescription: []\nexits:\n northwest:\n room: 1018\nobjects: []\nitem_spawns: []\nmobs: []\non_enter: []\nhazard: \"\"\nblock_transport: false\ntriggers: []\n","new_content":"","is_delete":true,"is_create":false},{"time":"2026-06-30T14:29:39-04:00","description":"delete room 1017 (cleaned 0 exits)","file_path":"data/rooms/intro/1017.yaml","old_content":"id: 1017\nname: New Room\ncolor: \"\"\ndescription:\n - text: A featureless room.\nexits: {}\nobjects: []\nitem_spawns: []\nmobs: []\non_enter: []\nhazard: \"\"\nblock_transport: false\ntriggers: []\n","new_content":"","is_delete":true,"is_create":false},{"time":"2026-06-30T14:29:40-04:00","description":"delete room 1018 (cleaned 0 exits)","file_path":"data/rooms/intro/1018.yaml","old_content":"id: 1018\nname: 'Room #1018'\ncolor: D0\ndescription: []\nexits: {}\nobjects: []\nitem_spawns: []\nmobs: []\non_enter: []\nhazard: \"\"\nblock_transport: false\ntriggers: []\n","new_content":"","is_delete":true,"is_create":false},{"time":"2026-06-30T14:29:40-04:00","description":"delete room 1019 (cleaned 0 exits)","file_path":"data/rooms/intro/1019.yaml","old_content":"id: 1019\nname: 'Room #1019'\ncolor: \"\"\ndescription: []\nexits: {}\nobjects: []\nitem_spawns: []\nmobs: []\non_enter: []\nhazard: \"\"\nblock_transport: false\ntriggers: []\n","new_content":"","is_delete":true,"is_create":false},{"time":"2026-06-30T14:29:41-04:00","description":"delete room 1020 (cleaned 0 exits)","file_path":"data/rooms/intro/1020.yaml","old_content":"id: 1020\nname: 'Room #1020'\ncolor: \"\"\ndescription: []\nexits: {}\nobjects: []\nitem_spawns: []\nmobs: []\non_enter: []\nhazard: \"\"\nblock_transport: false\ntriggers: []\n","new_content":"","is_delete":true,"is_create":false},{"time":"2026-06-30T14:30:45-04:00","description":"delete room 1013 (cleaned 1 exits)","file_path":"data/rooms/intro/1013.yaml","old_content":"id: 1013\nname: 'Room #1013'\ncolor: \"72\"\ndescription: []\nexits:\n west:\n room: 1007\nobjects: []\nitem_spawns: []\nmobs: []\non_enter: []\nhazard: \"\"\nblock_transport: false\ntriggers: []\n","new_content":"","is_delete":true,"is_create":false},{"time":"2026-06-30T14:30:49-04:00","description":"delete room 1009 (cleaned 0 exits)","file_path":"data/rooms/intro/1009.yaml","old_content":"id: 1009\nname: New Room\ncolor: \"27\"\ndescription:\n - text: A featureless room.\nexits:\n northwest:\n room: 8\n southwest:\n room: 1006\n west:\n room: 1005\nobjects: []\nitem_spawns: []\nmobs:\n - id: man\n - id: man\non_enter: []\nhazard: \"\"\nblock_transport: false\ntriggers: []\n","new_content":"","is_delete":true,"is_create":false},{"time":"2026-06-30T14:30:51-04:00","description":"delete room 1007 (cleaned 1 exits)","file_path":"data/rooms/intro/1007.yaml","old_content":"id: 1007\nname: 'Room #1007'\ncolor: \"\"\ndescription: []\nexits:\n west:\n room: 2004\nobjects: []\nitem_spawns: []\nmobs: []\non_enter: []\nhazard: \"\"\nblock_transport: false\ntriggers: []\n","new_content":"","is_delete":true,"is_create":false},{"time":"2026-06-30T14:30:53-04:00","description":"delete room 1006 (cleaned 4 exits)","file_path":"data/rooms/intro/1006.yaml","old_content":"id: 1006\nname: New Room\ncolor: E2\ndescription:\n - text: A featureless room.\nexits:\n north:\n room: 1005\n northwest:\n room: 1008\n up:\n room: 1010\n west:\n room: 2003\nobjects: []\nitem_spawns: []\nmobs: []\non_enter: []\nhazard: \"\"\nblock_transport: false\ntriggers: []\n","new_content":"","is_delete":true,"is_create":false},{"time":"2026-06-30T14:30:59-04:00","description":"delete room 1010 (cleaned 1 exits)","file_path":"data/rooms/intro/1010.yaml","old_content":"id: 1010\nname: New Room\ncolor: \"\"\ndescription:\n - text: A featureless room.\nexits:\n north:\n room: 1011\nobjects: []\nitem_spawns: []\nmobs: []\non_enter: []\nhazard: \"\"\nblock_transport: false\ntriggers: []\n","new_content":"","is_delete":true,"is_create":false},{"time":"2026-06-30T14:31:00-04:00","description":"delete room 1011 (cleaned 0 exits)","file_path":"data/rooms/intro/1011.yaml","old_content":"id: 1011\nname: New Room\ncolor: \"\"\ndescription:\n - text: A featureless room.\nexits:\n east:\n room: 1012\nobjects: []\nitem_spawns: []\nmobs: []\non_enter: []\nhazard: \"\"\nblock_transport: false\ntriggers: []\n","new_content":"","is_delete":true,"is_create":false},{"time":"2026-06-30T14:31:01-04:00","description":"delete room 1012 (cleaned 0 exits)","file_path":"data/rooms/intro/1012.yaml","old_content":"id: 1012\nname: New Room\ncolor: \"\"\ndescription:\n - text: A featureless room.\nexits: {}\nobjects: []\nitem_spawns: []\nmobs: []\non_enter: []\nhazard: \"\"\nblock_transport: false\ntriggers: []\n","new_content":"","is_delete":true,"is_create":false},{"time":"2026-06-30T14:31:02-04:00","description":"delete room 1005 (cleaned 2 exits)","file_path":"data/rooms/intro/1005.yaml","old_content":"id: 1005\nname: New Room\ncolor: CC\ndescription:\n - text: A featureless room.\nexits:\n southwest:\n room: 2003\n west:\n room: 1008\nobjects: []\nitem_spawns: []\nmobs: []\non_enter: []\nhazard: \"\"\nblock_transport: false\ntriggers: []\n","new_content":"","is_delete":true,"is_create":false},{"time":"2026-06-30T14:31:03-04:00","description":"delete room 1008 (cleaned 1 exits)","file_path":"data/rooms/intro/1008.yaml","old_content":"id: 1008\nname: New Room\ncolor: A9\ndescription:\n - text: A featureless room.\nexits:\n north:\n room: 7\n south:\n room: 2003\nobjects: []\nitem_spawns: []\nmobs: []\non_enter: []\nhazard: \"\"\nblock_transport: false\ntriggers: []\n","new_content":"","is_delete":true,"is_create":false},{"time":"2026-06-30T14:32:29-04:00","description":"update room 2003 (add exit north to 1005)","file_path":"data/rooms/intro/2003.yaml","old_content":"id: 2003\nname: Test Room\ncolor: \"\"\ndescription:\n - text: It's a test room\nexits:\n south:\n room: 2004\n southwest:\n room: 2005\n west:\n room: 2002\nobjects: []\nitem_spawns: []\nmobs: []\non_enter: []\nhazard: \"\"\nblock_transport: false\ntriggers: []\n","new_content":"id: 2003\nname: Test Room\ncolor: \"\"\ndescription:\n - text: It's a test room\nexits:\n north:\n room: 1005\n south:\n room: 2004\n southwest:\n room: 2005\n west:\n room: 2002\nobjects: []\nitem_spawns: []\nmobs: []\non_enter: []\nhazard: \"\"\nblock_transport: false\ntriggers: []\n","is_delete":false,"is_create":false},{"time":"2026-06-30T14:32:29-04:00","description":"create room 1005","file_path":"data/rooms/intro/1005.yaml","old_content":"","new_content":"exits:\n south: 2003\nid: 1005\nname: 'Room #1005'\n","is_delete":false,"is_create":true},{"time":"2026-06-30T14:32:30-04:00","description":"update room 1005 (add exit east to 1006)","file_path":"data/rooms/intro/1005.yaml","old_content":"exits:\n south: 2003\nid: 1005\nname: 'Room #1005'\n","new_content":"id: 1005\nname: 'Room #1005'\ncolor: \"\"\ndescription: []\nexits:\n east:\n room: 1006\n south:\n room: 2003\nobjects: []\nitem_spawns: []\nmobs: []\non_enter: []\nhazard: \"\"\nblock_transport: false\ntriggers: []\n","is_delete":false,"is_create":false},{"time":"2026-06-30T14:32:30-04:00","description":"create room 1006","file_path":"data/rooms/intro/1006.yaml","old_content":"","new_content":"exits:\n west: 1005\nid: 1006\nname: 'Room #1006'\n","is_delete":false,"is_create":true},{"time":"2026-06-30T14:32:31-04:00","description":"update room 1006 (add exit south to 1007)","file_path":"data/rooms/intro/1006.yaml","old_content":"exits:\n west: 1005\nid: 1006\nname: 'Room #1006'\n","new_content":"id: 1006\nname: 'Room #1006'\ncolor: \"\"\ndescription: []\nexits:\n south:\n room: 1007\n west:\n room: 1005\nobjects: []\nitem_spawns: []\nmobs: []\non_enter: []\nhazard: \"\"\nblock_transport: false\ntriggers: []\n","is_delete":false,"is_create":false},{"time":"2026-06-30T14:32:31-04:00","description":"create room 1007","file_path":"data/rooms/intro/1007.yaml","old_content":"","new_content":"exits:\n north: 1006\nid: 1007\nname: 'Room #1007'\n","is_delete":false,"is_create":true},{"time":"2026-06-30T14:32:32-04:00","description":"update room 1007 (add exit east to 1008)","file_path":"data/rooms/intro/1007.yaml","old_content":"exits:\n north: 1006\nid: 1007\nname: 'Room #1007'\n","new_content":"id: 1007\nname: 'Room #1007'\ncolor: \"\"\ndescription: []\nexits:\n east:\n room: 1008\n north:\n room: 1006\nobjects: []\nitem_spawns: []\nmobs: []\non_enter: []\nhazard: \"\"\nblock_transport: false\ntriggers: []\n","is_delete":false,"is_create":false},{"time":"2026-06-30T14:32:32-04:00","description":"create room 1008","file_path":"data/rooms/intro/1008.yaml","old_content":"","new_content":"exits:\n west: 1007\nid: 1008\nname: 'Room #1008'\n","is_delete":false,"is_create":true},{"time":"2026-06-30T14:32:32-04:00","description":"update room 1008 (add exit north to 1009)","file_path":"data/rooms/intro/1008.yaml","old_content":"exits:\n west: 1007\nid: 1008\nname: 'Room #1008'\n","new_content":"id: 1008\nname: 'Room #1008'\ncolor: \"\"\ndescription: []\nexits:\n north:\n room: 1009\n west:\n room: 1007\nobjects: []\nitem_spawns: []\nmobs: []\non_enter: []\nhazard: \"\"\nblock_transport: false\ntriggers: []\n","is_delete":false,"is_create":false},{"time":"2026-06-30T14:32:32-04:00","description":"create room 1009","file_path":"data/rooms/intro/1009.yaml","old_content":"","new_content":"exits:\n south: 1008\nid: 1009\nname: 'Room #1009'\n","is_delete":false,"is_create":true},{"time":"2026-06-30T14:32:33-04:00","description":"update room 1009 (add exit north to 1010)","file_path":"data/rooms/intro/1009.yaml","old_content":"exits:\n south: 1008\nid: 1009\nname: 'Room #1009'\n","new_content":"id: 1009\nname: 'Room #1009'\ncolor: \"\"\ndescription: []\nexits:\n north:\n room: 1010\n south:\n room: 1008\nobjects: []\nitem_spawns: []\nmobs: []\non_enter: []\nhazard: \"\"\nblock_transport: false\ntriggers: []\n","is_delete":false,"is_create":false},{"time":"2026-06-30T14:32:33-04:00","description":"create room 1010","file_path":"data/rooms/intro/1010.yaml","old_content":"","new_content":"exits:\n south: 1009\nid: 1010\nname: 'Room #1010'\n","is_delete":false,"is_create":true},{"time":"2026-06-30T14:32:33-04:00","description":"update room 1010 (add exit east to 1011)","file_path":"data/rooms/intro/1010.yaml","old_content":"exits:\n south: 1009\nid: 1010\nname: 'Room #1010'\n","new_content":"id: 1010\nname: 'Room #1010'\ncolor: \"\"\ndescription: []\nexits:\n east:\n room: 1011\n south:\n room: 1009\nobjects: []\nitem_spawns: []\nmobs: []\non_enter: []\nhazard: \"\"\nblock_transport: false\ntriggers: []\n","is_delete":false,"is_create":false},{"time":"2026-06-30T14:32:33-04:00","description":"create room 1011","file_path":"data/rooms/intro/1011.yaml","old_content":"","new_content":"exits:\n west: 1010\nid: 1011\nname: 'Room #1011'\n","is_delete":false,"is_create":true},{"time":"2026-06-30T14:32:34-04:00","description":"update room 1011 (add exit south to 1012)","file_path":"data/rooms/intro/1011.yaml","old_content":"exits:\n west: 1010\nid: 1011\nname: 'Room #1011'\n","new_content":"id: 1011\nname: 'Room #1011'\ncolor: \"\"\ndescription: []\nexits:\n south:\n room: 1012\n west:\n room: 1010\nobjects: []\nitem_spawns: []\nmobs: []\non_enter: []\nhazard: \"\"\nblock_transport: false\ntriggers: []\n","is_delete":false,"is_create":false},{"time":"2026-06-30T14:32:34-04:00","description":"create room 1012","file_path":"data/rooms/intro/1012.yaml","old_content":"","new_content":"exits:\n north: 1011\nid: 1012\nname: 'Room #1012'\n","is_delete":false,"is_create":true},{"time":"2026-06-30T14:32:34-04:00","description":"update room 1012 (add exit south to 1013)","file_path":"data/rooms/intro/1012.yaml","old_content":"exits:\n north: 1011\nid: 1012\nname: 'Room #1012'\n","new_content":"id: 1012\nname: 'Room #1012'\ncolor: \"\"\ndescription: []\nexits:\n north:\n room: 1011\n south:\n room: 1013\nobjects: []\nitem_spawns: []\nmobs: []\non_enter: []\nhazard: \"\"\nblock_transport: false\ntriggers: []\n","is_delete":false,"is_create":false},{"time":"2026-06-30T14:32:34-04:00","description":"create room 1013","file_path":"data/rooms/intro/1013.yaml","old_content":"","new_content":"exits:\n north: 1012\nid: 1013\nname: 'Room #1013'\n","is_delete":false,"is_create":true},{"time":"2026-06-30T14:32:35-04:00","description":"delete room 1013 (cleaned 1 exits)","file_path":"data/rooms/intro/1013.yaml","old_content":"exits:\n north: 1012\nid: 1013\nname: 'Room #1013'\n","new_content":"","is_delete":true,"is_create":false},{"time":"2026-06-30T14:32:36-04:00","description":"delete room 1012 (cleaned 1 exits)","file_path":"data/rooms/intro/1012.yaml","old_content":"id: 1012\nname: 'Room #1012'\ncolor: \"\"\ndescription: []\nexits:\n north:\n room: 1011\nobjects: []\nitem_spawns: []\nmobs: []\non_enter: []\nhazard: \"\"\nblock_transport: false\ntriggers: []\n","new_content":"","is_delete":true,"is_create":false},{"time":"2026-06-30T14:32:37-04:00","description":"delete room 1011 (cleaned 1 exits)","file_path":"data/rooms/intro/1011.yaml","old_content":"id: 1011\nname: 'Room #1011'\ncolor: \"\"\ndescription: []\nexits:\n west:\n room: 1010\nobjects: []\nitem_spawns: []\nmobs: []\non_enter: []\nhazard: \"\"\nblock_transport: false\ntriggers: []\n","new_content":"","is_delete":true,"is_create":false},{"time":"2026-06-30T14:32:37-04:00","description":"delete room 1010 (cleaned 1 exits)","file_path":"data/rooms/intro/1010.yaml","old_content":"id: 1010\nname: 'Room #1010'\ncolor: \"\"\ndescription: []\nexits:\n south:\n room: 1009\nobjects: []\nitem_spawns: []\nmobs: []\non_enter: []\nhazard: \"\"\nblock_transport: false\ntriggers: []\n","new_content":"","is_delete":true,"is_create":false},{"time":"2026-06-30T14:32:38-04:00","description":"delete room 1009 (cleaned 1 exits)","file_path":"data/rooms/intro/1009.yaml","old_content":"id: 1009\nname: 'Room #1009'\ncolor: \"\"\ndescription: []\nexits:\n south:\n room: 1008\nobjects: []\nitem_spawns: []\nmobs: []\non_enter: []\nhazard: \"\"\nblock_transport: false\ntriggers: []\n","new_content":"","is_delete":true,"is_create":false},{"time":"2026-06-30T14:32:39-04:00","description":"delete room 1008 (cleaned 1 exits)","file_path":"data/rooms/intro/1008.yaml","old_content":"id: 1008\nname: 'Room #1008'\ncolor: \"\"\ndescription: []\nexits:\n west:\n room: 1007\nobjects: []\nitem_spawns: []\nmobs: []\non_enter: []\nhazard: \"\"\nblock_transport: false\ntriggers: []\n","new_content":"","is_delete":true,"is_create":false},{"time":"2026-06-30T14:32:40-04:00","description":"delete room 1007 (cleaned 1 exits)","file_path":"data/rooms/intro/1007.yaml","old_content":"id: 1007\nname: 'Room #1007'\ncolor: \"\"\ndescription: []\nexits:\n north:\n room: 1006\nobjects: []\nitem_spawns: []\nmobs: []\non_enter: []\nhazard: \"\"\nblock_transport: false\ntriggers: []\n","new_content":"","is_delete":true,"is_create":false},{"time":"2026-06-30T14:32:40-04:00","description":"delete room 1006 (cleaned 1 exits)","file_path":"data/rooms/intro/1006.yaml","old_content":"id: 1006\nname: 'Room #1006'\ncolor: \"\"\ndescription: []\nexits:\n west:\n room: 1005\nobjects: []\nitem_spawns: []\nmobs: []\non_enter: []\nhazard: \"\"\nblock_transport: false\ntriggers: []\n","new_content":"","is_delete":true,"is_create":false},{"time":"2026-06-30T14:32:41-04:00","description":"delete room 1005 (cleaned 1 exits)","file_path":"data/rooms/intro/1005.yaml","old_content":"id: 1005\nname: 'Room #1005'\ncolor: \"\"\ndescription: []\nexits:\n south:\n room: 2003\nobjects: []\nitem_spawns: []\nmobs: []\non_enter: []\nhazard: \"\"\nblock_transport: false\ntriggers: []\n","new_content":"","is_delete":true,"is_create":false},{"time":"2026-06-30T15:05:42-04:00","description":"update room 1001","file_path":"data/rooms/intro/1001.yaml","old_content":"id: 1001\nname: Inside Transport Shuttle\ncolor: \"\"\ndescription:\n - text: |-\n A dim, windowless shuttle interior with a few uncomfortable rows of steel seats facing forward. A large framed sign hangs next to the closed cockpit door. The piston-powered staircase is firmly closed at the rear of the craft.\n\n A dim, windowless shuttle interior with a few uncomfortable rows of steel seats facing forward. A large {11}framed sign{/} hangs next to the closed cockpit door. A piston-powered staircase leads down out the back of the small craft with a smiling attendant ready to help disembark.\nexits:\n down:\n room: 1002\n condition:\n flag: \"\"\n value: null\n not: false\n player_flag: 1001_touchdown\n has_item: \"\"\n min_credits: 0\n all_of: []\n any_of: []\n blocked_message: The piston-powered staircase is firmly closed.\n east:\n room: 2001\nobjects:\n - name: framed sign\n hidden: true\n description:\n - text: \"We hope you enjoy your trip on our shuttle! Your pilot is [TYLER].\\n\\nWhen you arrive at your final destination, please be aware of the following basic commands:\\n\\n{0B bold}Movement:{/} {0A}north{/}, {0A}south{/}, {0A}east{/}, {0A}west{/}, {0A}up{/}, {0A}down{/}\\n{0B bold}Look:{/} {0A}look{/}, {0A}look \u003citem/object/mob\u003e{/}, and {0A}map{/}\\n{0B bold}Items:{/} {0A}inv{/} to see your 28-slot inventory\\n {0A}get \u003citem\u003e{/}, {0A}drop \u003citem\u003e{/}, {0A}wear \u003citem\u003e{/}, {0A}remove \u003citem\u003e{/}\\n {0A}use \u003citem\u003e on \u003citem/object\u003e{/}\\n {0A}eq{/} for equiped gear\\n{0B bold}Comms:{/} {0A}talk \u003cmob\u003e{/} for NPC chat\\n {0A}say \u003cmsg\u003e{/} and {0A}global \u003cmsg\u003e{/} for human chat\\n{0B bold}Character:{/} {0A}score{/} and {0A}skills{/} for stats. \\n{0B bold}Combat{/} {0A}attack \u003cmob\u003e{/}\\n{0B bold}Skills{/} Many skills have shortcuts like {0A}mine{/}, {0A}fish{/}, or {0A}chop{/}\\n{0B bold}Options{/} {0A}options{/} for a list of account options\\n {0A}options \u003copt\u003e \u003cvalue\u003e{/} to change an option\\n\\nType {0C bold}what{/} for a list of possible common actions\\n\\nMake sure to check the {0A}help{/} pages, especially {0A}help newplayer{/}!\"\n on_look:\n set_flags: {}\n set_player_flags:\n 1001_look_sign: true\n give_item: \"\"\n take_item: \"\"\n teleport: 0\n heal: 0\n cost: 0\n shop: null\n assign_task: false\n skip_task: false\n extend_task: false\n reputation_cost: 0\n sawmill: false\n aps_node: false\n - name: door\n hidden: true\n description:\n - text: A sturdy, locked steel door that keeps passengers out of the cockpit. There is a tiny, thin window at eye level.\n - name: window\n hidden: true\n description:\n - text: A thick trim with rounded bolt heads frames the tiny window. It looks like it was cut into the door at some point, potentially as a simple replacement to computerized security systems. Inside the cockpit there's a pilot finishing up landing procedures on a large panel of analog instruments.\n - name: instrument panel\n aliases:\n - cockpit\n hidden: true\n description:\n - text: The cramped cockpit is surrounded by buttons, swiches, dials, and analog gauges. The parts are a mix of technologies from the last century. Part of the panel is obscured by a draped cloth as if to hide it from view. Odd.\n - name: pilot\n hidden: true\n description:\n - text: That's the guy who took you from the Passenger Barge Denali down here to Vesta. A middle-aged man in a neat white jumpsuit with a matching white sort of conductor's hat. He's following a written procedure checklist and seems to take his job seriously.\nitem_spawns: []\nmobs:\n - id: flight_attendant\non_enter:\n - message: '{0B bold}Welcome to The House of Icarus{/}'\n condition:\n flag: \"\"\n value: null\n not: true\n player_flag: 1001_welcome\n has_item: \"\"\n min_credits: 0\n all_of: []\n any_of: []\n delay: 5\n set_flags: {}\n set_player_flags: {}\n broadcast: \"\"\n broadcast_global: \"\"\n spawn_mob: null\n despawn_mob: \"\"\n give_item: \"\"\n take_item: \"\"\n teleport: 0\n heal: 0\n - message: '{0B}Type{/} {0A}look sign{/} {0B}or{/} {0A}talk attendant{/} {0B}to get started{/}'\n condition:\n flag: \"\"\n value: null\n not: true\n player_flag: 1001_welcome\n has_item: \"\"\n min_credits: 0\n all_of: []\n any_of: []\n delay: 7\n set_flags: {}\n set_player_flags:\n 1001_welcome: true\n broadcast: \"\"\n broadcast_global: \"\"\n spawn_mob: null\n despawn_mob: \"\"\n give_item: \"\"\n take_item: \"\"\n teleport: 0\n heal: 0\n - message: '{0B}Type{/} {0A}help newplayer{/} {0B}for the new player''s guide. That''s it. Explore and have fun.{/}'\n condition:\n flag: \"\"\n value: null\n not: true\n player_flag: 1001_welcome\n has_item: \"\"\n min_credits: 0\n all_of: []\n any_of: []\n delay: 7\n set_flags: {}\n set_player_flags: {}\n broadcast: \"\"\n broadcast_global: \"\"\n spawn_mob: null\n despawn_mob: \"\"\n give_item: \"\"\n take_item: \"\"\n teleport: 0\n heal: 0\nhazard: \"\"\nblock_transport: true\ntriggers:\n - id: \"\"\n on_player_flag: 1001_look_sign\n on_flag: \"\"\n value: null\n room: 0\n steps:\n - delay: 5\n message: The cabin shakes as the small craft touches down\n broadcast: \"\"\n broadcast_global: \"\"\n set_flags: {}\n set_player_flags: {}\n spawn_mob: null\n give_item: \"\"\n take_item: \"\"\n teleport: 0\n heal: 0\n despawn_mob: \"\"\n - delay: 5\n message: The pistons hiss as the rear staircase opens\n broadcast: \"\"\n broadcast_global: \"\"\n set_flags: {}\n set_player_flags: {}\n spawn_mob: null\n give_item: \"\"\n take_item: \"\"\n teleport: 0\n heal: 0\n despawn_mob: \"\"\n - delay: 0\n message: \"\"\n broadcast: \"\"\n broadcast_global: \"\"\n set_flags: {}\n set_player_flags:\n 1001_touchdown: true\n spawn_mob: null\n give_item: \"\"\n take_item: \"\"\n teleport: 0\n heal: 0\n despawn_mob: \"\"\n","new_content":"block_transport: true\ncolor: \"\"\ndescription:\n - text: |-\n A dim, windowless shuttle interior with a few uncomfortable rows of steel seats facing forward. A large framed sign hangs next to the closed cockpit door. The piston-powered staircase is firmly closed at the rear of the craft.\n\n A dim, windowless shuttle interior with a few uncomfortable rows of steel seats facing forward. A large {11}framed sign{/} hangs next to the closed cockpit door. A piston-powered staircase leads down out the back of the small craft with a smiling attendant ready to help disembark.\nexits:\n down:\n blocked_message: The piston-powered staircase is firmly closed.\n condition:\n all_of: []\n any_of: []\n flag: \"\"\n has_item: \"\"\n min_credits: 0\n not: false\n player_flag: 1001_touchdown\n value: null\n room: 1002\n east:\n room: 2001\nhazard: \"\"\nid: 1001\nitem_spawns: []\nmobs:\n - id: flight_attendant\nname: Inside Transport Shuttle\nobjects:\n - description:\n - text: \"We hope you enjoy your trip on our shuttle! Your pilot is [TYLER].\\n\\nWhen you arrive at your final destination, please be aware of the following basic commands:\\n\\n{0B bold}Movement:{/} {0A}north{/}, {0A}south{/}, {0A}east{/}, {0A}west{/}, {0A}up{/}, {0A}down{/}\\n{0B bold}Look:{/} {0A}look{/}, {0A}look \u003citem/object/mob\u003e{/}, and {0A}map{/}\\n{0B bold}Items:{/} {0A}inv{/} to see your 28-slot inventory\\n {0A}get \u003citem\u003e{/}, {0A}drop \u003citem\u003e{/}, {0A}wear \u003citem\u003e{/}, {0A}remove \u003citem\u003e{/}\\n {0A}use \u003citem\u003e on \u003citem/object\u003e{/}\\n {0A}eq{/} for equiped gear\\n{0B bold}Comms:{/} {0A}talk \u003cmob\u003e{/} for NPC chat\\n {0A}say \u003cmsg\u003e{/} and {0A}global \u003cmsg\u003e{/} for human chat\\n{0B bold}Character:{/} {0A}score{/} and {0A}skills{/} for stats. \\n{0B bold}Combat{/} {0A}attack \u003cmob\u003e{/}\\n{0B bold}Skills{/} Many skills have shortcuts like {0A}mine{/}, {0A}fish{/}, or {0A}chop{/}\\n{0B bold}Options{/} {0A}options{/} for a list of account options\\n {0A}options \u003copt\u003e \u003cvalue\u003e{/} to change an option\\n\\nType {0C bold}what{/} for a list of possible common actions\\n\\nMake sure to check the {0A}help{/} pages, especially {0A}help newplayer{/}!\"\n hidden: true\n name: framed sign\n on_look:\n aps_node: false\n assign_task: false\n cost: 0\n extend_task: false\n give_item: \"\"\n heal: 0\n reputation_cost: 0\n sawmill: false\n set_flags: {}\n set_player_flags:\n 1001_look_sign: true\n shop: null\n skip_task: false\n take_item: \"\"\n teleport: 0\n - description:\n - text: A sturdy, locked steel door that keeps passengers out of the cockpit. There is a tiny, thin window at eye level.\n hidden: true\n name: door\n - description:\n - text: A thick trim with rounded bolt heads frames the tiny window. It looks like it was cut into the door at some point, potentially as a simple replacement to computerized security systems. Inside the cockpit there's a pilot finishing up landing procedures on a large panel of analog instruments.\n hidden: true\n name: window\n - aliases:\n - cockpit\n description:\n - text: The cramped cockpit is surrounded by buttons, swiches, dials, and analog gauges. The parts are a mix of technologies from the last century. Part of the panel is obscured by a draped cloth as if to hide it from view. Odd.\n hidden: true\n name: instrument panel\n - aliases: []\n description:\n - text: That's the guy who took you from the Passenger Barge Denali down here to Vesta. A middle-aged man in a neat white jumpsuit with a matching white sort of conductor's hat. He's following a written procedure checklist and seems to take his job seriously.\n hidden: false\n name: pilot\non_enter:\n - broadcast: \"\"\n broadcast_global: \"\"\n condition:\n all_of: []\n any_of: []\n flag: \"\"\n has_item: \"\"\n min_credits: 0\n not: true\n player_flag: 1001_welcome\n value: null\n delay: 5\n despawn_mob: \"\"\n give_item: \"\"\n heal: 0\n message: '{0B bold}Welcome to The House of Icarus{/}'\n set_flags: {}\n set_player_flags: {}\n spawn_mob: null\n take_item: \"\"\n teleport: 0\n - broadcast: \"\"\n broadcast_global: \"\"\n condition:\n all_of: []\n any_of: []\n flag: \"\"\n has_item: \"\"\n min_credits: 0\n not: true\n player_flag: 1001_welcome\n value: null\n delay: 7\n despawn_mob: \"\"\n give_item: \"\"\n heal: 0\n message: '{0B}Type{/} {0A}look sign{/} {0B}or{/} {0A}talk attendant{/} {0B}to get started{/}'\n set_flags: {}\n set_player_flags:\n 1001_welcome: true\n spawn_mob: null\n take_item: \"\"\n teleport: 0\n - broadcast: \"\"\n broadcast_global: \"\"\n condition:\n all_of: []\n any_of: []\n flag: \"\"\n has_item: \"\"\n min_credits: 0\n not: true\n player_flag: 1001_welcome\n value: null\n delay: 7\n despawn_mob: \"\"\n give_item: \"\"\n heal: 0\n message: '{0B}Type{/} {0A}help newplayer{/} {0B}for the new player''s guide. That''s it. Explore and have fun.{/}'\n set_flags: {}\n set_player_flags: {}\n spawn_mob: null\n take_item: \"\"\n teleport: 0\ntriggers:\n - id: \"\"\n on_flag: \"\"\n on_player_flag: 1001_look_sign\n room: 0\n steps:\n - broadcast: \"\"\n broadcast_global: \"\"\n delay: 5\n despawn_mob: \"\"\n give_item: \"\"\n heal: 0\n message: The cabin shakes as the small craft touches down\n set_flags: {}\n set_player_flags: {}\n spawn_mob: null\n take_item: \"\"\n teleport: 0\n - broadcast: \"\"\n broadcast_global: \"\"\n delay: 5\n despawn_mob: \"\"\n give_item: \"\"\n heal: 0\n message: The pistons hiss as the rear staircase opens\n set_flags: {}\n set_player_flags: {}\n spawn_mob: null\n take_item: \"\"\n teleport: 0\n - broadcast: \"\"\n broadcast_global: \"\"\n delay: 0\n despawn_mob: \"\"\n give_item: \"\"\n heal: 0\n message: \"\"\n set_flags: {}\n set_player_flags:\n 1001_touchdown: true\n spawn_mob: null\n take_item: \"\"\n teleport: 0\n value: null\n","is_delete":false,"is_create":false},{"time":"2026-06-30T15:05:43-04:00","description":"update room 1001","file_path":"data/rooms/intro/1001.yaml","old_content":"block_transport: true\ncolor: \"\"\ndescription:\n - text: |-\n A dim, windowless shuttle interior with a few uncomfortable rows of steel seats facing forward. A large framed sign hangs next to the closed cockpit door. The piston-powered staircase is firmly closed at the rear of the craft.\n\n A dim, windowless shuttle interior with a few uncomfortable rows of steel seats facing forward. A large {11}framed sign{/} hangs next to the closed cockpit door. A piston-powered staircase leads down out the back of the small craft with a smiling attendant ready to help disembark.\nexits:\n down:\n blocked_message: The piston-powered staircase is firmly closed.\n condition:\n all_of: []\n any_of: []\n flag: \"\"\n has_item: \"\"\n min_credits: 0\n not: false\n player_flag: 1001_touchdown\n value: null\n room: 1002\n east:\n room: 2001\nhazard: \"\"\nid: 1001\nitem_spawns: []\nmobs:\n - id: flight_attendant\nname: Inside Transport Shuttle\nobjects:\n - description:\n - text: \"We hope you enjoy your trip on our shuttle! Your pilot is [TYLER].\\n\\nWhen you arrive at your final destination, please be aware of the following basic commands:\\n\\n{0B bold}Movement:{/} {0A}north{/}, {0A}south{/}, {0A}east{/}, {0A}west{/}, {0A}up{/}, {0A}down{/}\\n{0B bold}Look:{/} {0A}look{/}, {0A}look \u003citem/object/mob\u003e{/}, and {0A}map{/}\\n{0B bold}Items:{/} {0A}inv{/} to see your 28-slot inventory\\n {0A}get \u003citem\u003e{/}, {0A}drop \u003citem\u003e{/}, {0A}wear \u003citem\u003e{/}, {0A}remove \u003citem\u003e{/}\\n {0A}use \u003citem\u003e on \u003citem/object\u003e{/}\\n {0A}eq{/} for equiped gear\\n{0B bold}Comms:{/} {0A}talk \u003cmob\u003e{/} for NPC chat\\n {0A}say \u003cmsg\u003e{/} and {0A}global \u003cmsg\u003e{/} for human chat\\n{0B bold}Character:{/} {0A}score{/} and {0A}skills{/} for stats. \\n{0B bold}Combat{/} {0A}attack \u003cmob\u003e{/}\\n{0B bold}Skills{/} Many skills have shortcuts like {0A}mine{/}, {0A}fish{/}, or {0A}chop{/}\\n{0B bold}Options{/} {0A}options{/} for a list of account options\\n {0A}options \u003copt\u003e \u003cvalue\u003e{/} to change an option\\n\\nType {0C bold}what{/} for a list of possible common actions\\n\\nMake sure to check the {0A}help{/} pages, especially {0A}help newplayer{/}!\"\n hidden: true\n name: framed sign\n on_look:\n aps_node: false\n assign_task: false\n cost: 0\n extend_task: false\n give_item: \"\"\n heal: 0\n reputation_cost: 0\n sawmill: false\n set_flags: {}\n set_player_flags:\n 1001_look_sign: true\n shop: null\n skip_task: false\n take_item: \"\"\n teleport: 0\n - description:\n - text: A sturdy, locked steel door that keeps passengers out of the cockpit. There is a tiny, thin window at eye level.\n hidden: true\n name: door\n - description:\n - text: A thick trim with rounded bolt heads frames the tiny window. It looks like it was cut into the door at some point, potentially as a simple replacement to computerized security systems. Inside the cockpit there's a pilot finishing up landing procedures on a large panel of analog instruments.\n hidden: true\n name: window\n - aliases:\n - cockpit\n description:\n - text: The cramped cockpit is surrounded by buttons, swiches, dials, and analog gauges. The parts are a mix of technologies from the last century. Part of the panel is obscured by a draped cloth as if to hide it from view. Odd.\n hidden: true\n name: instrument panel\n - aliases: []\n description:\n - text: That's the guy who took you from the Passenger Barge Denali down here to Vesta. A middle-aged man in a neat white jumpsuit with a matching white sort of conductor's hat. He's following a written procedure checklist and seems to take his job seriously.\n hidden: false\n name: pilot\non_enter:\n - broadcast: \"\"\n broadcast_global: \"\"\n condition:\n all_of: []\n any_of: []\n flag: \"\"\n has_item: \"\"\n min_credits: 0\n not: true\n player_flag: 1001_welcome\n value: null\n delay: 5\n despawn_mob: \"\"\n give_item: \"\"\n heal: 0\n message: '{0B bold}Welcome to The House of Icarus{/}'\n set_flags: {}\n set_player_flags: {}\n spawn_mob: null\n take_item: \"\"\n teleport: 0\n - broadcast: \"\"\n broadcast_global: \"\"\n condition:\n all_of: []\n any_of: []\n flag: \"\"\n has_item: \"\"\n min_credits: 0\n not: true\n player_flag: 1001_welcome\n value: null\n delay: 7\n despawn_mob: \"\"\n give_item: \"\"\n heal: 0\n message: '{0B}Type{/} {0A}look sign{/} {0B}or{/} {0A}talk attendant{/} {0B}to get started{/}'\n set_flags: {}\n set_player_flags:\n 1001_welcome: true\n spawn_mob: null\n take_item: \"\"\n teleport: 0\n - broadcast: \"\"\n broadcast_global: \"\"\n condition:\n all_of: []\n any_of: []\n flag: \"\"\n has_item: \"\"\n min_credits: 0\n not: true\n player_flag: 1001_welcome\n value: null\n delay: 7\n despawn_mob: \"\"\n give_item: \"\"\n heal: 0\n message: '{0B}Type{/} {0A}help newplayer{/} {0B}for the new player''s guide. That''s it. Explore and have fun.{/}'\n set_flags: {}\n set_player_flags: {}\n spawn_mob: null\n take_item: \"\"\n teleport: 0\ntriggers:\n - id: \"\"\n on_flag: \"\"\n on_player_flag: 1001_look_sign\n room: 0\n steps:\n - broadcast: \"\"\n broadcast_global: \"\"\n delay: 5\n despawn_mob: \"\"\n give_item: \"\"\n heal: 0\n message: The cabin shakes as the small craft touches down\n set_flags: {}\n set_player_flags: {}\n spawn_mob: null\n take_item: \"\"\n teleport: 0\n - broadcast: \"\"\n broadcast_global: \"\"\n delay: 5\n despawn_mob: \"\"\n give_item: \"\"\n heal: 0\n message: The pistons hiss as the rear staircase opens\n set_flags: {}\n set_player_flags: {}\n spawn_mob: null\n take_item: \"\"\n teleport: 0\n - broadcast: \"\"\n broadcast_global: \"\"\n delay: 0\n despawn_mob: \"\"\n give_item: \"\"\n heal: 0\n message: \"\"\n set_flags: {}\n set_player_flags:\n 1001_touchdown: true\n spawn_mob: null\n take_item: \"\"\n teleport: 0\n value: null\n","new_content":"block_transport: true\ncolor: \"\"\ndescription:\n - text: |-\n A dim, windowless shuttle interior with a few uncomfortable rows of steel seats facing forward. A large framed sign hangs next to the closed cockpit door. The piston-powered staircase is firmly closed at the rear of the craft.\n\n A dim, windowless shuttle interior with a few uncomfortable rows of steel seats facing forward. A large {11}framed sign{/} hangs next to the closed cockpit door. A piston-powered staircase leads down out the back of the small craft with a smiling attendant ready to help disembark.\nexits:\n down:\n blocked_message: The piston-powered staircase is firmly closed.\n condition:\n all_of: []\n any_of: []\n flag: \"\"\n has_item: \"\"\n min_credits: 0\n not: false\n player_flag: 1001_touchdown\n value: null\n room: 1002\n east:\n room: 2001\nhazard: \"\"\nid: 1001\nitem_spawns: []\nmobs:\n - id: flight_attendant\nname: Inside Transport Shuttle\nobjects:\n - description:\n - text: \"We hope you enjoy your trip on our shuttle! Your pilot is [TYLER].\\n\\nWhen you arrive at your final destination, please be aware of the following basic commands:\\n\\n{0B bold}Movement:{/} {0A}north{/}, {0A}south{/}, {0A}east{/}, {0A}west{/}, {0A}up{/}, {0A}down{/}\\n{0B bold}Look:{/} {0A}look{/}, {0A}look \u003citem/object/mob\u003e{/}, and {0A}map{/}\\n{0B bold}Items:{/} {0A}inv{/} to see your 28-slot inventory\\n {0A}get \u003citem\u003e{/}, {0A}drop \u003citem\u003e{/}, {0A}wear \u003citem\u003e{/}, {0A}remove \u003citem\u003e{/}\\n {0A}use \u003citem\u003e on \u003citem/object\u003e{/}\\n {0A}eq{/} for equiped gear\\n{0B bold}Comms:{/} {0A}talk \u003cmob\u003e{/} for NPC chat\\n {0A}say \u003cmsg\u003e{/} and {0A}global \u003cmsg\u003e{/} for human chat\\n{0B bold}Character:{/} {0A}score{/} and {0A}skills{/} for stats. \\n{0B bold}Combat{/} {0A}attack \u003cmob\u003e{/}\\n{0B bold}Skills{/} Many skills have shortcuts like {0A}mine{/}, {0A}fish{/}, or {0A}chop{/}\\n{0B bold}Options{/} {0A}options{/} for a list of account options\\n {0A}options \u003copt\u003e \u003cvalue\u003e{/} to change an option\\n\\nType {0C bold}what{/} for a list of possible common actions\\n\\nMake sure to check the {0A}help{/} pages, especially {0A}help newplayer{/}!\"\n hidden: true\n name: framed sign\n on_look:\n aps_node: false\n assign_task: false\n cost: 0\n extend_task: false\n give_item: \"\"\n heal: 0\n reputation_cost: 0\n sawmill: false\n set_flags: {}\n set_player_flags:\n 1001_look_sign: true\n shop: null\n skip_task: false\n take_item: \"\"\n teleport: 0\n - description:\n - text: A sturdy, locked steel door that keeps passengers out of the cockpit. There is a tiny, thin window at eye level.\n hidden: true\n name: door\n - description:\n - text: A thick trim with rounded bolt heads frames the tiny window. It looks like it was cut into the door at some point, potentially as a simple replacement to computerized security systems. Inside the cockpit there's a pilot finishing up landing procedures on a large panel of analog instruments.\n hidden: true\n name: window\n - aliases:\n - cockpit\n description:\n - text: The cramped cockpit is surrounded by buttons, swiches, dials, and analog gauges. The parts are a mix of technologies from the last century. Part of the panel is obscured by a draped cloth as if to hide it from view. Odd.\n hidden: true\n name: instrument panel\n - aliases: []\n description:\n - text: That's the guy who took you from the Passenger Barge Denali down here to Vesta. A middle-aged man in a neat white jumpsuit with a matching white sort of conductor's hat. He's following a written procedure checklist and seems to take his job seriously.\n hidden: true\n name: pilot\non_enter:\n - broadcast: \"\"\n broadcast_global: \"\"\n condition:\n all_of: []\n any_of: []\n flag: \"\"\n has_item: \"\"\n min_credits: 0\n not: true\n player_flag: 1001_welcome\n value: null\n delay: 5\n despawn_mob: \"\"\n give_item: \"\"\n heal: 0\n message: '{0B bold}Welcome to The House of Icarus{/}'\n set_flags: {}\n set_player_flags: {}\n spawn_mob: null\n take_item: \"\"\n teleport: 0\n - broadcast: \"\"\n broadcast_global: \"\"\n condition:\n all_of: []\n any_of: []\n flag: \"\"\n has_item: \"\"\n min_credits: 0\n not: true\n player_flag: 1001_welcome\n value: null\n delay: 7\n despawn_mob: \"\"\n give_item: \"\"\n heal: 0\n message: '{0B}Type{/} {0A}look sign{/} {0B}or{/} {0A}talk attendant{/} {0B}to get started{/}'\n set_flags: {}\n set_player_flags:\n 1001_welcome: true\n spawn_mob: null\n take_item: \"\"\n teleport: 0\n - broadcast: \"\"\n broadcast_global: \"\"\n condition:\n all_of: []\n any_of: []\n flag: \"\"\n has_item: \"\"\n min_credits: 0\n not: true\n player_flag: 1001_welcome\n value: null\n delay: 7\n despawn_mob: \"\"\n give_item: \"\"\n heal: 0\n message: '{0B}Type{/} {0A}help newplayer{/} {0B}for the new player''s guide. That''s it. Explore and have fun.{/}'\n set_flags: {}\n set_player_flags: {}\n spawn_mob: null\n take_item: \"\"\n teleport: 0\ntriggers:\n - id: \"\"\n on_flag: \"\"\n on_player_flag: 1001_look_sign\n room: 0\n steps:\n - broadcast: \"\"\n broadcast_global: \"\"\n delay: 5\n despawn_mob: \"\"\n give_item: \"\"\n heal: 0\n message: The cabin shakes as the small craft touches down\n set_flags: {}\n set_player_flags: {}\n spawn_mob: null\n take_item: \"\"\n teleport: 0\n - broadcast: \"\"\n broadcast_global: \"\"\n delay: 5\n despawn_mob: \"\"\n give_item: \"\"\n heal: 0\n message: The pistons hiss as the rear staircase opens\n set_flags: {}\n set_player_flags: {}\n spawn_mob: null\n take_item: \"\"\n teleport: 0\n - broadcast: \"\"\n broadcast_global: \"\"\n delay: 0\n despawn_mob: \"\"\n give_item: \"\"\n heal: 0\n message: \"\"\n set_flags: {}\n set_player_flags:\n 1001_touchdown: true\n spawn_mob: null\n take_item: \"\"\n teleport: 0\n value: null\n","is_delete":false,"is_create":false},{"time":"2026-06-30T16:34:21-04:00","description":"update room 2001","file_path":"data/rooms/intro/2001.yaml","old_content":"block_transport: false\ncolor: \"\"\ndescription:\n - text: It's a test room\nexits:\n east:\n room: 2002\n south:\n room: 2006\n southeast:\n room: 2005\n west:\n room: 1001\nhazard: \"\"\nid: 2001\nitem_spawns: []\nmobs: []\nname: Test Room\nobjects: []\non_enter: []\ntriggers: []\n","new_content":"block_transport: false\ncolor: \"\"\ndescription:\n - text: It's a test room\nexits:\n east:\n room: 2002\n south:\n room: 2006\n southeast:\n room: 2005\n west:\n room: 1001\nhazard: \"\"\nid: 2001\nitem_spawns: []\nmobs: []\nname: Test Room\nobjects:\n - id: tree\non_enter: []\ntriggers: []\n","is_delete":false,"is_create":false},{"time":"2026-06-30T16:35:02-04:00","description":"update room 2001","file_path":"data/rooms/intro/2001.yaml","old_content":"block_transport: false\ncolor: \"\"\ndescription:\n - text: It's a test room\nexits:\n east:\n room: 2002\n south:\n room: 2006\n southeast:\n room: 2005\n west:\n room: 1001\nhazard: \"\"\nid: 2001\nitem_spawns: []\nmobs: []\nname: Test Room\nobjects:\n - id: tree\non_enter: []\ntriggers: []\n","new_content":"block_transport: false\ncolor: \"\"\ndescription:\n - text: It's a test room\nexits:\n east:\n room: 2002\n south:\n room: 2006\n southeast:\n room: 2005\n west:\n room: 1001\nhazard: \"\"\nid: 2001\nitem_spawns:\n - id: bronze_axe\n quantity: 1\n respawn_ticks: 0\nmobs: []\nname: Test Room\nobjects:\n - id: tree\non_enter: []\ntriggers: []\n","is_delete":false,"is_create":false},{"time":"2026-06-30T16:35:15-04:00","description":"update room 2001","file_path":"data/rooms/intro/2001.yaml","old_content":"block_transport: false\ncolor: \"\"\ndescription:\n - text: It's a test room\nexits:\n east:\n room: 2002\n south:\n room: 2006\n southeast:\n room: 2005\n west:\n room: 1001\nhazard: \"\"\nid: 2001\nitem_spawns:\n - id: bronze_axe\n quantity: 1\n respawn_ticks: 0\nmobs: []\nname: Test Room\nobjects:\n - id: tree\non_enter: []\ntriggers: []\n","new_content":"block_transport: false\ncolor: \"\"\ndescription:\n - text: It's a test room\nexits:\n east:\n room: 2002\n south:\n room: 2006\n southeast:\n room: 2005\n west:\n room: 1001\nhazard: \"\"\nid: 2001\nitem_spawns:\n - id: bronze_axe\n quantity: 1\n respawn_ticks: 1\nmobs: []\nname: Test Room\nobjects:\n - id: tree\non_enter: []\ntriggers: []\n","is_delete":false,"is_create":false},{"time":"2026-06-30T17:43:28-04:00","description":"Update object copper_rock","file_path":"data/objects/copper_rock.yaml","old_content":"color: \"B2\"\ngather:\n depleted_message: You don't see any ore in this rock.\n drops:\n - depletes: true\n item_id: copper_ore\n level: 1\n message: You manage to mine some {B2}copper ore{/}.\n weight: 90\n xp: 17\n - depletes: false\n message: You spot a glint of something valuable!\n table: gem_table\n weight: 10\n fail_message: You chip away but get nothing useful.\n gather_message: You swing your pickaxe at the rock...\n respawn_broadcast: A glint of copper catches your eye from some {name}.\n respawn_timer: 50\n skill: mining\n success:\n base: 0.5\n cap: 0.95\n per_level: 0.01\n tools:\n - pickaxe\nname: copper rock\n","new_content":"aliases: []\ncolor: B2\ndescription: \"\"\ngather:\n bait: \"\"\n deplete_timer: 0\n depleted_message: You don't see any ore in this rock.\n drops:\n - depletes: true\n item_id: copper_ore\n level: 1\n message: You manage to mine some {B2}copper ore{/}.\n quantity: 0\n table: \"\"\n weight: 90\n xp: 17\n - depletes: false\n item_id: \"\"\n level: 0\n message: You spot a glint of something valuable!\n quantity: 0\n table: gem_table\n weight: 10\n xp: 0\n exhausted_message: \"\"\n fail_message: You chip away but get nothing useful.\n gather_message: You swing your pickaxe at the rock...\n nest_chance: 0\n respawn_broadcast: A glint of copper catches your eye from some {name}.\n respawn_timer: 50\n skill: mining\n success:\n base: 0.5\n cap: 0.95\n per_level: 0.01\n tools:\n - pickaxe\nhidden: false\nid: copper_rock\ninroom_description: \"\"\nname: copper rock\nremoval_item: \"\"\n","is_delete":false,"is_create":false},{"time":"2026-06-30T23:48:18-04:00","description":"update room 2001","file_path":"data/rooms/intro/2001.yaml","old_content":"block_transport: false\ncolor: \"\"\ndescription:\n - text: It's a test room\nexits:\n east:\n room: 2002\n south:\n room: 2006\n southeast:\n room: 2005\n west:\n room: 1001\nhazard: \"\"\nid: 2001\nitem_spawns:\n - id: bronze_axe\n quantity: 1\n respawn_ticks: 1\nmobs: []\nname: Test Room\nobjects:\n - id: tree\non_enter: []\ntriggers: []\n","new_content":"block_transport: false\ncolor: \"\"\ndescription:\n - text: It's a test room\nexits:\n east:\n room: 2002\n south:\n room: 2006\n southeast:\n room: 2005\n west:\n room: 1001\nhazard: \"\"\nid: 2001\nitem_spawns:\n - id: bronze_axe\n quantity: 1\n respawn_ticks: 1\n - id: pot_of_flour\n quantity: 1\n respawn_ticks: 0\nmobs: []\nname: Test Room\nobjects:\n - id: tree\non_enter: []\ntriggers: []\n","is_delete":false,"is_create":false},{"time":"2026-06-30T23:48:23-04:00","description":"update room 2001","file_path":"data/rooms/intro/2001.yaml","old_content":"block_transport: false\ncolor: \"\"\ndescription:\n - text: It's a test room\nexits:\n east:\n room: 2002\n south:\n room: 2006\n southeast:\n room: 2005\n west:\n room: 1001\nhazard: \"\"\nid: 2001\nitem_spawns:\n - id: bronze_axe\n quantity: 1\n respawn_ticks: 1\n - id: pot_of_flour\n quantity: 1\n respawn_ticks: 0\nmobs: []\nname: Test Room\nobjects:\n - id: tree\non_enter: []\ntriggers: []\n","new_content":"block_transport: false\ncolor: \"\"\ndescription:\n - text: It's a test room\nexits:\n east:\n room: 2002\n south:\n room: 2006\n southeast:\n room: 2005\n west:\n room: 1001\nhazard: \"\"\nid: 2001\nitem_spawns:\n - id: bronze_axe\n quantity: 1\n respawn_ticks: 1\n - id: pot_of_flour\n quantity: 1\n respawn_ticks: 0\n - id: bucket_of_water\n quantity: 1\n respawn_ticks: 0\nmobs: []\nname: Test Room\nobjects:\n - id: tree\non_enter: []\ntriggers: []\n","is_delete":false,"is_create":false},{"time":"2026-06-30T23:53:08-04:00","description":"Update item bread_dough","file_path":"data/items/consumables/bread_dough.yaml","old_content":"color: \"DE\"\ncraft:\n type: combine\n consume:\n - byproducts:\n - empty_pot\n items:\n - pot_of_flour\n quantity: 1\n - byproducts:\n - empty_bucket\n - empty_jug\n items:\n - bucket_of_water\n - jug_of_water\n quantity: 1\n wait: 2\ndescription: A ball of uncooked bread dough. It needs to be baked.\nname: bread dough\nstackable: false\nvalue: 3\n","new_content":"color: DE\ncraft:\n - consume:\n - byproducts:\n - empty_pot\n items:\n - pot_of_flour\n quantity: 1\n - byproducts:\n - empty_bucket\n - empty_jug\n items:\n - bucket_of_water\n - jug_of_water\n quantity: 1\n end_message: testend\n fail: \"\"\n level: 0\n message: testmsg\n output_qty: 0\n start_message: teststart\n station: []\n subtype: \"\"\n tool: \"\"\n type: combine\n wait: 2\n xp: 0\ndescription: A ball of uncooked bread dough. It needs to be baked.\nid: bread_dough\nmax_quality: 0\nname: bread dough\nquality: 0\nstackable: false\nvalue: 3\n","is_delete":false,"is_create":false},{"time":"2026-07-01T00:23:04-04:00","description":"Update item bread_dough","file_path":"data/items/consumables/bread_dough.yaml","old_content":"color: DE\ncraft:\n - consume:\n - byproducts:\n - empty_pot\n items:\n - pot_of_flour\n quantity: 1\n - byproducts:\n - empty_bucket\n - empty_jug\n items:\n - bucket_of_water\n - jug_of_water\n quantity: 1\n end_message: testend\n fail: \"\"\n level: 0\n message: testmsg\n output_qty: 0\n start_message: teststart\n station: []\n subtype: \"\"\n tool: \"\"\n type: combine\n wait: 2\n xp: 0\ndescription: A ball of uncooked bread dough. It needs to be baked.\nid: bread_dough\nmax_quality: 0\nname: bread dough\nquality: 0\nstackable: false\nvalue: 3\n","new_content":"color: DE\ncraft:\n - consume:\n - byproducts:\n - empty_pot\n items:\n - pot_of_flour\n quantity: 1\n - byproducts:\n - empty_bucket\n - empty_jug\n items:\n - bucket_of_water\n - jug_of_water\n quantity: 1\n end_message: testend\n fail: \"\"\n level: 0\n message: testmsg\n output_qty: 0\n start_message: teststart\n station: []\n subtype: \"\"\n tool: \"\"\n type: combine\n wait: 2\n xp: 0\ndescription: A ball of uncooked bread dough. It needs to be baked.\nid: bread_dough\nmax_quality: 0\nname: bread dough\nquality: 0\nstackable: false\nvalue: 3\n","is_delete":false,"is_create":false},{"time":"2026-07-01T01:22:55-04:00","description":"update room 1001","file_path":"data/rooms/intro/1001.yaml","old_content":"block_transport: true\ncolor: \"\"\ndescription:\n - text: |-\n A dim, windowless shuttle interior with a few uncomfortable rows of steel seats facing forward. A large framed sign hangs next to the closed cockpit door. The piston-powered staircase is firmly closed at the rear of the craft.\n\n A dim, windowless shuttle interior with a few uncomfortable rows of steel seats facing forward. A large {11}framed sign{/} hangs next to the closed cockpit door. A piston-powered staircase leads down out the back of the small craft with a smiling attendant ready to help disembark.\nexits:\n down:\n blocked_message: The piston-powered staircase is firmly closed.\n condition:\n all_of: []\n any_of: []\n flag: \"\"\n has_item: \"\"\n min_credits: 0\n not: false\n player_flag: 1001_touchdown\n value: null\n room: 1002\n east:\n room: 2001\nhazard: \"\"\nid: 1001\nitem_spawns: []\nmobs:\n - id: flight_attendant\nname: Inside Transport Shuttle\nobjects:\n - description:\n - text: \"We hope you enjoy your trip on our shuttle! Your pilot is [TYLER].\\n\\nWhen you arrive at your final destination, please be aware of the following basic commands:\\n\\n{0B bold}Movement:{/} {0A}north{/}, {0A}south{/}, {0A}east{/}, {0A}west{/}, {0A}up{/}, {0A}down{/}\\n{0B bold}Look:{/} {0A}look{/}, {0A}look \u003citem/object/mob\u003e{/}, and {0A}map{/}\\n{0B bold}Items:{/} {0A}inv{/} to see your 28-slot inventory\\n {0A}get \u003citem\u003e{/}, {0A}drop \u003citem\u003e{/}, {0A}wear \u003citem\u003e{/}, {0A}remove \u003citem\u003e{/}\\n {0A}use \u003citem\u003e on \u003citem/object\u003e{/}\\n {0A}eq{/} for equiped gear\\n{0B bold}Comms:{/} {0A}talk \u003cmob\u003e{/} for NPC chat\\n {0A}say \u003cmsg\u003e{/} and {0A}global \u003cmsg\u003e{/} for human chat\\n{0B bold}Character:{/} {0A}score{/} and {0A}skills{/} for stats. \\n{0B bold}Combat{/} {0A}attack \u003cmob\u003e{/}\\n{0B bold}Skills{/} Many skills have shortcuts like {0A}mine{/}, {0A}fish{/}, or {0A}chop{/}\\n{0B bold}Options{/} {0A}options{/} for a list of account options\\n {0A}options \u003copt\u003e \u003cvalue\u003e{/} to change an option\\n\\nType {0C bold}what{/} for a list of possible common actions\\n\\nMake sure to check the {0A}help{/} pages, especially {0A}help newplayer{/}!\"\n hidden: true\n name: framed sign\n on_look:\n aps_node: false\n assign_task: false\n cost: 0\n extend_task: false\n give_item: \"\"\n heal: 0\n reputation_cost: 0\n sawmill: false\n set_flags: {}\n set_player_flags:\n 1001_look_sign: true\n shop: null\n skip_task: false\n take_item: \"\"\n teleport: 0\n - description:\n - text: A sturdy, locked steel door that keeps passengers out of the cockpit. There is a tiny, thin window at eye level.\n hidden: true\n name: door\n - description:\n - text: A thick trim with rounded bolt heads frames the tiny window. It looks like it was cut into the door at some point, potentially as a simple replacement to computerized security systems. Inside the cockpit there's a pilot finishing up landing procedures on a large panel of analog instruments.\n hidden: true\n name: window\n - aliases:\n - cockpit\n description:\n - text: The cramped cockpit is surrounded by buttons, swiches, dials, and analog gauges. The parts are a mix of technologies from the last century. Part of the panel is obscured by a draped cloth as if to hide it from view. Odd.\n hidden: true\n name: instrument panel\n - aliases: []\n description:\n - text: That's the guy who took you from the Passenger Barge Denali down here to Vesta. A middle-aged man in a neat white jumpsuit with a matching white sort of conductor's hat. He's following a written procedure checklist and seems to take his job seriously.\n hidden: true\n name: pilot\non_enter:\n - broadcast: \"\"\n broadcast_global: \"\"\n condition:\n all_of: []\n any_of: []\n flag: \"\"\n has_item: \"\"\n min_credits: 0\n not: true\n player_flag: 1001_welcome\n value: null\n delay: 5\n despawn_mob: \"\"\n give_item: \"\"\n heal: 0\n message: '{0B bold}Welcome to The House of Icarus{/}'\n set_flags: {}\n set_player_flags: {}\n spawn_mob: null\n take_item: \"\"\n teleport: 0\n - broadcast: \"\"\n broadcast_global: \"\"\n condition:\n all_of: []\n any_of: []\n flag: \"\"\n has_item: \"\"\n min_credits: 0\n not: true\n player_flag: 1001_welcome\n value: null\n delay: 7\n despawn_mob: \"\"\n give_item: \"\"\n heal: 0\n message: '{0B}Type{/} {0A}look sign{/} {0B}or{/} {0A}talk attendant{/} {0B}to get started{/}'\n set_flags: {}\n set_player_flags:\n 1001_welcome: true\n spawn_mob: null\n take_item: \"\"\n teleport: 0\n - broadcast: \"\"\n broadcast_global: \"\"\n condition:\n all_of: []\n any_of: []\n flag: \"\"\n has_item: \"\"\n min_credits: 0\n not: true\n player_flag: 1001_welcome\n value: null\n delay: 7\n despawn_mob: \"\"\n give_item: \"\"\n heal: 0\n message: '{0B}Type{/} {0A}help newplayer{/} {0B}for the new player''s guide. That''s it. Explore and have fun.{/}'\n set_flags: {}\n set_player_flags: {}\n spawn_mob: null\n take_item: \"\"\n teleport: 0\ntriggers:\n - id: \"\"\n on_flag: \"\"\n on_player_flag: 1001_look_sign\n room: 0\n steps:\n - broadcast: \"\"\n broadcast_global: \"\"\n delay: 5\n despawn_mob: \"\"\n give_item: \"\"\n heal: 0\n message: The cabin shakes as the small craft touches down\n set_flags: {}\n set_player_flags: {}\n spawn_mob: null\n take_item: \"\"\n teleport: 0\n - broadcast: \"\"\n broadcast_global: \"\"\n delay: 5\n despawn_mob: \"\"\n give_item: \"\"\n heal: 0\n message: The pistons hiss as the rear staircase opens\n set_flags: {}\n set_player_flags: {}\n spawn_mob: null\n take_item: \"\"\n teleport: 0\n - broadcast: \"\"\n broadcast_global: \"\"\n delay: 0\n despawn_mob: \"\"\n give_item: \"\"\n heal: 0\n message: \"\"\n set_flags: {}\n set_player_flags:\n 1001_touchdown: true\n spawn_mob: null\n take_item: \"\"\n teleport: 0\n value: null\n","new_content":"block_transport: true\ncolor: \"\"\ndescription:\n - text: |-\n A dim, windowless shuttle interior with a few uncomfortable rows of steel seats facing forward. A large framed sign hangs next to the closed cockpit door. The piston-powered staircase is firmly closed at the rear of the craft.\n\n A dim, windowless shuttle interior with a few uncomfortable rows of steel seats facing forward. A large {11}framed sign{/} hangs next to the closed cockpit door. A piston-powered staircase leads down out the back of the small craft with a smiling attendant ready to help disembark.\nexits:\n down:\n blocked_message: The piston-powered staircase is firmly closed.\n condition:\n all_of: []\n any_of: []\n flag: \"\"\n has_item: \"\"\n min_credits: 0\n not: false\n player_flag: 1001_touchdown\n value: null\n room: 1002\n east:\n room: 2001\nhazard: \"\"\nid: 1001\nitem_spawns: []\nmobs:\n - id: flight_attendant\nname: Inside Transport Shuttle\nobjects:\n - description:\n - text: \"We hope you enjoy your trip on our shuttle! Your pilot is [TYLER].\\n\\nWhen you arrive at your final destination, please be aware of the following basic commands:\\n\\n{0B bold}Movement:{/} {0A}north{/}, {0A}south{/}, {0A}east{/}, {0A}west{/}, {0A}up{/}, {0A}down{/}\\n{0B bold}Look:{/} {0A}look{/}, {0A}look \u003citem/object/mob\u003e{/}, and {0A}map{/}\\n{0B bold}Items:{/} {0A}inv{/} to see your 28-slot inventory\\n {0A}get \u003citem\u003e{/}, {0A}drop \u003citem\u003e{/}, {0A}wear \u003citem\u003e{/}, {0A}remove \u003citem\u003e{/}\\n {0A}use \u003citem\u003e on \u003citem/object\u003e{/}\\n {0A}eq{/} for equiped gear\\n{0B bold}Comms:{/} {0A}talk \u003cmob\u003e{/} for NPC chat\\n {0A}say \u003cmsg\u003e{/} and {0A}global \u003cmsg\u003e{/} for human chat\\n{0B bold}Character:{/} {0A}score{/} and {0A}skills{/} for stats. \\n{0B bold}Combat{/} {0A}attack \u003cmob\u003e{/}\\n{0B bold}Skills{/} Many skills have shortcuts like {0A}mine{/}, {0A}fish{/}, or {0A}chop{/}\\n{0B bold}Options{/} {0A}options{/} for a list of account options\\n {0A}options \u003copt\u003e \u003cvalue\u003e{/} to change an option\\n\\nType {0C bold}what{/} for a list of possible common actions\\n\\nMake sure to check the {0A}help{/} pages, especially {0A}help newplayer{/}!\"\n hidden: true\n name: framed sign\n on_look:\n aps_node: false\n assign_task: false\n cost: 0\n extend_task: false\n give_item: \"\"\n heal: 0\n reputation_cost: 0\n sawmill: false\n set_flags: {}\n set_player_flags:\n 1001_look_sign: true\n shop: null\n skip_task: false\n take_item: \"\"\n teleport: 0\n - description:\n - text: A sturdy, locked steel door that keeps passengers out of the cockpit. There is a tiny, thin window at eye level.\n hidden: true\n name: door\n - description:\n - text: A thick trim with rounded bolt heads frames the tiny window. It looks like it was cut into the door at some point, potentially as a simple replacement to computerized security systems. Inside the cockpit there's a pilot finishing up landing procedures on a large panel of analog instruments.\n hidden: true\n name: window\n - aliases:\n - cockpit\n description:\n - text: The cramped cockpit is surrounded by buttons, swiches, dials, and analog gauges. The parts are a mix of technologies from the last century. Part of the panel is obscured by a draped cloth as if to hide it from view. Odd.\n hidden: true\n name: instrument panel\n - aliases: []\n description:\n - text: That's the guy who took you from the Passenger Barge Denali down here to Vesta. A middle-aged man in a neat white jumpsuit with a matching white sort of conductor's hat. He's following a written procedure checklist and seems to take his job seriously.\n hidden: true\n name: pilot\non_enter:\n - broadcast: \"\"\n broadcast_global: \"\"\n condition:\n all_of: []\n any_of: []\n flag: \"\"\n has_item: \"\"\n min_credits: 0\n not: true\n player_flag: 1001_welcome\n value: null\n delay: 5\n despawn_mob: \"\"\n give_item: \"\"\n heal: 0\n message: '{0B bold}Welcome to The House of Icarus{/}'\n set_flags: {}\n set_player_flags: {}\n spawn_mob: null\n take_item: \"\"\n teleport: 0\n - broadcast: \"\"\n broadcast_global: \"\"\n condition:\n all_of: []\n any_of: []\n flag: \"\"\n has_item: \"\"\n min_credits: 0\n not: true\n player_flag: 1001_welcome\n value: null\n delay: 7\n despawn_mob: \"\"\n give_item: \"\"\n heal: 0\n message: '{0B}Type{/} {0A}look sign{/} {0B}or{/} {0A}talk attendant{/} {0B}to get started{/}'\n set_flags: {}\n set_player_flags:\n 1001_welcome: true\n spawn_mob: null\n take_item: \"\"\n teleport: 0\n - broadcast: \"\"\n broadcast_global: \"\"\n condition:\n all_of: []\n any_of: []\n flag: \"\"\n has_item: \"\"\n min_credits: 0\n not: true\n player_flag: 1001_welcome\n value: null\n delay: 7\n despawn_mob: \"\"\n give_item: \"\"\n heal: 0\n message: '{0B}Type{/} {0A}help newplayer{/} {0B}for the new player''s guide. That''s it. Explore and have fun.{/}'\n set_flags: {}\n set_player_flags: {}\n spawn_mob: null\n take_item: \"\"\n teleport: 0\ntriggers:\n - id: \"\"\n on_flag: \"\"\n on_player_flag: 1001_look_sign\n room: 0\n steps:\n - broadcast: \"\"\n broadcast_global: \"\"\n delay: 5\n despawn_mob: \"\"\n give_item: \"\"\n heal: 0\n message: The cabin shakes as the small craft touches down\n set_flags: {}\n set_player_flags: {}\n spawn_mob: null\n take_item: \"\"\n teleport: 0\n - broadcast: \"\"\n broadcast_global: \"\"\n delay: 5\n despawn_mob: \"\"\n give_item: \"\"\n heal: 0\n message: The pistons hiss as the rear staircase opens\n set_flags: {}\n set_player_flags: {}\n spawn_mob: null\n take_item: \"\"\n teleport: 0\n - broadcast: \"\"\n broadcast_global: \"\"\n delay: 0\n despawn_mob: \"\"\n give_item: \"\"\n heal: 0\n message: \"\"\n set_flags: {}\n set_player_flags:\n 1001_touchdown: true\n spawn_mob: null\n take_item: \"\"\n teleport: 0\n value: null\n","is_delete":false,"is_create":false},{"time":"2026-07-01T03:00:10-04:00","description":"update room 2001","file_path":"data/rooms/intro/2001.yaml","old_content":"block_transport: false\ncolor: \"\"\ndescription:\n - text: It's a test room\nexits:\n east:\n room: 2002\n south:\n room: 2006\n southeast:\n room: 2005\n west:\n room: 1001\nhazard: \"\"\nid: 2001\nitem_spawns:\n - id: bronze_axe\n quantity: 1\n respawn_ticks: 1\n - id: pot_of_flour\n quantity: 1\n respawn_ticks: 0\n - id: bucket_of_water\n quantity: 1\n respawn_ticks: 0\nmobs: []\nname: Test Room\nobjects:\n - id: tree\non_enter: []\ntriggers: []\n","new_content":"block_transport: false\ncolor: \"\"\ndescription:\n - text: It's a test room\nexits:\n east:\n room: 2002\n south:\n room: 2006\n southeast:\n room: 2005\n west:\n room: 1001\nhazard: \"\"\nid: 2001\nitem_spawns:\n - id: bronze_axe\n quantity: 1\n respawn_ticks: 1\n - id: pot_of_flour\n quantity: 1\n respawn_ticks: 1\n - id: bucket_of_water\n quantity: 1\n respawn_ticks: 0\nmobs: []\nname: Test Room\nobjects:\n - id: tree\non_enter: []\ntriggers: []\n","is_delete":false,"is_create":false},{"time":"2026-07-01T03:00:11-04:00","description":"update room 2001","file_path":"data/rooms/intro/2001.yaml","old_content":"block_transport: false\ncolor: \"\"\ndescription:\n - text: It's a test room\nexits:\n east:\n room: 2002\n south:\n room: 2006\n southeast:\n room: 2005\n west:\n room: 1001\nhazard: \"\"\nid: 2001\nitem_spawns:\n - id: bronze_axe\n quantity: 1\n respawn_ticks: 1\n - id: pot_of_flour\n quantity: 1\n respawn_ticks: 1\n - id: bucket_of_water\n quantity: 1\n respawn_ticks: 0\nmobs: []\nname: Test Room\nobjects:\n - id: tree\non_enter: []\ntriggers: []\n","new_content":"block_transport: false\ncolor: \"\"\ndescription:\n - text: It's a test room\nexits:\n east:\n room: 2002\n south:\n room: 2006\n southeast:\n room: 2005\n west:\n room: 1001\nhazard: \"\"\nid: 2001\nitem_spawns:\n - id: bronze_axe\n quantity: 1\n respawn_ticks: 1\n - id: pot_of_flour\n quantity: 1\n respawn_ticks: 1\n - id: bucket_of_water\n quantity: 1\n respawn_ticks: 1\nmobs: []\nname: Test Room\nobjects:\n - id: tree\non_enter: []\ntriggers: []\n","is_delete":false,"is_create":false}],"redo":null} \ No newline at end of file diff --git a/data/items/ammo/headless_arrow.yaml b/data/items/ammo/headless_arrow.yaml index 61ad40f..ca62b1d 100644 --- a/data/items/ammo/headless_arrow.yaml +++ b/data/items/ammo/headless_arrow.yaml @@ -8,7 +8,7 @@ craft: - feather quantity: 15 level: 1 - message: "You attach feathers to the %i1." + success_message: "You attach feathers to the %i1." output_qty: 15 type: fletching wait: 2 diff --git a/data/items/consumables/bread.yaml b/data/items/consumables/bread.yaml index 1f8a996..6ded8b0 100644 --- a/data/items/consumables/bread.yaml +++ b/data/items/consumables/bread.yaml @@ -7,7 +7,7 @@ craft: fail: burnt_meat fail_message: You burn the bread to a crisp. level: 1 - message: "You bake the dough into a %n." + success_message: "You bake the dough into a %n." station: - cooking_range type: cooking diff --git a/data/items/consumables/bread_dough.yaml b/data/items/consumables/bread_dough.yaml index 48fa986..cce972d 100644 --- a/data/items/consumables/bread_dough.yaml +++ b/data/items/consumables/bread_dough.yaml @@ -16,7 +16,7 @@ craft: end_message: testend fail: "" level: 0 - message: testmsg + success_message: testmsg output_qty: 0 start_message: teststart station: [] diff --git a/data/items/consumables/guam_potion_unf.yaml b/data/items/consumables/guam_potion_unf.yaml index dc963ed..b758ac1 100644 --- a/data/items/consumables/guam_potion_unf.yaml +++ b/data/items/consumables/guam_potion_unf.yaml @@ -9,7 +9,7 @@ craft: - vial_of_water quantity: 1 wait: 0 - message: "You mix %i1 and %i2 into %n!!!" + success_message: "You mix %i1 and %i2 into %n!!!" description: An unfinished potion with guam floating in water. name: guam potion (unf) stackable: false diff --git a/data/items/consumables/pie_dish.yaml b/data/items/consumables/pie_dish.yaml index 89d82e4..959cb65 100644 --- a/data/items/consumables/pie_dish.yaml +++ b/data/items/consumables/pie_dish.yaml @@ -6,7 +6,7 @@ craft: quantity: 1 fail_message: The pie dish cracks in the oven and is ruined. level: 7 - message: "You fire the %i1 in the oven." + success_message: "You fire the %i1 in the oven." station: - pottery_oven success: diff --git a/data/items/materials/ball_of_wool.yaml b/data/items/materials/ball_of_wool.yaml index d074203..5dc1a2d 100644 --- a/data/items/materials/ball_of_wool.yaml +++ b/data/items/materials/ball_of_wool.yaml @@ -5,7 +5,7 @@ craft: - wool quantity: 1 level: 1 - message: "You spin the wool into a %n." + success_message: "You spin the wool into a %n." station: - spinning_wheel type: crafting diff --git a/data/items/materials/bowstring.yaml b/data/items/materials/bowstring.yaml index fab0510..e0f63b3 100644 --- a/data/items/materials/bowstring.yaml +++ b/data/items/materials/bowstring.yaml @@ -5,7 +5,7 @@ craft: - flax quantity: 1 level: 1 - message: "You spin the flax into a %n." + success_message: "You spin the flax into a %n." station: - spinning_wheel type: crafting diff --git a/data/items/materials/diamond.yaml b/data/items/materials/diamond.yaml index 4bf610a..0e8fe92 100644 --- a/data/items/materials/diamond.yaml +++ b/data/items/materials/diamond.yaml @@ -5,7 +5,7 @@ craft: - uncut_diamond quantity: 1 level: 43 - message: "You cut the %i1 into a beautiful %n." + success_message: "You cut the %i1 into a beautiful %n." tool: chisel type: crafting wait: 3 diff --git a/data/items/materials/emerald.yaml b/data/items/materials/emerald.yaml index 5d729cd..a39257c 100644 --- a/data/items/materials/emerald.yaml +++ b/data/items/materials/emerald.yaml @@ -5,7 +5,7 @@ craft: - uncut_emerald quantity: 1 level: 27 - message: "You cut the %i1 into a beautiful %n." + success_message: "You cut the %i1 into a beautiful %n." tool: chisel type: crafting wait: 3 diff --git a/data/items/materials/mahogany_planks.yaml b/data/items/materials/mahogany_planks.yaml index a3f3e0b..e75ec1c 100644 --- a/data/items/materials/mahogany_planks.yaml +++ b/data/items/materials/mahogany_planks.yaml @@ -5,7 +5,7 @@ craft: - mahogany_logs quantity: 1 level: 50 - message: "You saw the mahogany logs into %n." + success_message: "You saw the mahogany logs into %n." station: - workbench tool: saw diff --git a/data/items/materials/oak_planks.yaml b/data/items/materials/oak_planks.yaml index 82e5504..6b2571c 100644 --- a/data/items/materials/oak_planks.yaml +++ b/data/items/materials/oak_planks.yaml @@ -5,7 +5,7 @@ craft: - oak_logs quantity: 1 level: 15 - message: "You saw the oak logs into %n." + success_message: "You saw the oak logs into %n." station: - workbench tool: saw diff --git a/data/items/materials/planks.yaml b/data/items/materials/planks.yaml index d2ad6c2..b616120 100644 --- a/data/items/materials/planks.yaml +++ b/data/items/materials/planks.yaml @@ -5,7 +5,7 @@ craft: - logs quantity: 1 level: 1 - message: "You saw the logs into %n." + success_message: "You saw the logs into %n." station: - workbench tool: saw diff --git a/data/items/materials/ruby.yaml b/data/items/materials/ruby.yaml index eb7968b..6a2b18f 100644 --- a/data/items/materials/ruby.yaml +++ b/data/items/materials/ruby.yaml @@ -5,7 +5,7 @@ craft: - uncut_ruby quantity: 1 level: 63 - message: "You cut the %i1 into a beautiful %n." + success_message: "You cut the %i1 into a beautiful %n." tool: chisel type: crafting wait: 3 diff --git a/data/items/materials/sapphire.yaml b/data/items/materials/sapphire.yaml index bc73cd9..9a5a7d6 100644 --- a/data/items/materials/sapphire.yaml +++ b/data/items/materials/sapphire.yaml @@ -5,7 +5,7 @@ craft: - uncut_sapphire quantity: 1 level: 20 - message: "You cut the %i1 into a beautiful %n." + success_message: "You cut the %i1 into a beautiful %n." tool: chisel type: crafting wait: 3 diff --git a/data/items/materials/teak_planks.yaml b/data/items/materials/teak_planks.yaml index 400c9e5..145b731 100644 --- a/data/items/materials/teak_planks.yaml +++ b/data/items/materials/teak_planks.yaml @@ -5,7 +5,7 @@ craft: - teak_logs quantity: 1 level: 35 - message: "You saw the teak logs into %n." + success_message: "You saw the teak logs into %n." station: - workbench tool: saw diff --git a/data/items/tools/empty_pot.yaml b/data/items/tools/empty_pot.yaml index 371a783..0386b37 100644 --- a/data/items/tools/empty_pot.yaml +++ b/data/items/tools/empty_pot.yaml @@ -6,7 +6,7 @@ craft: quantity: 1 fail_message: The pot cracks in the oven and is ruined. level: 1 - message: "You fire the %i1 in the oven." + success_message: "You fire the %i1 in the oven." station: - pottery_oven success: diff --git a/data/items/tools/plant_pot.yaml b/data/items/tools/plant_pot.yaml index e758167..b748877 100644 --- a/data/items/tools/plant_pot.yaml +++ b/data/items/tools/plant_pot.yaml @@ -6,7 +6,7 @@ craft: quantity: 1 fail_message: The plant pot cracks in the oven and is ruined. level: 19 - message: "You fire the %i1 in the oven." + success_message: "You fire the %i1 in the oven." station: - pottery_oven success: diff --git a/data/items/tools/unfired_pie_dish.yaml b/data/items/tools/unfired_pie_dish.yaml index bc0c5a5..455921d 100644 --- a/data/items/tools/unfired_pie_dish.yaml +++ b/data/items/tools/unfired_pie_dish.yaml @@ -5,7 +5,7 @@ craft: - soft_clay quantity: 1 level: 7 - message: "You shape the clay into a %n." + success_message: "You shape the clay into a %n." station: - pottery_wheel type: crafting diff --git a/data/items/tools/unfired_plant_pot.yaml b/data/items/tools/unfired_plant_pot.yaml index 30ccd83..26dfcca 100644 --- a/data/items/tools/unfired_plant_pot.yaml +++ b/data/items/tools/unfired_plant_pot.yaml @@ -5,7 +5,7 @@ craft: - soft_clay quantity: 1 level: 19 - message: "You shape the clay into a %n." + success_message: "You shape the clay into a %n." station: - pottery_wheel type: crafting diff --git a/data/items/tools/unfired_pot.yaml b/data/items/tools/unfired_pot.yaml index 9dc2406..6ba9551 100644 --- a/data/items/tools/unfired_pot.yaml +++ b/data/items/tools/unfired_pot.yaml @@ -5,7 +5,7 @@ craft: - soft_clay quantity: 1 level: 1 - message: "You shape the clay into a %n." + success_message: "You shape the clay into a %n." station: - pottery_wheel type: crafting diff --git a/data/objects/adamantite_rock.yaml b/data/objects/adamantite_rock.yaml index 6fa88b8..06ce7bd 100644 --- a/data/objects/adamantite_rock.yaml +++ b/data/objects/adamantite_rock.yaml @@ -4,7 +4,7 @@ gather: - depletes: true item_id: adamantite_ore level: 70 - message: You manage to mine some {78}adamantite ore{/}. + success_message: You manage to mine some {78}adamantite ore{/}. weight: 100 xp: 95 fail_message: You chip away but get nothing useful. diff --git a/data/objects/anglerfish_spot.yaml b/data/objects/anglerfish_spot.yaml index def90ea..0c670a2 100644 --- a/data/objects/anglerfish_spot.yaml +++ b/data/objects/anglerfish_spot.yaml @@ -5,7 +5,7 @@ gather: drops: - item_id: raw_anglerfish level: 82 - message: You catch a {50}raw anglerfish{/}. + success_message: You catch a {50}raw anglerfish{/}. weight: 100 xp: 120 fail_message: Nothing seems to bite. diff --git a/data/objects/bait_fishing_spot.yaml b/data/objects/bait_fishing_spot.yaml index f687016..b870a7f 100644 --- a/data/objects/bait_fishing_spot.yaml +++ b/data/objects/bait_fishing_spot.yaml @@ -5,17 +5,17 @@ gather: drops: - item_id: raw_sardine level: 5 - message: You catch a {4B}raw sardine{/}. + success_message: You catch a {4B}raw sardine{/}. weight: 60 xp: 20 - item_id: raw_herring level: 10 - message: You catch a {4B}raw herring{/}. + success_message: You catch a {4B}raw herring{/}. weight: 40 xp: 30 - item_id: raw_pike level: 25 - message: You catch a {45}raw pike{/}. + success_message: You catch a {45}raw pike{/}. weight: 30 xp: 60 fail_message: Nothing seems to bite. diff --git a/data/objects/cage_fishing_spot.yaml b/data/objects/cage_fishing_spot.yaml index 051f1aa..977d4fb 100644 --- a/data/objects/cage_fishing_spot.yaml +++ b/data/objects/cage_fishing_spot.yaml @@ -4,7 +4,7 @@ gather: drops: - item_id: raw_lobster level: 40 - message: You catch a {21}raw lobster{/}. + success_message: You catch a {21}raw lobster{/}. weight: 100 xp: 90 fail_message: The pot comes up empty. diff --git a/data/objects/clay_rock.yaml b/data/objects/clay_rock.yaml index 2bf4169..8f9275c 100644 --- a/data/objects/clay_rock.yaml +++ b/data/objects/clay_rock.yaml @@ -5,7 +5,7 @@ gather: - depletes: true item_id: clay level: 1 - message: You manage to mine some clay. + success_message: You manage to mine some clay. weight: 100 xp: 5 fail_message: You chip away but get nothing useful. diff --git a/data/objects/coal_rock.yaml b/data/objects/coal_rock.yaml index 40bf4d6..9d09672 100644 --- a/data/objects/coal_rock.yaml +++ b/data/objects/coal_rock.yaml @@ -4,7 +4,7 @@ gather: - depletes: true item_id: coal level: 30 - message: You manage to mine some {F0}coal{/}. + success_message: You manage to mine some {F0}coal{/}. weight: 100 xp: 50 fail_message: You chip away but get nothing useful. diff --git a/data/objects/copper_rock.yaml b/data/objects/copper_rock.yaml index 9694d1f..dc4e166 100644 --- a/data/objects/copper_rock.yaml +++ b/data/objects/copper_rock.yaml @@ -9,7 +9,7 @@ gather: - depletes: true item_id: copper_ore level: 1 - message: You manage to mine some {B2}copper ore{/}. + success_message: You manage to mine some {B2}copper ore{/}. quantity: 0 table: "" weight: 90 @@ -17,7 +17,7 @@ gather: - depletes: false item_id: "" level: 0 - message: You spot a glint of something valuable! + success_message: You spot a glint of something valuable! quantity: 0 table: gem_table weight: 10 diff --git a/data/objects/fly_fishing_spot.yaml b/data/objects/fly_fishing_spot.yaml index e3bf342..8c32d38 100644 --- a/data/objects/fly_fishing_spot.yaml +++ b/data/objects/fly_fishing_spot.yaml @@ -5,17 +5,17 @@ gather: drops: - item_id: raw_trout level: 20 - message: You catch a {45}raw trout{/}. + success_message: You catch a {45}raw trout{/}. weight: 50 xp: 50 - item_id: raw_salmon level: 30 - message: You catch a {45}raw salmon{/}. + success_message: You catch a {45}raw salmon{/}. weight: 50 xp: 70 - item_id: raw_rainbow_fish level: 38 - message: You catch a {B1}raw rainbow fish{/}. + success_message: You catch a {B1}raw rainbow fish{/}. weight: 30 xp: 80 fail_message: Nothing seems to bite. diff --git a/data/objects/gold_rock.yaml b/data/objects/gold_rock.yaml index a6228a4..d1326c2 100644 --- a/data/objects/gold_rock.yaml +++ b/data/objects/gold_rock.yaml @@ -4,7 +4,7 @@ gather: - depletes: true item_id: gold_ore level: 40 - message: You manage to mine some {DC}gold ore{/}. + success_message: You manage to mine some {DC}gold ore{/}. weight: 100 xp: 65 fail_message: You chip away but get nothing useful. diff --git a/data/objects/harpoon_fishing_spot.yaml b/data/objects/harpoon_fishing_spot.yaml index ca377b2..2a78bc5 100644 --- a/data/objects/harpoon_fishing_spot.yaml +++ b/data/objects/harpoon_fishing_spot.yaml @@ -4,17 +4,17 @@ gather: drops: - item_id: raw_tuna level: 35 - message: You harpoon a {21}raw tuna{/}. + success_message: You harpoon a {21}raw tuna{/}. weight: 60 xp: 80 - item_id: raw_swordfish level: 50 - message: You harpoon a {21}raw swordfish{/}. + success_message: You harpoon a {21}raw swordfish{/}. weight: 50 xp: 100 - item_id: raw_shark level: 76 - message: You harpoon a {1B}raw shark{/}. + success_message: You harpoon a {1B}raw shark{/}. weight: 30 xp: 110 fail_message: You fail to spear anything. diff --git a/data/objects/iron_rock.yaml b/data/objects/iron_rock.yaml index 70eafe6..3e94dc8 100644 --- a/data/objects/iron_rock.yaml +++ b/data/objects/iron_rock.yaml @@ -4,7 +4,7 @@ gather: - depletes: true item_id: iron_ore level: 15 - message: You manage to mine some {FA}iron ore{/}. + success_message: You manage to mine some {FA}iron ore{/}. weight: 100 xp: 35 fail_message: You chip away but get nothing useful. diff --git a/data/objects/magic_tree.yaml b/data/objects/magic_tree.yaml index 9016853..39ee11d 100644 --- a/data/objects/magic_tree.yaml +++ b/data/objects/magic_tree.yaml @@ -5,7 +5,7 @@ gather: - depletes: false item_id: magic_logs level: 75 - message: You get some {87}magic logs{/}. + success_message: You get some {87}magic logs{/}. weight: 100 xp: 250 fail_message: You swing but get no logs. diff --git a/data/objects/mahogany_tree.yaml b/data/objects/mahogany_tree.yaml index bb5077b..25b344e 100644 --- a/data/objects/mahogany_tree.yaml +++ b/data/objects/mahogany_tree.yaml @@ -5,7 +5,7 @@ gather: - depletes: false item_id: mahogany_logs level: 50 - message: You get some {83}mahogany logs{/}. + success_message: You get some {83}mahogany logs{/}. weight: 100 xp: 125 fail_message: You swing but get no logs. diff --git a/data/objects/maple_tree.yaml b/data/objects/maple_tree.yaml index 3bf4005..fe80732 100644 --- a/data/objects/maple_tree.yaml +++ b/data/objects/maple_tree.yaml @@ -5,7 +5,7 @@ gather: - depletes: false item_id: maple_logs level: 45 - message: You get some {AD}maple logs{/}. + success_message: You get some {AD}maple logs{/}. weight: 100 xp: 100 fail_message: You swing but get no logs. diff --git a/data/objects/mithril_rock.yaml b/data/objects/mithril_rock.yaml index b561c97..e5da31e 100644 --- a/data/objects/mithril_rock.yaml +++ b/data/objects/mithril_rock.yaml @@ -4,7 +4,7 @@ gather: - depletes: true item_id: mithril_ore level: 55 - message: You manage to mine some {4B}mithril ore{/}. + success_message: You manage to mine some {4B}mithril ore{/}. weight: 100 xp: 80 fail_message: You chip away but get nothing useful. diff --git a/data/objects/net_fishing_spot.yaml b/data/objects/net_fishing_spot.yaml index 7acfcce..4c97ea8 100644 --- a/data/objects/net_fishing_spot.yaml +++ b/data/objects/net_fishing_spot.yaml @@ -5,27 +5,27 @@ gather: drops: - item_id: raw_shrimps level: 1 - message: You catch some {4B}raw shrimps{/}. + success_message: You catch some {4B}raw shrimps{/}. weight: 50 xp: 10 - item_id: raw_anchovies level: 1 - message: You catch some {4B}raw anchovies{/}. + success_message: You catch some {4B}raw anchovies{/}. weight: 50 xp: 10 - item_id: raw_mackerel level: 16 - message: You catch a {45}raw mackerel{/}. + success_message: You catch a {45}raw mackerel{/}. weight: 50 xp: 20 - item_id: raw_cod level: 23 - message: You catch a {45}raw cod{/}. + success_message: You catch a {45}raw cod{/}. weight: 50 xp: 30 - item_id: raw_bass level: 46 - message: You catch a {45}raw bass{/}. + success_message: You catch a {45}raw bass{/}. weight: 50 xp: 50 fail_message: You catch nothing. diff --git a/data/objects/oak_tree.yaml b/data/objects/oak_tree.yaml index 98c35b8..47a4354 100644 --- a/data/objects/oak_tree.yaml +++ b/data/objects/oak_tree.yaml @@ -5,7 +5,7 @@ gather: - depletes: false item_id: oak_logs level: 15 - message: You get some {71}oak logs{/}. + success_message: You get some {71}oak logs{/}. weight: 100 xp: 37 fail_message: You swing but get no logs. diff --git a/data/objects/redwood_tree.yaml b/data/objects/redwood_tree.yaml index 9eee250..f599d18 100644 --- a/data/objects/redwood_tree.yaml +++ b/data/objects/redwood_tree.yaml @@ -5,7 +5,7 @@ gather: - depletes: false item_id: redwood_logs level: 90 - message: You get some {83}redwood logs{/}. + success_message: You get some {83}redwood logs{/}. weight: 100 xp: 380 fail_message: You swing but get no logs. diff --git a/data/objects/runite_rock.yaml b/data/objects/runite_rock.yaml index 7bc3681..53f9cf2 100644 --- a/data/objects/runite_rock.yaml +++ b/data/objects/runite_rock.yaml @@ -4,7 +4,7 @@ gather: - depletes: true item_id: runite_ore level: 85 - message: You manage to mine some {57}runite ore{/}. + success_message: You manage to mine some {57}runite ore{/}. weight: 100 xp: 125 fail_message: You chip away but get nothing useful. diff --git a/data/objects/sacred_eel_spot.yaml b/data/objects/sacred_eel_spot.yaml index 3c05576..1a712cb 100644 --- a/data/objects/sacred_eel_spot.yaml +++ b/data/objects/sacred_eel_spot.yaml @@ -5,7 +5,7 @@ gather: drops: - item_id: sacred_eel level: 87 - message: You catch a {B1}sacred eel{/}. + success_message: You catch a {B1}sacred eel{/}. weight: 100 xp: 125 fail_message: Nothing seems to bite. diff --git a/data/objects/scrap_pile.yaml b/data/objects/scrap_pile.yaml index f85815b..f05a234 100644 --- a/data/objects/scrap_pile.yaml +++ b/data/objects/scrap_pile.yaml @@ -4,7 +4,7 @@ gather: - depletes: false item_id: scrap level: 1 - message: You salvage some {F3}scrap{/}. + success_message: You salvage some {F3}scrap{/}. weight: 100 xp: 5 gather_message: You swing your pickaxe at the scrap pile... diff --git a/data/objects/sheep.yaml b/data/objects/sheep.yaml index 234714b..e482198 100644 --- a/data/objects/sheep.yaml +++ b/data/objects/sheep.yaml @@ -5,7 +5,7 @@ gather: - depletes: true item_id: wool level: 1 - message: You shear some wool from the sheep. + success_message: You shear some wool from the sheep. weight: 100 xp: 0 fail_message: The sheep wriggles free! diff --git a/data/objects/silver_rock.yaml b/data/objects/silver_rock.yaml index c9b436f..b9f7777 100644 --- a/data/objects/silver_rock.yaml +++ b/data/objects/silver_rock.yaml @@ -4,7 +4,7 @@ gather: - depletes: true item_id: silver_ore level: 20 - message: You manage to mine some {FD}silver ore{/}. + success_message: You manage to mine some {FD}silver ore{/}. weight: 100 xp: 40 fail_message: You chip away but get nothing useful. diff --git a/data/objects/swamp_fishing_spot.yaml b/data/objects/swamp_fishing_spot.yaml index 8bca2bd..5c2cafc 100644 --- a/data/objects/swamp_fishing_spot.yaml +++ b/data/objects/swamp_fishing_spot.yaml @@ -5,12 +5,12 @@ gather: drops: - item_id: raw_slimy_eel level: 28 - message: You catch a {6C}raw slimy eel{/}. + success_message: You catch a {6C}raw slimy eel{/}. weight: 60 xp: 80 - item_id: raw_cave_eel level: 38 - message: You catch a {50}raw cave eel{/}. + success_message: You catch a {50}raw cave eel{/}. weight: 40 xp: 80 fail_message: Nothing seems to bite. diff --git a/data/objects/teak_tree.yaml b/data/objects/teak_tree.yaml index 5e47900..0419838 100644 --- a/data/objects/teak_tree.yaml +++ b/data/objects/teak_tree.yaml @@ -5,7 +5,7 @@ gather: - depletes: false item_id: teak_logs level: 35 - message: You get some {B3}teak logs{/}. + success_message: You get some {B3}teak logs{/}. weight: 100 xp: 85 fail_message: You swing but get no logs. diff --git a/data/objects/tin_rock.yaml b/data/objects/tin_rock.yaml index 20b2f21..9ec1011 100644 --- a/data/objects/tin_rock.yaml +++ b/data/objects/tin_rock.yaml @@ -4,7 +4,7 @@ gather: - depletes: true item_id: tin_ore level: 1 - message: You manage to mine some {FD}tin ore{/}. + success_message: You manage to mine some {FD}tin ore{/}. weight: 100 xp: 17 fail_message: You chip away but get nothing useful. diff --git a/data/objects/tree.yaml b/data/objects/tree.yaml index 4bd4ab0..83aba3a 100644 --- a/data/objects/tree.yaml +++ b/data/objects/tree.yaml @@ -5,7 +5,7 @@ gather: - depletes: true item_id: logs level: 1 - message: You get some {6B}logs{/}. + success_message: You get some {6B}logs{/}. weight: 100 xp: 25 exhausted_message: The tree comes crashing down! diff --git a/data/objects/willow_tree.yaml b/data/objects/willow_tree.yaml index 1b7645e..a0e697a 100644 --- a/data/objects/willow_tree.yaml +++ b/data/objects/willow_tree.yaml @@ -5,7 +5,7 @@ gather: - depletes: false item_id: willow_logs level: 30 - message: You get some {72}willow logs{/}. + success_message: You get some {72}willow logs{/}. weight: 100 xp: 67 fail_message: You swing but get no logs. diff --git a/data/objects/yew_tree.yaml b/data/objects/yew_tree.yaml index a9313ea..61aa71e 100644 --- a/data/objects/yew_tree.yaml +++ b/data/objects/yew_tree.yaml @@ -5,7 +5,7 @@ gather: - depletes: false item_id: yew_logs level: 60 - message: You get some {6C}yew logs{/}. + success_message: You get some {6C}yew logs{/}. weight: 100 xp: 175 fail_message: You swing but get no logs. diff --git a/data/rooms/intro/2001.yaml b/data/rooms/intro/2001.yaml index 4b21ab8..ad4667a 100644 --- a/data/rooms/intro/2001.yaml +++ b/data/rooms/intro/2001.yaml @@ -19,10 +19,10 @@ item_spawns: respawn_ticks: 1 - id: pot_of_flour quantity: 1 - respawn_ticks: 0 + respawn_ticks: 1 - id: bucket_of_water quantity: 1 - respawn_ticks: 0 + respawn_ticks: 1 mobs: [] name: Test Room objects: diff --git a/internal/admin/static/itemeditor.js b/internal/admin/static/itemeditor.js index d02e7ab..d02945a 100644 --- a/internal/admin/static/itemeditor.js +++ b/internal/admin/static/itemeditor.js @@ -59,24 +59,24 @@ var SECTIONS = [ ['success_base', 'Base', 'number', '', 'narrow'], ['success_per_level', 'Per Lvl', 'number', '', 'narrow'], ['success_cap', 'Cap', 'number', '', 'narrow'], - ['start_message', 'Start Message', 'text', '', 'wide'], - ['message', 'Message', 'text', '', 'wide'], - ['fail_message', 'Fail Message', 'text', '', 'wide', function(item) { return item.type === 'cooking' || item.subtype === 'smelt'; }], - ['end_message', 'End Message', 'text', '', 'wide'], + ['start_message', 'Start Message', 'text', 'e.g. You begin smithing %i1.', 'wide'], + ['success_message', 'Success Message', 'text', 'e.g. You smith a %n.', 'wide'], + ['fail_message', 'Fail Message', 'text', 'e.g. You accidentally burn the %i1.', 'wide', function(item) { return item.type === 'cooking' || item.subtype === 'smelt'; }], + ['end_message', 'End Message', 'text', 'e.g. You\'ve finished smithing.', 'wide'], ], fieldGroups: [ ['type', 'subtype', 'level', 'xp', 'wait', 'output_qty'], {fields: ['station', 'tool'], right: true}, {label: 'Success', fields: ['success_base', 'success_per_level', 'success_cap', 'fail']}, - ['start_message', 'message', 'fail_message', 'end_message'], + ['start_message', 'success_message', 'fail_message', 'end_message'], ], subSubtables: [ {label:'Ingredients', key:'ingredients', fields:[ ['quantity', 'Qty', 'number', '1', 'narrow'], ]}, {label:'Steps', key:'steps', fields:[ - ['tick', 'Ticks', 'number', '', 'narrow'], - ['message', 'Message', 'text', '', 'wide'], + ['delay', 'Delay (ticks)', 'number', '', 'narrow'], + ['message', 'Message', 'text', '', 'wide'], ]}, ], } @@ -556,6 +556,8 @@ function renderSubFieldHTML(sec, stKey, idx, f, val) { if (f[4] === 'narrow') extraCls = ' obj-narrow'; else if (f[4] === 'grow') extraCls = ' obj-grow'; if (f[4] === 'wide') extraStyle = ' style="flex:1 1 100%"'; + var defaultPh = ''; + if (f[3]) defaultPh = ' placeholder="' + escAttr(f[3]) + '"'; if (f[2] === 'search') { var entity = f[6] || 'items'; var ph = f[3] ? ' placeholder="' + escAttr(f[3]) + '"' : ' placeholder="Search ' + entity + '..."'; @@ -573,7 +575,7 @@ function renderSubFieldHTML(sec, stKey, idx, f, val) { sel += ''; return sel; } - return ''; + return ''; } function renderSubtable(sec, st, data) { @@ -653,7 +655,7 @@ function renderSubtable(sec, st, data) { if (sst.key === 'steps') { var stepsArr = item[sst.key]; if (!stepsArr || !Array.isArray(stepsArr) || stepsArr.length === 0) { - h += ''; + h += ''; return; } } @@ -721,7 +723,9 @@ function removeConsumePair(secID, subKey, rowIdx, subSubKey, subIdx, pairIdx) { function renderSubSubtable(sec, st, rowIdx, sst, parentItem) { var arr = parentItem[sst.key] || []; var isIngredients = sst.key === 'ingredients'; - var h = '
'; + var isSteps = sst.key === 'steps'; + var stepsAttr = isSteps ? ' data-section="steps-section"' : ''; + var h = '
'; if (!isIngredients) { h += '
' + esc(sst.label) + '
'; } @@ -1035,6 +1039,11 @@ function setupCraftTypeChange() { var xpField = document.getElementById(id.replace(/_type$/, '_xp')); var stationField = document.getElementById(id.replace(/_type$/, '_station')); + var combineHideFields = ['success_message', 'fail_message', 'tool', 'wait', + 'success_base', 'success_per_level', 'success_cap', 'fail']; + + var recipeRow = typeSelect.closest('.obj-sub-row'); + function update() { var t = typeSelect.value; @@ -1049,6 +1058,25 @@ function setupCraftTypeChange() { if (sLbl) sLbl.style.display = (t === 'fletching' || t === 'combine' || t === 'pharmacy') ? 'none' : ''; } + combineHideFields.forEach(function(fKey) { + var el = document.getElementById(id.replace(/_type$/, '_' + fKey)); + if (!el) return; + var lbl = el.closest('.obj-field'); + if (lbl) lbl.style.display = t === 'combine' ? 'none' : ''; + }); + + var successGroup = document.querySelector('.success-group'); + if (successGroup) successGroup.style.display = t === 'combine' ? 'none' : ''; + var successBtn = document.getElementById(successGroup ? successGroup.id + '_btn' : ''); + if (successBtn) successBtn.style.display = t === 'combine' ? 'none' : ''; + + var stepsSection = recipeRow.querySelector('[data-section="steps-section"]'); + var stepsAddBtn = recipeRow.querySelector('[data-section^="steps-add-"]'); + + var showSteps = t === 'combine'; + if (stepsSection) stepsSection.style.display = showSteps ? '' : 'none'; + if (stepsAddBtn) stepsAddBtn.style.display = showSteps ? '' : 'none'; + if (subtypeSel) { var sLbl = subtypeSel.closest('.obj-field'); if (t === 'smithing') { diff --git a/internal/behavior/behavior.go b/internal/behavior/behavior.go index 8333a05..c0a714c 100644 --- a/internal/behavior/behavior.go +++ b/internal/behavior/behavior.go @@ -5,15 +5,16 @@ type GatherConfig struct { Tools []string `yaml:"tools"` Bait string `yaml:"bait"` Success SuccessFormula `yaml:"success"` - GatherMsg string `yaml:"gather_message"` + GatherMessage string `yaml:"gather_message"` DepletedMessage string `yaml:"depleted_message"` ExhaustedMessage string `yaml:"exhausted_message"` - FailMsg string `yaml:"fail_message"` + FailMessage string `yaml:"fail_message"` Drops []DropEntry `yaml:"drops"` RespawnTimer float64 `yaml:"respawn_timer"` RespawnBroadcast string `yaml:"respawn_broadcast"` DepleteTimer float64 `yaml:"deplete_timer"` NestChance int `yaml:"nest_chance"` + BroadcastMessage string `yaml:"broadcast_message"` } type SuccessFormula struct { @@ -82,13 +83,16 @@ type Condition struct { } type UseConfig struct { - Message string `yaml:"message"` - Wait float64 `yaml:"wait"` - Consume map[string]int `yaml:"consume"` - Reward DropEntry `yaml:"reward"` - FailMsg string `yaml:"fail_message"` - Success *SuccessFormula `yaml:"success"` - Skill string `yaml:"skill"` - Level int `yaml:"level"` - XP int `yaml:"xp"` + StartMessage string `yaml:"start_message"` + Wait float64 `yaml:"wait"` + Consume map[string]int `yaml:"consume"` + Reward DropEntry `yaml:"reward"` + FailMessage string `yaml:"fail_message"` + Success *SuccessFormula `yaml:"success"` + Skill string `yaml:"skill"` + Level int `yaml:"level"` + XP int `yaml:"xp"` + SuccessMessage string `yaml:"success_message"` + EndMessage string `yaml:"end_message"` + BroadcastMessage string `yaml:"broadcast_message"` } diff --git a/internal/behavior/store.go b/internal/behavior/store.go index 710506e..38cc72b 100644 --- a/internal/behavior/store.go +++ b/internal/behavior/store.go @@ -154,10 +154,10 @@ func ResolveDrop(dataDir string, drops []DropEntry) *DropEntry { qty = 1 } return &DropEntry{ - ItemID: resolved.ItemID, - Quantity: qty, - Depletes: drops[i].Depletes, - Message: drops[i].Message, + ItemID: resolved.ItemID, + Quantity: qty, + Depletes: drops[i].Depletes, + SuccessMessage: drops[i].SuccessMessage, } } } diff --git a/internal/behavior/types.go b/internal/behavior/types.go index c061742..571f2c4 100644 --- a/internal/behavior/types.go +++ b/internal/behavior/types.go @@ -55,6 +55,7 @@ const ( TypeMix ActionType = "mix" TypeConstruct ActionType = "construct" TypeTriggerModule ActionType = "trigger_module" + TypeUseInteraction ActionType = "use_interaction" ) type Action struct { @@ -85,14 +86,12 @@ type GatherData struct { } type ProductionData struct { - ItemID string - Phase int - Wait float64 - StartMsg string - EndMsg string - Remaining int - NextStepIndex int - StepsAccumulatedTicks float64 + ItemID string + Phase int + Wait float64 + StartMessage string + EndMessage string + Remaining int } type StealData struct { @@ -126,6 +125,12 @@ type UseData struct { Step int } +type UseInteractionData struct { + Message string + Action *NodeAction + ObjName string +} + type BurnData struct { ItemID string ToolSpeed float64 @@ -172,6 +177,16 @@ type SearchData struct { Started bool } +type CombineData struct { + ItemID string + Phase int + StepIndex int + Remaining int + StartMessage string + EndMessage string + Wait float64 +} + type FletchData struct { ItemID string Phase int @@ -196,14 +211,14 @@ type TriggerModuleData struct { } type DropEntry struct { - ItemID string `yaml:"item_id"` - Table string `yaml:"table"` - Weight int `yaml:"weight"` - Quantity int `yaml:"quantity"` - Depletes bool `yaml:"depletes"` - Message string `yaml:"message"` - Level int `yaml:"level"` - XP int `yaml:"xp"` + ItemID string `yaml:"item_id"` + Table string `yaml:"table"` + Weight int `yaml:"weight"` + Quantity int `yaml:"quantity"` + Depletes bool `yaml:"depletes"` + SuccessMessage string `yaml:"success_message"` + Level int `yaml:"level"` + XP int `yaml:"xp"` } type DropTableDef struct { diff --git a/internal/game/act.go b/internal/game/act.go index aa25625..c8101ab 100644 --- a/internal/game/act.go +++ b/internal/game/act.go @@ -236,9 +236,13 @@ func (g *Game) AdvanceActions() { g.advanceObstacle(sess, p) case behavior.TypeTalk: g.advanceTalk(sess, p) - case behavior.TypeTriggerModule: - g.advanceTriggerModule(sess, p) - default: + case behavior.TypeTriggerModule: + g.advanceTriggerModule(sess, p) + case behavior.TypeUseInteraction: + g.advanceUseInteraction(sess, p) + case behavior.TypeCombine: + g.advanceCombine(sess, p) + default: if productionActionTypes[string(p.Action.Type)] { g.advanceProduction(sess, p) } diff --git a/internal/game/act_clean.go b/internal/game/act_clean.go index 021a07c..7647f4f 100644 --- a/internal/game/act_clean.go +++ b/internal/game/act_clean.go @@ -71,7 +71,7 @@ func (g *Game) advanceClean(sess *net.Session, p *player.Player) { } g.AccountStore.SaveCharacter(p) - msg := g.resolveCraftMessage(sess, craft.Message, "You clean the %i1.", craft, matchItem.ID, nil, p.HasItem) + msg := g.resolveCraftMessage(sess, craft.SuccessMessage, "You clean the %i1.", craft, matchItem.ID, nil, p.HasItem) if p.OptionBool("xp_drops") && craft.XP > 0 { msg += g.formatXpDropSingle(sess, p, player.Pharmacy, craft.XP) } diff --git a/internal/game/act_combine.go b/internal/game/act_combine.go new file mode 100644 index 0000000..8937d38 --- /dev/null +++ b/internal/game/act_combine.go @@ -0,0 +1,157 @@ +package game + +import ( + "thehouseoficarus/internal/behavior" + "thehouseoficarus/internal/engine" + "thehouseoficarus/internal/item" + "thehouseoficarus/internal/net" + "thehouseoficarus/internal/player" +) + +func (g *Game) startCombine(sess *net.Session, p *player.Player, item *item.ItemDef, craft *item.CraftDef, count int) { + g.cancelAction(p) + g.cancelBgAction(p) + + if !craftHasAllItemsQty(craft, p.CountItem) { + sess.WriteLine("You don't have the required materials.") + g.reprompt(sess) + return + } + + outDef, _ := g.ItemStore.Load(item.ID) + outputName := item.ID + if outDef != nil { + outputName = outDef.Name + } + + startMsg := g.resolveCraftMessage(sess, craft.StartMessage, "You start combining %i1.", craft, item.ID, nil, p.HasItem) + endMsg := g.resolveCraftMessage(sess, craft.EndMessage, "You've finished combining.", craft, item.ID, nil, p.HasItem) + + p.Action = &behavior.Action{ + Type: behavior.TypeCombine, + TargetID: item.ID, + TargetName: outputName, + Data: &behavior.CombineData{ + ItemID: item.ID, + Phase: 0, + StepIndex: 0, + Remaining: count, + StartMessage: startMsg, + EndMessage: endMsg, + Wait: craft.Wait, + }, + WaitLeft: engine.ToTicks(1), + } + + g.broadcastAction(sess, "%s starts combining.", p.Name) +} + +func (g *Game) advanceCombine(sess *net.Session, p *player.Player) { + d, ok := p.Action.Data.(*behavior.CombineData) + if !ok { + g.cancelAction(p) + return + } + + item := g.loadCraftItem(d.ItemID) + if item == nil { + g.cancelAction(p) + return + } + craft := item.FirstCraft() + + switch d.Phase { + case 0: + if d.StartMessage != "" { + sess.WriteLine(d.StartMessage) + } + d.Phase = 1 + if len(craft.Steps) > 0 { + p.Action.WaitLeft = engine.ToTicks(craft.Steps[0].Delay) + } else { + firstWait := craft.Wait + if firstWait <= 0 { + firstWait = 4 + } + p.Action.WaitLeft = engine.ToTicks(firstWait) + } + return + + case 1: + if len(craft.Steps) > 0 && d.StepIndex < len(craft.Steps) { + step := craft.Steps[d.StepIndex] + sess.WriteLine(g.resolveCraftVar(sess, step.Message, craft, item.ID, nil, p.HasItem)) + d.StepIndex++ + if d.StepIndex < len(craft.Steps) { + p.Action.WaitLeft = engine.ToTicks(craft.Steps[d.StepIndex].Delay) + return + } + } + d.Phase = 2 + p.Action.WaitLeft = engine.ToTicks(1) + return + + case 2: + if !craftHasAllItemsQty(craft, p.CountItem) { + if d.EndMessage != "" { + sess.WriteLine(d.EndMessage) + } + g.cancelAction(p) + return + } + + consumeIngredients(craft, p.HasItem, p.RemoveItem) + + outputQty := craft.OutputQty + if outputQty <= 0 { + outputQty = 1 + } + + outDef, _ := g.ItemStore.Load(item.ID) + placed := false + if outDef != nil && outDef.Stackable { + for i := 0; i < 28; i++ { + slot := p.InvSlot(i) + if slot != nil && slot.ItemID == item.ID { + slot.Quantity += outputQty + placed = true + break + } + } + } + if !placed { + freeSlot := p.FirstFreeSlot() + if freeSlot == -1 { + sess.WriteLine("Your inventory is too full!") + g.cancelAction(p) + return + } + p.SetInvSlot(freeSlot, &player.InventorySlot{ItemID: item.ID, Quantity: outputQty}) + } + + g.AccountStore.SaveCharacter(p) + + if d.Remaining > 0 { + d.Remaining-- + if d.Remaining <= 0 { + if d.EndMessage != "" { + sess.WriteLine(d.EndMessage) + } + g.cancelAction(p) + return + } + } + + if !craftHasAllItemsQty(craft, p.CountItem) { + if d.EndMessage != "" { + sess.WriteLine(d.EndMessage) + } + g.cancelAction(p) + return + } + + d.Phase = 0 + d.StepIndex = 0 + p.Action.WaitLeft = engine.ToTicks(1) + } +} diff --git a/internal/game/act_fletch.go b/internal/game/act_fletch.go index 800bc8e..ce3a525 100644 --- a/internal/game/act_fletch.go +++ b/internal/game/act_fletch.go @@ -188,7 +188,7 @@ func (g *Game) advanceFletch(sess *net.Session, p *player.Player) { } g.AccountStore.SaveCharacter(p) - msg := g.resolveCraftMessage(sess, c.Message, "You fletch a %n.", c, def.ID, nil, p.HasItem) + msg := g.resolveCraftMessage(sess, c.SuccessMessage, "You fletch a %n.", c, def.ID, nil, p.HasItem) if p.OptionBool("xp_drops") && c.XP > 0 { msg += g.formatXpDropSingle(sess, p, skill, c.XP) } diff --git a/internal/game/act_gather.go b/internal/game/act_gather.go index ab59de0..c34c6ae 100644 --- a/internal/game/act_gather.go +++ b/internal/game/act_gather.go @@ -106,7 +106,12 @@ func (g *Game) startGather(sess *net.Session, p *player.Player, obj *object.Obje verb = "chopping" } - g.broadcastAction(sess, "%s starts %s the %s.", p.Name, verb, obj.Name) + if cfg.BroadcastMessage != "" { + bcMsg := strings.ReplaceAll(cfg.BroadcastMessage, "%o", obj.Name) + g.broadcastAction(sess, bcMsg, p.Name) + } else { + g.broadcastAction(sess, "%s starts %s the %s.", p.Name, verb, obj.Name) + } d := &behavior.GatherData{ ObjDefID: obj.ID, @@ -158,7 +163,7 @@ func (g *Game) advanceGather(sess *net.Session, p *player.Player) { return } } - sess.WriteLine(fmt.Sprintf("%s", cfg.GatherMsg)) + sess.WriteLine(fmt.Sprintf("%s", cfg.GatherMessage)) d.Step = 1 p.Action.WaitLeft = engine.ToTicks(wait) return @@ -220,12 +225,14 @@ func (g *Game) advanceGather(sess *net.Session, p *player.Player) { } g.AccountStore.SaveCharacter(p) - msg := drop.Message - if msg == "" { - msg = fmt.Sprintf("You manage to get some %s.", g.itemColorize(sess, itemDef, itemName)) - } else { - msg = color.ExpandTags(g.colorMode(sess), msg) - } + msg := drop.SuccessMessage + coloredName := g.itemColorize(sess, itemDef, itemName) + if msg == "" { + msg = fmt.Sprintf("You manage to get some %s.", coloredName) + } else { + msg = strings.ReplaceAll(msg, "%n", coloredName) + msg = color.ExpandTags(g.colorMode(sess), msg) + } if xp > 0 && p.OptionBool("xp_drops") { msg += g.formatXpDropSingle(sess, p, player.SkillName(cfg.Skill), xp) } @@ -294,7 +301,7 @@ func (g *Game) advanceGather(sess *net.Session, p *player.Player) { } } - sess.WriteLine(cfg.FailMsg) + sess.WriteLine(cfg.FailMessage) if p.FirstFreeSlot() == -1 { sess.WriteLine(g.colorize(sess, "error", "Your inventory is too full!")) g.cancelAction(p) diff --git a/internal/game/act_state.go b/internal/game/act_state.go index 051390f..c4ccaba 100644 --- a/internal/game/act_state.go +++ b/internal/game/act_state.go @@ -81,9 +81,11 @@ func (g *Game) playerActionDisplay(p *player.Player) string { return "mixing some " + a.TargetName case behavior.TypeConstruct: return "constructing some " + a.TargetName - case behavior.TypeTriggerModule: - return "triggering " + a.TargetName - } + case behavior.TypeTriggerModule: + return "triggering " + a.TargetName + case behavior.TypeUseInteraction: + return "using " + a.TargetName + } } if a := p.BackgroundAction; a != nil { diff --git a/internal/game/act_use.go b/internal/game/act_use.go index 0d8582d..1e9d8e9 100644 --- a/internal/game/act_use.go +++ b/internal/game/act_use.go @@ -3,6 +3,7 @@ package game import ( "fmt" "math/rand" + "strings" "thehouseoficarus/internal/behavior" "thehouseoficarus/internal/engine" @@ -34,7 +35,11 @@ func (g *Game) startUse(sess *net.Session, p *player.Player, obj *object.ObjectD return } - g.broadcastAction(sess, "%s uses the %s.", p.Name, obj.Name) + if cfg.BroadcastMessage != "" { + g.broadcastAction(sess, strings.ReplaceAll(cfg.BroadcastMessage, "%o", obj.Name), p.Name) + } else { + g.broadcastAction(sess, "%s uses the %s.", p.Name, obj.Name) + } p.Action = &behavior.Action{ Type: "use", @@ -44,7 +49,7 @@ func (g *Game) startUse(sess *net.Session, p *player.Player, obj *object.ObjectD Data: &behavior.UseData{Cfg: cfg, Step: 0}, } - sess.WriteLine(fmt.Sprintf("%s", cfg.Message)) + sess.WriteLine(fmt.Sprintf("%s", cfg.StartMessage)) } func (g *Game) advanceUse(sess *net.Session, p *player.Player) { @@ -76,8 +81,8 @@ func (g *Game) advanceUse(sess *net.Session, p *player.Player) { skillLevel := p.Level(player.SkillName(cfg.Skill)) chance := behavior.SuccessChance(*cfg.Success, skillLevel, cfg.Level) if rand.Float64() >= chance { - if cfg.FailMsg != "" { - sess.WriteLine(cfg.FailMsg) + if cfg.FailMessage != "" { + sess.WriteLine(cfg.FailMessage) } p.Action.WaitLeft = engine.ToTicks(cfg.Wait) return @@ -107,17 +112,30 @@ func (g *Game) advanceUse(sess *net.Session, p *player.Player) { if rewardDef != nil { itemName = rewardDef.Name } - line := fmt.Sprintf("You make a %s.", g.itemColorize(sess, rewardDef, itemName)) + coloredName := g.itemColorize(sess, rewardDef, itemName) + + var line string + if cfg.SuccessMessage != "" { + line = strings.ReplaceAll(cfg.SuccessMessage, "%n", coloredName) + } else { + line = fmt.Sprintf("You make a %s.", coloredName) + } if cfg.XP > 0 && p.OptionBool("xp_drops") { line += g.formatXpDropSingle(sess, p, player.SkillName(cfg.Skill), cfg.XP) } sess.WriteLine(line) if p.FirstFreeSlot() == -1 { + if cfg.EndMessage != "" { + sess.WriteLine(cfg.EndMessage) + } sess.WriteLine("Your inventory is full.") g.cancelAction(p) return } + if cfg.EndMessage != "" { + sess.WriteLine(cfg.EndMessage) + } p.Action.WaitLeft = engine.ToTicks(cfg.Wait) } diff --git a/internal/game/act_use_interaction.go b/internal/game/act_use_interaction.go new file mode 100644 index 0000000..b96aaa3 --- /dev/null +++ b/internal/game/act_use_interaction.go @@ -0,0 +1,23 @@ +package game + +import ( + "thehouseoficarus/internal/behavior" + "thehouseoficarus/internal/net" + "thehouseoficarus/internal/player" +) + +func (g *Game) advanceUseInteraction(sess *net.Session, p *player.Player) { + d, ok := p.Action.Data.(*behavior.UseInteractionData) + if !ok { + g.cancelAction(p) + return + } + if d.Message != "" { + sess.WriteLine(d.Message) + } + if d.Action != nil { + g.applyNodeAction(sess, d.Action) + } + g.broadcastAction(sess, "%s uses the %s.", p.Name, d.ObjName) + g.cancelAction(p) +} diff --git a/internal/game/cmd_use.go b/internal/game/cmd_use.go index 033fd62..1989a3e 100644 --- a/internal/game/cmd_use.go +++ b/internal/game/cmd_use.go @@ -4,6 +4,7 @@ import ( "fmt" "strings" + "thehouseoficarus/internal/behavior" "thehouseoficarus/internal/item" "thehouseoficarus/internal/net" "thehouseoficarus/internal/player" @@ -97,13 +98,17 @@ func (g *Game) useRoomObject(sess *net.Session, p *player.Player, input string) if ui.Condition != nil && !g.checkCondition(sess, ui.Condition) { continue } - if ui.Message != "" { - sess.WriteLine(ui.Message) + g.cancelAction(p) + p.Action = &behavior.Action{ + Type: behavior.TypeUseInteraction, + TargetName: def.Name, + WaitLeft: 1, + Data: &behavior.UseInteractionData{ + Message: ui.Message, + Action: ui.Action, + ObjName: def.Name, + }, } - if ui.Action != nil { - g.applyNodeAction(sess, ui.Action) - } - g.broadcastAction(sess, "%s uses the %s.", p.Name, def.Name) return true } if len(def.UseInteractions) > 0 { @@ -286,11 +291,16 @@ func (g *Game) doUseItemOnTarget(sess *net.Session, p *player.Player, itemAName, if ui.Condition != nil && !g.checkCondition(sess, ui.Condition) { continue } - if ui.Message != "" { - sess.WriteLine(ui.Message) - } - if ui.Action != nil { - g.applyNodeAction(sess, ui.Action) + g.cancelAction(p) + p.Action = &behavior.Action{ + Type: behavior.TypeUseInteraction, + TargetName: def.Name, + WaitLeft: 1, + Data: &behavior.UseInteractionData{ + Message: ui.Message, + Action: ui.Action, + ObjName: def.Name, + }, } return } diff --git a/internal/game/core_production.go b/internal/game/core_production.go index da9466f..e6a62d4 100644 --- a/internal/game/core_production.go +++ b/internal/game/core_production.go @@ -80,13 +80,6 @@ var productionTypes = map[string]productionTypeInfo{ SuccessMessage: "You craft a %n.", EndMessage: "You've finished crafting.", }, - "combine": { - ActionType: behavior.TypeCombine, - DisplayVerb: "combining", - StartMessage: "You start combining %i1.", - SuccessMessage: "You produce %n.", - EndMessage: "You've finished combining.", - }, "fletching": { ActionType: behavior.TypeFletch, DisplayVerb: "fletching", diff --git a/internal/game/production_engine.go b/internal/game/production_engine.go index 048e152..1d54714 100644 --- a/internal/game/production_engine.go +++ b/internal/game/production_engine.go @@ -113,8 +113,8 @@ func (g *Game) startProduction(sess *net.Session, p *player.Player, item *item.I ItemID: item.ID, Phase: 0, Wait: wait, - StartMsg: startMsg, - EndMsg: endMsg, + StartMessage: startMsg, + EndMessage: endMsg, Remaining: count, }, WaitLeft: engine.ToTicks(1), @@ -129,6 +129,11 @@ func (g *Game) startProductionFromItem(sess *net.Session, p *player.Player, item return } + if craft.Type == "combine" { + g.startCombine(sess, p, item, craft, count) + return + } + _, stationName := g.findStation(p.RoomID, craft.Station) if stationName == "" { stationName = "inventory" @@ -177,8 +182,8 @@ func (g *Game) advanceProduction(sess *net.Session, p *player.Player) bool { itemID := d.ItemID phase := d.Phase wait := d.Wait - startMsg := d.StartMsg - endMsg := d.EndMsg + startMsg := d.StartMessage + endMsg := d.EndMessage remaining := d.Remaining item := g.loadCraftItem(itemID) @@ -192,27 +197,11 @@ func (g *Game) advanceProduction(sess *net.Session, p *player.Player) bool { if startMsg != "" { sess.WriteLine(startMsg) } - if len(craft.Steps) > 0 { - d.NextStepIndex = 0 - d.StepsAccumulatedTicks = 0 - } d.Phase = 1 p.Action.WaitLeft = engine.ToTicks(wait) return true } - if stepsIdx := d.NextStepIndex; stepsIdx < len(craft.Steps) { - accTicks := d.StepsAccumulatedTicks - accTicks += wait - d.StepsAccumulatedTicks = accTicks - for i := stepsIdx; i < len(craft.Steps); i++ { - if accTicks >= craft.Steps[i].Tick { - sess.WriteLine(g.resolveCraftVar(sess, craft.Steps[i].Message, craft, item.ID, nil, p.HasItem)) - d.NextStepIndex = i + 1 - } - } - } - skill := craft.EffectiveSkill() skillLevel := p.Level(player.SkillName(skill)) chance := 1.0 @@ -278,7 +267,7 @@ func (g *Game) advanceProduction(sess *net.Session, p *player.Player) bool { } else { defaultSuccess = "You produce %n." } - msg := g.resolveCraftMessage(sess, craft.Message, defaultSuccess, craft, item.ID, byproducts, p.HasItem) + msg := g.resolveCraftMessage(sess, craft.SuccessMessage, defaultSuccess, craft, item.ID, byproducts, p.HasItem) if p.OptionBool("xp_drops") && craft.XP > 0 { msg += g.formatXpDropSingle(sess, p, player.SkillName(skill), craft.XP) } diff --git a/internal/item/item.go b/internal/item/item.go index 0e63156..9c753b1 100644 --- a/internal/item/item.go +++ b/internal/item/item.go @@ -265,7 +265,7 @@ type IngredientEntry struct { } type CraftStep struct { - Tick float64 `yaml:"tick"` + Delay float64 `yaml:"delay"` Message string `yaml:"message"` } @@ -286,7 +286,7 @@ type CraftDef struct { Ingredients []IngredientEntry `yaml:"ingredients"` OutputQty int `yaml:"output_qty"` Fail string `yaml:"fail"` - Message string `yaml:"message"` + SuccessMessage string `yaml:"success_message"` FailMessage string `yaml:"fail_message"` StartMessage string `yaml:"start_message"` EndMessage string `yaml:"end_message"` -- cgit v1.2.3