diff options
| author | historia <[not public]> | 2026-06-24 20:58:25 -0400 |
|---|---|---|
| committer | historia <[not public]> | 2026-06-24 20:58:25 -0400 |
| commit | 9d4b799db4868bcab291b83599ff088763cd4ed6 (patch) | |
| tree | 252f0fcc779acf35243983d643d6399ee2e0cd0b /worldbuilding_guide/objects.md | |
| parent | d25638d98fe63efdeab570ef77e6a6a97f2d7a60 (diff) | |
| download | thehouseoficarus-9d4b799db4868bcab291b83599ff088763cd4ed6.tar.gz | |
feat: new type of non-violent 'combat': work
Diffstat (limited to 'worldbuilding_guide/objects.md')
| -rw-r--r-- | worldbuilding_guide/objects.md | 392 |
1 files changed, 0 insertions, 392 deletions
diff --git a/worldbuilding_guide/objects.md b/worldbuilding_guide/objects.md deleted file mode 100644 index 427968a..0000000 --- a/worldbuilding_guide/objects.md +++ /dev/null @@ -1,392 +0,0 @@ -## Objects - -Objects interact with the world through **inline behavior configs** under -`gather:`, `talk:`, or `use:` keys. There is no separate behavior -directory — everything goes directly in the object's YAML. - -Gathering object (mining): -```yaml -id: copper_rock -name: copper rock -color: "178" # xterm-256 color index (0-255) -gather: - skill: mining - level: 1 - xp: 17 - base_wait: 8 - tools: - - pickaxe - success: - base: 0.40 - per_level: 0.01 - cap: 0.95 - gather_message: "You swing your pickaxe at the rock..." - fail_message: "You chip away but get nothing useful." - drops: - - item_id: copper_ore - weight: 90 - depletes: true - message: "You manage to mine some {178}copper ore{/}." - - table: gem_table - weight: 10 - depletes: false - message: "You spot a glint of something valuable!" - respawn_timer: 50 - respawn_broadcast: "A glint of copper catches your eye from some {name}." -``` - -Tree object (woodcutting with shared depletion): -```yaml -id: oak_tree -name: oak tree -color: "113" -gather: - skill: woodcutting - level: 15 - xp: 37 - base_wait: 6 - tools: - - axe - success: - base: 0.40 - per_level: 0.01 - cap: 0.90 - gather_message: "You swing your axe at the oak tree..." - fail_message: "You swing but get no logs." - drops: - - item_id: oak_logs - weight: 100 - depletes: false - message: "You get some {113}oak logs{/}." - respawn_timer: 14 - deplete_timer: 45 - nest_chance: 256 - respawn_broadcast: "An {name} grows back." -``` - -Color accepts xterm-256 indices with optional modifiers (`bold`, `dim`, `underline`) -and gradients (`g:196,82`). In ANSI mode, extended colors downgrade to the nearest -ANSI color. - -Object interaction (gate, lever — uses `use_interactions:` key): -```yaml -id: iron_gate -name: iron gate -hidden: true -description: "A heavy iron gate set into the north wall." -use_interactions: - - condition: - flag: gate_open - value: true - not: true - message: "You push the heavy iron gate open." - action: - set_flags: - gate_open: true -``` - -Decorative object (no behavior keys — just a name/description): -```yaml -id: lumby_fountain -name: town fountain -description: "Clear water sparkles in the sunlight." -``` - -Talk object (NPC conversations — uses `talk:` key): -```yaml -id: tool_shed -name: Tool Shed -description: "A small shed with an open window." -talk: - nodes: - start: - message: "\"Welcome to the tool shed!\"" - options: - - text: "\"What do you have?\"" - goto: shop - - text: "\"Goodbye.\"" - end: true -``` - -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. - -Entries are checked top-to-bottom; the first match with a passing condition wins. - -Simple message (no action): -```yaml -id: anvil -name: anvil -use_interactions: - - item_id: silver_bar - message: "You should use this with a mold at a furnace." - - item_id: gold_bar - message: "You should use this with a mold at a furnace." -``` - -Puzzle interaction (take item, set flag): -```yaml -id: crystal_slot -name: crystal slot -use_interactions: - - item_id: crystal_key - condition: - 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." - action: - take_item: crystal_key - set_flags: - crystal_inserted: true -``` - -Quest item exchange: -```yaml -use_interactions: - - item_id: ancient_scroll - condition: - player_flag: quest_started - message: "You place the scroll on the pedestal. The door rumbles open!" - action: - take_item: ancient_scroll - set_player_flags: - quest_complete: true - set_flags: - 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_flags` | map[string]any | Set world 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 | -| ------------- | -------------------------------- | -| `flag` | World 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 | - ---- - -## Stealable Objects - -Objects can be stealable via the `steal` command. These use the same drop table system as mobs and searches. - -```yaml -id: market_stall -name: Market Stall -description: "A wooden stall piled with food and sundries." -steal_table: market_stall_steal -steal_level: 5 -steal_xp: 12 -steal_speed: 5 -guard_mob: guard -``` - -| Field | Description | -| ------------- | ------------------------------------------------ | -| `steal_table` | Drop table ID for loot when stealing | -| `steal_level` | Required thieving level | -| `steal_xp` | XP awarded per successful steal | -| `steal_speed` | Ticks per steal attempt (base wait) | -| `guard_mob` | Mob def ID that guards this object (watches it) | - -When `guard_mob` is set, a mob with that def ID in the same room watches the object -on a tick-based cycle (8 ticks watching, 4 ticks looking away). While the guard is -watching, steal success chance is halved and failures trigger a confrontation dialog. - -Use the `sneak` command to see guard watch state changes in real time. - ---- - -## Safespots - -Safespot objects provide cover that blocks melee attacks. Players use `hide <object>` to -crouch behind them and attack with ranged or science weapons. Melee attacks force the player -out of cover. - -```yaml -id: rock_outcrop -name: rock outcrop -color: "248" -hidden: true -inroom_description: "A jagged rock outcrop juts from the floor." -description: "A large, jagged rock formation providing natural cover." -safespot: - tier: 2 - max_block_size: large - max_occupants: 3 - unsafe_chance: 0.008 - decay_ticks: 500 - decay_chance: 0.01 - respawn_on_hide: false - respawn_ticks: 300 - levels: - - message: "The rock formation stands solid." - degrade_message: "The rock structure begins crumbling!" - - message: "The rock outcrop is cracked and worn." - degrade_message: "A few jagged bits are all that's left of the rock outcrop!" - - message: "Only a few jagged rocks remain." - degrade_message: "The rock outcrop crumbles to nothing!" -``` - -Safespot objects should be `hidden: true`. They never appear in room descriptions — players -discover them through quest guidance, `inroom_description` text in the room's YAML, or by -examining objects directly with `look <name>`. - -### SafespotConfig Fields - -| Field | Type | Default | Description | -|---|---|---|---| -| `tier` | int | 0 | Required safespot tier to use this object | -| `max_block_size` | string | `""` (all) | Largest mob size blocked: small/medium/large/massive | -| `max_occupants` | int | 0 | Max players that can hide behind this object (0 = unlimited) | -| `unsafe_chance` | float64 | 0 | Per-tick chance (0.0-1.0) to be forced out of cover | -| `decay_ticks` | float64 | 0 | Guaranteed ticks before object degrades one level | -| `decay_chance` | float64 | 0 | Per-tick random chance (0.0-1.0) to degrade one level | -| `respawn_on_hide` | bool | false | If true, hiding behind an empty safespot resets it to max level. Only triggers when no occupants are present. | -| `respawn_ticks` | float64 | 0 | Ticks until a destroyed safespot respawns (0 = never respawns — object is deleted from the room) | -| `levels` | []SafespotLevel | required | At least one level entry | - -### SafespotLevel Fields - -| Field | Type | Description | -|---|---|---| -| `message` | string | Shown to the player when the safespot is at this level | -| `degrade_message` | string | Broadcast to the room when the safespot degrades FROM this level | - -Levels are ordered from highest to lowest. The first entry is the safespot's best state; -the last entry is its weakest state before destruction. When the last level degrades, -the safespot is destroyed. - -### Three Safespot Patterns - -The combination of `respawn_on_hide` and `respawn_ticks` creates three distinct use cases: - -**1. Standard Safespot (always available)** - -```yaml -safespot: - respawn_on_hide: true - respawn_ticks: 0 - levels: - - message: "You crouch behind the rock formation, using it as cover." -``` - -The safespot starts at full health each time a player hides behind it (first occupant only — -subsequent players don't reset the level). Ideal for skilling areas and general exploration. -Since `respawn_ticks: 0`, a destroyed safespot would be deleted, but with a single level and -no decay, it never degrades. Simple and permanent. - -**2. Regenerating Safespot (timer-based respawn)** - -```yaml -safespot: - respawn_on_hide: false - respawn_ticks: 300 - levels: - - message: "The rock formation stands solid." - degrade_message: "The rock structure begins crumbling!" - - message: "The rock outcrop is cracked and worn." - degrade_message: "A few jagged bits are all that's left!" - - message: "Only a few jagged rocks remain." - degrade_message: "The rock outcrop crumbles to nothing!" -``` - -Degradation persists between hides — a player who leaves and re-hides finds the -safespot at its previous level. After total destruction, a timer (`respawn_ticks`) -counts down, then the safespot reforms at full health. Suits areas with heavy use -where a temporary respite is valuable. - -**3. Disposable Safespot (boss fight cover)** - -```yaml -safespot: - respawn_on_hide: false - respawn_ticks: 0 - levels: - - message: "The barricade offers solid cover." - degrade_message: "The barricade splinters under the assault!" - - message: "The barricade is splintering badly." - degrade_message: "The barricade shatters completely!" -``` - -Degradation persists between hides. When the last level degrades, the safespot is -**deleted from the room entirely** — it does not respawn. Perfect for boss encounters -where a room script places temporary cover that the party consumes during the fight. -Once destroyed, it's gone for good (until the boss room re-instantiates it). - -### Mob Size - -Mobs must have a `size` field for safespot blocking to work: - -```yaml -# data/mobs/cow.yaml -size: small - -# data/mobs/moss_giant.yaml -size: large -``` - -Size ordering: `small` < `medium` < `large` < `massive`. Defaults to `medium` when absent. -A safespot with `max_block_size: large` blocks mobs of size small, medium, and large, -but not massive. - -### Progression - -Players gain safespot tier by completing quests and combat achievements, which set -player flags via talk node actions: - -| Flag | Source | Tier bonus | -|---|---|---| -| `quest_animal_magnetism` | Quest completion | +1 | -| `quest_dragon_slayer` | Quest completion | +1 | -| `achieve_medium_combat` | Combat achievement | +1 | -| `achieve_hard_combat` | Combat achievement | +2 | - -### Combat Integration - -- Melee mobs (attack_type: stab/slash/crush) cannot initiate aggro or land hits on - safespotted players if the mob's size is within the safespot's `max_block_size`. -- Ranged and science mobs (attack_type: ranged/science) ignore safespots entirely. -- If a safespotted player attacks with melee, they automatically leave cover. -- Hiding in combat takes 4 ticks; if the mob hits during this time, the hide fails. -- Hiding out of combat takes 1 tick. - -### Option: safespot_alert - -Players can customize the message shown when forced out of a safespot: - - option safespot_alert "{196 bold}** DANGER **{/} Cover blown!" -Default: `"{196 bold}** Your safespot has been compromised! **{/}"` - ---- - |
