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 ++++--- 6 files changed, 151 insertions(+), 83 deletions(-) (limited to 'building_guide') 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 -- cgit v1.2.3