aboutsummaryrefslogtreecommitdiff
path: root/building_guide/behaviors.md
diff options
context:
space:
mode:
authorhistoria <[not public]>2026-07-09 22:15:54 -0400
committerhistoria <[not public]>2026-07-09 22:15:54 -0400
commitecba7f726f70b37126d852c38c7e3eec7b04d730 (patch)
tree9129215c6e5015336fde1116395336d82bb952d1 /building_guide/behaviors.md
parentb3d4c616f59ad2519f3a0b77e3b47d6571cd2486 (diff)
downloadthehouseoficarus-ecba7f726f70b37126d852c38c7e3eec7b04d730.tar.gz
feat: old standalone trigger systems completely unified into trigger->condition->action system
Diffstat (limited to 'building_guide/behaviors.md')
-rw-r--r--building_guide/behaviors.md120
1 files changed, 78 insertions, 42 deletions
diff --git a/building_guide/behaviors.md b/building_guide/behaviors.md
index f358a33..3063677 100644
--- a/building_guide/behaviors.md
+++ b/building_guide/behaviors.md
@@ -478,25 +478,38 @@ talk:
### Interaction Reference
-The `Interaction` struct is the shared shape used by `on_use`, `on_look`, `on_kill`,
-`on_traverse`, on_enter steps, and trigger steps. When a list of interactions is evaluated,
-the first whose condition passes wins and fires.
+The unified **Trigger** shape is the shared wrapper used by every event block: `on_use`,
+`on_look`, `on_kill`, `on_traverse`, `on_enter`, `on_exit`, `on_flag_change`,
+`on_global_flag_change`, and global trigger files (`data/triggers/*.yaml`). When a block's
+list of Triggers is evaluated, the first whose filters pass fires and its `steps` run as a
+scripted sequence (first-match-wins).
+
+| Field | Scope | Description |
+|-------|-------|-------------|
+| `lock` | all | `true` = atomic (player can only `quit`) + resumable on reconnect. Default `false` = interruptable, not persisted. |
+| `item_id` | on_use/on_look/on_kill | `on_use`: required item (`use <item> on <obj>`); empty = bare `use <obj>`. `on_look`: only fires if carrying this item. `on_kill`: only fires if wielding this weapon. |
+| `condition` | all | Optional Trigger-level gate (Condition struct). |
+| `steps` | all | Ordered list of Step entries run as a scripted sequence. |
+| `on_player_flag` | on_flag_change only | Player flag this trigger watches. |
+| `on_global_flag` | on_global_flag_change only | Global flag this trigger watches. |
+| `value` | flag triggers | Optional value-match filter. |
+
+Talk node/option actions still use the NodeAction shape (`action:` with the effect fields
+inline) — those have not changed.
+
+#### Step vocabulary
+
+Each Step can carry a `wait` (ticks to pause before the step fires) and any combination of
+the effects below. All effects on a step fire together when the wait elapses. Messages are
+plain strings — neither `{message, delay}` maps nor the old `delay` field exist.
| Field | Type | Description |
|-------|------|-------------|
-| `item_id` | string | `on_use`: required item (empty = bare `use <obj>`). `on_look`: only fires if carrying this item. `on_kill`: only fires if wielding this weapon. |
-| `condition` | Condition | Optional gate |
-| `message` | string | Message shown to the player when this entry fires |
-| `action` | StepAction | Optional effects (see below) |
-
-#### StepAction / NodeAction vocabulary
-
-The universal effect vocabulary used by all interaction types, talk node actions, on_enter
-steps, and trigger steps:
-
-| Field | Type | Description |
-|-------|------|-------------|
-| `set_global_flags` | map[string]any | Set global flags (cascades other triggers) |
+| `wait` | int | Ticks to wait before this step fires. `0`/omitted = next tick. |
+| `messages` | []string | Plain strings sent to the triggering player only. Support `%p`/`%v` templates. |
+| `broadcast` | string | Announce to all players in the room. |
+| `broadcast_global` | string | Announce to all online players. |
+| `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) |
| `give_item` | string | Give one unit of an item to inventory |
| `take_item` | string | Remove one unit of an item from inventory |
@@ -504,13 +517,36 @@ steps, and trigger steps:
| `heal` | int | Restore hitpoints (clamped to MaxHP) |
| `credits` | int | Add (positive) or deduct (negative) credits |
| `aps_node` | bool | Mark current room as discovered APS node |
-| `message` | string | Direct message to the player (`%p`/`%v` supported) |
-| `broadcast` | string | Announce to all in the room |
-| `broadcast_global` | string | Announce to all online |
-| `spawn_mob` | string/map | Spawn a transient mob |
-| `despawn_mob` | string | Despawn all transient mobs of this id |
-| `delay` | int | Ticks to wait (on_enter/triggers only) |
-| `condition` | Condition | Per-step gate (on_enter/trigger steps only) |
+| `spawn_mob` | string/map | Spawn a transient mob (see SpawnMobConfig below) |
+| `despawn_mob` | string | Despawn all trigger-spawned mobs of this id |
+| `condition` | Condition | Per-step gate; evaluated once when the sequence reaches this step |
+
+#### Condition vocabulary
+
+Conditions gate a Trigger (Trigger-level `condition`) or an individual step. A bare
+`global_flag` / `player_flag` check passes when the flag is set to a truthy value;
+`not: true` inverts.
+
+| Field | Description |
+|-------|-------------|
+| `global_flag` | Passes when the named global flag is truthy |
+| `player_flag` | Passes when the named player flag is truthy |
+| `value` | Match a specific (non-boolean) value |
+| `not` | `true` inverts the entire condition |
+| `has_item` | Passes when the player carries this item |
+| `min_credits` | Passes when the player has at least this many credits |
+| `room` | **New.** Passes when the triggering player is currently in this room — use to scope flag-change triggers |
+| `all_of` | List of sub-conditions; all must pass |
+| `any_of` | List of sub-conditions; any one must pass |
+
+#### Lock and first-match-wins
+
+- **First-match-wins:** entries in a block are walked top-to-bottom; the first whose
+ `item_id` and `condition` pass fires and runs its whole `steps` sequence. Other entries
+ are skipped.
+- **Lock:** `lock: true` makes the sequence atomic (the player can only `quit` until it
+ finishes) and resumable across disconnect. Default `false` is interruptable by any verb
+ and not persisted.
#### SpawnMobConfig
@@ -538,9 +574,9 @@ Full config:
### On Kill — Mob Interactions
-Mobs can define `on_kill` — fires when the mob is defeated. Standard loot `drops` hit the
-ground first, then the first matching interaction fires. An entry with `item_id` only fires
-if the player wields that weapon:
+Mobs can define `on_kill` — a `[]Trigger` list that fires when the mob is defeated. Standard
+loot `drops` hit the ground first, then the first matching Trigger fires. An entry with
+`item_id` only fires if the player wields that weapon:
```yaml
name: boss
@@ -548,17 +584,17 @@ combat: ...
on_kill:
- condition:
global_flag: boss_quest_active
- message: "The boss crumbles to dust!"
- action:
- set_global_flags:
- boss_slain: true
- broadcast_global: "%p has slain the World Boss!"
- spawn_mob: boss_add
+ steps:
+ - messages: ["The boss crumbles to dust!"]
+ 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
+ steps:
+ - give_item: boss_heart
+ set_global_flags:
+ dragon_slain: true
```
Task mob `on_kill` works the same way — fires when the work is completed:
@@ -567,10 +603,10 @@ Task mob `on_kill` works the same way — fires when the work is completed:
name: reactor panel
task: ...
on_kill:
- - message: "The panel snaps into place."
- action:
- set_global_flags:
- reactor_repaired: true
- set_player_flags:
- repaired_reactor: true
+ - steps:
+ - messages: ["The panel snaps into place."]
+ set_global_flags:
+ reactor_repaired: true
+ set_player_flags:
+ repaired_reactor: true
```