diff options
| author | historia <[not public]> | 2026-07-08 19:59:14 -0400 |
|---|---|---|
| committer | historia <[not public]> | 2026-07-08 19:59:14 -0400 |
| commit | 09d325dcf5e779eab5550d3fd3377bde50101428 (patch) | |
| tree | a433be903aabbf1d2eadce2aacdac12a9eb8dde0 /building_guide/behaviors.md | |
| parent | 9184377301c2604e003f36426788c032fb0ca524 (diff) | |
| download | thehouseoficarus-09d325dcf5e779eab5550d3fd3377bde50101428.tar.gz | |
feat: unify on use, on look, and on kill. all support same conditions/actions now.
Diffstat (limited to 'building_guide/behaviors.md')
| -rw-r--r-- | building_guide/behaviors.md | 147 |
1 files changed, 139 insertions, 8 deletions
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`) | + --- |
