diff options
Diffstat (limited to 'building_guide')
| -rw-r--r-- | building_guide/admin.md | 4 | ||||
| -rw-r--r-- | building_guide/behaviors.md | 147 | ||||
| -rw-r--r-- | building_guide/conditions.md | 5 | ||||
| -rw-r--r-- | building_guide/doors.md | 4 | ||||
| -rw-r--r-- | building_guide/hidden_objects.md | 4 | ||||
| -rw-r--r-- | building_guide/objects.md | 116 | ||||
| -rw-r--r-- | building_guide/triggers.md | 18 |
7 files changed, 222 insertions, 76 deletions
diff --git a/building_guide/admin.md b/building_guide/admin.md index af2184c..d66aabe 100644 --- a/building_guide/admin.md +++ b/building_guide/admin.md @@ -251,8 +251,8 @@ the game server and is configured in `config.yaml` under `admin_http` (plain HTT |------|-----|-------------| | 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. | +| Objects | `/editor/objects` | CRUD editor with sections for gather (tools/drops/success formula), use (message/wait/consumes), talk (visual talk tree editor), safespot, steal, on_use (interactions — see Effects help in-card), on_look (interactions, same row UI), and the raw-file editor covers on_use/on_look + on_kill on mobs. | +| Mobs | `/editor/mobs` | CRUD for mob definitions — stats, drops, talk, shop, behavior, assassin/steal/task fields, plus on_kill interaction cards. | | 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). | diff --git a/building_guide/behaviors.md b/building_guide/behaviors.md index 1857681..3b7d769 100644 --- a/building_guide/behaviors.md +++ b/building_guide/behaviors.md @@ -266,9 +266,13 @@ talk: | `teleport` | Moves the player to a room ID. | | `heal` | Restores that many hitpoints. | | `credits` | Credits charged (negative) or awarded (positive). | -| `reputation_cost` | Deducts reputation from `assassin_reputation` flag before other actions. | | `aps_node` | Marks this room's APS node as unlocked. | +The full effect vocabulary (used by all interaction types and on_enter/trigger +steps) additionally includes `message`, `broadcast`, `broadcast_global`, +`spawn_mob`, `despawn_mob`, and `delay` — see [interaction +reference](#interaction-reference) below. + > **Planned (not yet implemented):** `assign_task`, `skip_task`, `extend_task`, and `sawmill` are under design and will be added in a future update. All fields in a single action are processed together — give an item, take an item, set flags, @@ -521,19 +525,26 @@ talk: A specialty shop that only buys back its own stock sets `buys_anything: false`. -### Object Interactions (levers, switches, gates) +### Object Interactions (levers, switches, gates) — `on_use` and `on_look` + +Interactions are the unified, conditional action system shared by objects +(`on_use`, `on_look`), mobs (`on_kill`), exit traversal +(`on_traverse`), on_enter steps, room/global triggers, talk nodes, and talk +options. Each interaction has an optional condition, an optional message, +and an optional `action` (the full effect vocabulary). When a list of +interactions is evaluated, the first whose condition passes wins and fires. -Interaction configs go under the `use_interactions:` key on objects. -Entries with no `item` field are bare interactions triggered by "use" -or "push"/"pull": +On objects, `on_use` runs when the player types `use <obj>` (bare) or +`use <item> on <obj>` (item-specific). Entries with no `item_id` are bare (fire when `use <obj>` is typed) — +triggered by `use <obj>`: ```yaml name: iron gate hidden: true description: "A heavy iron gate set into the north wall." -use_interactions: +on_use: - condition: - flag: gate_open + global_flag: gate_open value: true not: true message: "You push the heavy iron gate open." @@ -545,7 +556,7 @@ use_interactions: Item-specific interaction: ```yaml name: bookshelf -use_interactions: +on_use: - item_id: dusty_tome message: "The bookshelf slides aside, revealing a secret passage!" action: @@ -553,4 +564,124 @@ use_interactions: secret_passage_open: true ``` +`on_look` runs after the description is shown when the player types +`look <obj>`. It is a list of interactions (same shape), with `item_id` +acting as a *has_item* gate: an entry with an `item_id` only fires if the +player currently carries that item in their inventory (empty = always fires +on look). +typically empty: + +```yaml +name: sign +on_look: + - set_player_flags: + read_sign: true +``` + +--- + +### Interaction Reference + +The `Interaction` struct is the shared per-entry shape: + +| Field | Type | Description | +| ----------- | ---------- | --------------------------------------------------------------- | +| `item_id` | string | `on_use`: required item id (empty = bare `use <object>`). `on_look`: only fires if you carry this item. `on_kill`: only fires if you wield this weapon (main_hand or off_hand) when the mob is defeated. | +| `condition` | Condition | Optional gate (see [conditions](conditions.md)) | +| `message` | string | Message shown to the player when this entry fires | +| `action` | StepAction | Optional effects — the full superset below | + +The `StepAction` superset is the universal effect container used by every +interaction type, talk node actions, on_enter steps, and trigger steps. The +inline-only `NodeAction` fields are the subset historically used by talk +nodes; the additional sequence-only fields (`message`, `broadcast`, +`broadcast_global`, `spawn_mob`, `despawn_mob`, `delay`) are available on +all of them but primarily meaningful for on_enter/triggers (inline callers +may use `broadcast` to announce to the room — handy for `on_kill` +announcements). + +| Field | Type | Description | +| ------------------ | -------------- | -------------------------------------------------------------------- | +| `set_global_flags` | map[string]any | Set global flags (shared by all players; cascades other triggers) | +| `set_player_flags` | map[string]any | Set player flags (per-character, saved to YAML; cascades) | +| `give_item` | string | Give one unit of an item to inventory | +| `take_item` | string | Remove one unit of an item from inventory | +| `teleport` | int | Move player to a room ID; runs `look` + `on_enter` of the destination | +| `heal` | int | Restore hitpoints (clamped to MaxHP) | +| `credits` | int | Add (positive) or deduct (negative) credits (gated by affordability) | +| `aps_node` | bool | Mark the current room as a discovered APS node on the datapad | +| `message` | string | Direct message to the player (template vars `%p`/`%v` supported) | +| `broadcast` | string | Announce to all in the room (`%p`/`%v` substituted per recipient) | +| `broadcast_global` | string | Announce to all online (`%p`/`%v` substituted per recipient) | +| `spawn_mob` | string/map | Spawn a transient mob — bare string (id) or full [config](#spawn-mob-config) | +| `despawn_mob` | string | Despawn all transient mobs of this id (optionally owner-filtered) | +| `delay` | int | Ticks to wait before this step fires (on_enter/triggers only) | +| `condition` | Condition | Per-step gate (on_enter steps and trigger steps; evaluated before firing) | + +### Mob Interactions (On Kill) + +Mobs can define `on_kill` (fires when this mob is defeated — either by a +combat kill or by a `kind: task` mob's HP draining to zero, the +"completion" of the work). It is additive — standard loot `drops` still +hit the ground first, then the first matching interaction fires. An +entry with an `item_id` only fires if the player is wielding that item +in a weapon-hand slot (main_hand or off_hand) at the moment of the kill. + +```yaml +name: boss +combat: ... +on_kill: + - condition: + global_flag: boss_quest_active + message: "The boss crumbles to dust. The Guardian Stone reverberates!" + action: + set_global_flags: + boss_slain: true + broadcast_global: "%p has slain the World Boss!" + spawn_mob: boss_add + - item_id: dragon_slayer + action: + give_item: boss_heart + set_global_flags: + dragon_slain: true +``` + +```yaml +name: reactor panel +task: ... +on_kill: + - message: "With a final burst of effort, the panel snaps into place." + action: + set_global_flags: + reactor_repaired: true + set_player_flags: + repaired_reactor: true +``` + +### Spawn Mob Config + +For transient mob spawning (in `spawn_mob:` fields), pass either a bare +string (the mob ID) or a map with these fields: + +```yaml +spawn_mob: rat +``` + +```yaml +spawn_mob: + id: boss_add + owner_only: true + despawn_on_leave: true + despawn_rooms: [100, 101] + despawn_ticks: 30.0 +``` + +| Field | Description | +| ----------------- | ------------------------------------------------------------------------ | +| `id` | Mob ID to spawn (required when a map) | +| `owner_only` | If true, the spawn is private to the triggering player | +| `despawn_on_leave`| Trigger-spawned mob fades after leaving the owner's room (grace window) | +| `despawn_rooms` | List of rooms where the spawn survives without ticking the despawn timer | +| `despawn_ticks` | Despawn countdown in ticks (float OK; rounded probabilistically via `engine.ToTicks`) | + --- diff --git a/building_guide/conditions.md b/building_guide/conditions.md index acfdf57..2fb3d7a 100644 --- a/building_guide/conditions.md +++ b/building_guide/conditions.md @@ -1,8 +1,9 @@ ## Conditions Reference Conditions are used in talk option guards, talk node conditions, exit gates, -on-enter scripts, use_interactions checks, room descriptions, object -descriptions, and trigger value matching. +on-enter scripts, on_use / on_look / on_kill interactions, +exit on_traverse interactions, room descriptions, object descriptions, and +trigger value matching. ### Simple conditions diff --git a/building_guide/doors.md b/building_guide/doors.md index 358001f..c987d0f 100644 --- a/building_guide/doors.md +++ b/building_guide/doors.md @@ -10,9 +10,9 @@ A button in room 3 opens a door in room 7. Anyone can press it. Once pressed, th ```yaml name: stone button hidden: true -use_interactions: +on_use: - condition: - flag: secret_door_open + global_flag: secret_door_open not: true message: "You press the stone button. You hear grinding stone in the distance." action: diff --git a/building_guide/hidden_objects.md b/building_guide/hidden_objects.md index b1ed7b4..1866d67 100644 --- a/building_guide/hidden_objects.md +++ b/building_guide/hidden_objects.md @@ -9,9 +9,9 @@ Objects with `hidden: true` don't appear in the room's object listing. Players d name: stone lever hidden: true description: "A cleverly concealed lever behind a loose stone." -use_interactions: +on_use: - condition: - flag: secret_passage_open + global_flag: secret_passage_open value: true not: true message: "You pull the lever. A grinding sound echoes from the east." diff --git a/building_guide/objects.md b/building_guide/objects.md index a8877a7..db72cf3 100644 --- a/building_guide/objects.md +++ b/building_guide/objects.md @@ -49,8 +49,8 @@ objects: description: |- Conditional or multi-line descriptions work exactly like file objects. on_look: - set_player_flags: - 1001_look_sign: true + - set_player_flags: + 1001_look_sign: true ``` - **Identity comes from `name`.** Internally the object's id is the name, normalized @@ -69,7 +69,7 @@ objects: - Local objects support only the **passive subset**: `name`, `aliases`, `color`, `hidden`, `inroom_description`, `description` (including conditional variants), and `on_look`. - Interactable / stateful behavior (`gather`, `talk`, `use`, `safespot`, `steal`, `guard_mob`, - `removal_item`, `use_interactions`, craft stations) **must** be a standalone object file; + `removal_item`, `on_use`, craft stations) **must** be a standalone object file; startup validation errors if those appear locally. - Local objects are re-read from the room file on every access, so edits take effect immediately (file objects are cached after first load). @@ -137,14 +137,14 @@ Color accepts xterm-256 indices with optional modifiers (`bold`, `dim`, `underli and gradients (`g:C4,52`). In ANSI mode, extended colors downgrade to the nearest ANSI color. -Object interaction (gate, lever — uses `use_interactions:` key): +Object interaction (gate, lever — uses `on_use:` key): ```yaml name: iron gate hidden: true description: "A heavy iron gate set into the north wall." -use_interactions: +on_use: - condition: - flag: gate_open + global_flag: gate_open value: true not: true message: "You push the heavy iron gate open." @@ -173,35 +173,40 @@ talk: - text: "\"Goodbye.\"" ``` -On-look action (runs when a player examines an object with `look <name>`): +On-look interaction (runs when a player examines an object with `look <name>`): ```yaml name: sign aliases: [notice, board] description: "A wooden signpost with faded writing." on_look: - set_player_flags: + - set_player_flags: read_sign: true ``` -`on_look` fires the action AFTER showing the object's description. It uses the same -`NodeAction` type as talk nodes — supports `set_player_flags`, `set_global_flags`, -`give_item`, `take_item`, `teleport`, `heal`, `cost`, and everything else in the -[node action reference](behaviors.md#node-action-reference). +`on_look` is a list of interactions (same shape as `on_use`). The first entry +whose `item_id` and `condition` pass wins, and fires AFTER the object's +description is shown. An entry with an `item_id` only fires if the player +currently carries that item in their inventory (empty `item_id` = always +fires on look). It uses the same `interaction` shape as `on_use` — supports +`condition`, `message`, and a full `action` (`set_global_flags`, +`set_player_flags`, `give_item`, `take_item`, `teleport`, `heal`, `credits`, +`aps_node`, `broadcast`, `broadcast_global`, `spawn_mob`, `despawn_mob`, +`delay`), per the [interaction reference](behaviors.md#interaction-reference). See the [Talk section of behaviors](behaviors.md#talk-dialog-trees) for the full dialog tree format. See [Stealable Objects](#stealable-objects) for theft mechanics. --- -## Use Interactions - -Objects can define `use_interactions` to handle when a player uses a specific item on the object. Each interaction can check conditions, show a message, and execute actions — using the same condition and action primitives as the talk system. +## Interactions (On Use / On Look) -Entries are checked top-to-bottom; the first match with a passing condition wins. +Objects can define `on_use` and/or `on_look` to react to player actions. Both take a +list of interactions (entries are checked top-to-bottom; the first whose +`condition` passes wins — one fires per use/look). Simple message (no action): ```yaml name: anvil -use_interactions: +on_use: - item_id: silver_bar message: "You should use this with a mold at a furnace." - item_id: gold_bar @@ -211,10 +216,10 @@ use_interactions: Puzzle interaction (take item, set flag): ```yaml name: crystal slot -use_interactions: +on_use: - item_id: crystal_key condition: - flag: crystal_inserted + global_flag: crystal_inserted message: "The crystal key is already in the slot." - item_id: crystal_key message: "You insert the crystal key into the slot. It clicks into place." @@ -226,7 +231,7 @@ use_interactions: Quest item exchange: ```yaml -use_interactions: +on_use: - item_id: ancient_scroll condition: player_flag: quest_started @@ -239,37 +244,46 @@ use_interactions: temple_door_open: true ``` -### UseInteraction Fields - -| Field | Type | Description | -| ----------- | ---------- | ------------------------------------------------ | -| `item_id` | string | Item ID that triggers this interaction | -| `condition` | Condition | Optional condition (same as exits/talk/use_interactions) | -| `message` | string | Message shown to the player | -| `action` | NodeAction | Optional actions (same as talk node actions) | - -### Available Actions (same as talk) - -| Field | Type | Description | -| ------------------ | -------------- | ---------------------------------- | -| `set_global_flags` | map[string]any | Set global flags (shared) | -| `set_player_flags` | map[string]any | Set player flags (per-character) | -| `give_item` | string | Give an item to inventory | -| `take_item` | string | Remove an item from inventory | -| `teleport` | int | Move player to a room ID | -| `heal` | int | Restore hitpoints | - -### Available Conditions (same as exits/talk) - -| Field | Description | -| ------------- | -------------------------------- | -| `global_flag` | Global flag check | -| `player_flag` | Per-character flag check | -| `has_item` | Inventory item check | -| `value` | Expected value for flag checks | -| `not` | Invert the condition | -| `all_of` | All sub-conditions must pass | -| `any_of` | Any sub-condition must pass | +### Interaction Fields + +| Field | Type | Description | +| ----------- | ---------- | --------------------------------------------------------------- | +| `item_id` | string | `on_use`: required item id (empty = bare `use <object>`). `on_look`: only fires if you carry this item. (Mobs' `on_kill`: only fires if you wield this weapon in main_hand or off_hand.) | +| `condition` | Condition | Optional condition (same as exits/talk/on_enter/triggers) | +| `message` | string | Message shown to the player when this entry fires | +| `action` | StepAction | Optional actions (see [interaction reference](behaviors.md#interaction-reference)) | + +### Available Actions (same superset as on_enter steps/triggers/talk) + +| Field | Type | Description | +| ------------------ | -------------- | ----------------------------------------------------- | +| `set_global_flags` | map[string]any | Set global flags (shared by all players) | +| `set_player_flags` | map[string]any | Set player flags (per-character, saved to YAML) | +| `give_item` | string | Give an item to inventory (1 unit) | +| `take_item` | string | Remove an item from inventory (1 unit) | +| `teleport` | int | Move player to a room ID | +| `heal` | int | Restore hitpoints (clamped to MaxHP) | +| `credits` | int | Add (positive) or deduct (negative) credits | +| `aps_node` | bool | Mark current room as a discovered APS node | +| `broadcast` | string | Announce to all in the room (uses `%p`, `%v`) | +| `broadcast_global` | string | Announce to all online (uses `%p`, `%v`) | +| `spawn_mob` | string/map | Spawn a transient mob (`id` or full [config](behaviors.md#spawn-mob-config)) | +| `despawn_mob` | string | Despawn all transient mobs of this id | +| `message` | string | Direct message to the player (also valid here) | +| `delay` | int | Ticks to wait before this step (only meaningful in on_enter/triggers) | + +### Available Conditions (same as exits/talk/on_enter/triggers) + +| Field | Description | +| ------------- | ------------------------------------------------------- | +| `global_flag` | Global flag check | +| `player_flag` | Per-character flag check | +| `has_item` | Inventory item check | +| `min_credits` | Minimum credits | +| `value` | Expected value for flag checks | +| `not` | Invert the condition | +| `all_of` | All sub-conditions must pass | +| `any_of` | Any sub-condition must pass | --- diff --git a/building_guide/triggers.md b/building_guide/triggers.md index 0d227bd..69cd3d1 100644 --- a/building_guide/triggers.md +++ b/building_guide/triggers.md @@ -39,13 +39,13 @@ and the object are cleanly separated. The sign is a local object in room `1001`: objects: - name: sign on_look: - set_player_flags: - 1001_look_sign: true + - set_player_flags: + 1001_look_sign: true ``` This separation is deliberate. The object sets flags. The trigger watches flags. -Any system that sets a player flag (`on_look`, talk nodes, on-enter steps, exits, -use interactions) can activate a trigger watching that flag. +Any system that sets a player flag (`on_look`, `on_use`, `on_kill`, talk nodes, +on-enter steps, exit `on_traverse`) can activate a trigger watching that flag. --- @@ -396,8 +396,8 @@ advances a numeric flag through stages. The last stage spawns a boss. # data/objects/unique/5001_body.yaml name: body on_look: - set_player_flags: - investigation: 1 + - set_player_flags: + investigation: 1 ``` **Step 2: Blood trail in room 5002** — room trigger fires on value 1 @@ -504,12 +504,12 @@ All of these paths activate triggers: | Source | Example | |---|---| -| Object `on_look` | `look sign` sets `1001_look_sign: true` | +| Object `on_look` / `on_use` | `look sign` sets `1001_look_sign: true` | +| Mob `on_kill` | Killing a boss sets `boss_slain: true` | | Talk node actions | NPC sets `quest_started: true` after accepting | | Talk option actions | Player selects a choice that sets a flag | | On-enter steps | Room entry sets `1001_welcome: true` | -| Exit traversal | Walking through an exit sets `boarded_shuttle: true` | -| Use interactions | `push button` sets `gate_open: true` | +| Exit `on_traverse` | Walking through an exit sets `boarded_shuttle: true` | | Trigger steps | One trigger chain-sets a flag for another trigger | --- |
