aboutsummaryrefslogtreecommitdiff
path: root/worldbuilding_guide/objects.md
diff options
context:
space:
mode:
authorhistoria <[not public]>2026-06-21 22:19:17 -0400
committerhistoria <[not public]>2026-06-21 22:19:17 -0400
commita3ae1e6aad696f584d138d9363c05dedff136a65 (patch)
tree81e615f7227bc9d1ec79ceefc7311ecde917b074 /worldbuilding_guide/objects.md
parent84072ffe6365ad57c4976e9272762aa6db41de7e (diff)
downloadthehouseoficarus-a3ae1e6aad696f584d138d9363c05dedff136a65.tar.gz
feat: safespot system implemented
Diffstat (limited to 'worldbuilding_guide/objects.md')
-rw-r--r--worldbuilding_guide/objects.md109
1 files changed, 109 insertions, 0 deletions
diff --git a/worldbuilding_guide/objects.md b/worldbuilding_guide/objects.md
index 38eaeeb..65ab430 100644
--- a/worldbuilding_guide/objects.md
+++ b/worldbuilding_guide/objects.md
@@ -227,3 +227,112 @@ 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` so they only appear in `look` when the player's
+effective safespot tier meets or exceeds the object's required tier. This creates a natural
+discovery mechanic: as players complete quests and achievements, they begin to notice cover
+they couldn't use before.
+
+### 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, re-hiding resets the safespot to max level |
+| `respawn_ticks` | float64 | 0 | Ticks until a destroyed safespot respawns (0 = never) |
+| `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.
+
+### 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!"
+ option safespot_alert none
+
+Default: `"{196 bold}** Your safespot has been compromised! **{/}"`
+
+---
+