aboutsummaryrefslogtreecommitdiff
path: root/building_guide/courses.md
diff options
context:
space:
mode:
authorhistoria <[not public]>2026-06-24 20:58:25 -0400
committerhistoria <[not public]>2026-06-24 20:58:25 -0400
commit9d4b799db4868bcab291b83599ff088763cd4ed6 (patch)
tree252f0fcc779acf35243983d643d6399ee2e0cd0b /building_guide/courses.md
parentd25638d98fe63efdeab570ef77e6a6a97f2d7a60 (diff)
downloadthehouseoficarus-9d4b799db4868bcab291b83599ff088763cd4ed6.tar.gz
feat: new type of non-violent 'combat': work
Diffstat (limited to 'building_guide/courses.md')
-rw-r--r--building_guide/courses.md119
1 files changed, 119 insertions, 0 deletions
diff --git a/building_guide/courses.md b/building_guide/courses.md
new file mode 100644
index 0000000..491e2bd
--- /dev/null
+++ b/building_guide/courses.md
@@ -0,0 +1,119 @@
+## Agility Courses
+
+Agility courses are defined in `data/courses/<id>.yaml`. Each course defines a sequence of obstacle rooms, each with a specific verb the player must type to advance. Obstacle rooms themselves are standard room YAML files (typically in `data/rooms/agility/`).
+
+### Course YAML
+
+```yaml
+id: "vent_shaft"
+name: "Ventilation Shaft Course"
+required_level: 1
+start_room: 200
+completion_xp: 40
+obstacles:
+ - room_id: 201
+ verb: scramble
+ ticks_per_phase: 2
+ xp: 8
+ fail_damage: [1, 2]
+ messages:
+ - "You approach the corroded ventilation wall..."
+ - "You find footholds in the rusted panels and begin to climb..."
+ - "You scramble up the wall and haul yourself onto the ledge!"
+ - room_id: 202
+ verb: balance
+ ticks_per_phase: 2
+ xp: 8
+ fail_damage: [1, 2]
+ messages:
+ - "You step onto the narrow coolant pipe..."
+ - "Arms outstretched, you carefully place one foot in front of the other..."
+ - "You reach the other side of the pipe and step onto solid ground!"
+```
+
+### CourseConfig Fields
+
+| Field | Type | Description |
+| ---------------- | ------------- | ---------------------------------------------------- |
+| `id` | string | Unique course identifier |
+| `name` | string | Display name shown to players |
+| `required_level` | int | Minimum Agility level to attempt the course |
+| `start_room` | int | Hub room — teleported here on fail or lap completion |
+| `completion_xp` | int | Bonus XP awarded when a full lap is completed |
+| `obstacles` | []ObstacleDef | Ordered list of obstacles |
+
+### ObstacleDef Fields
+
+| Field | Type | Description |
+| ----------------- | -------- | --------------------------------------------------------------------------- |
+| `room_id` | int | Room ID for this obstacle |
+| `verb` | string | Command the player types to attempt it (e.g. `scramble`, `jump`, `climb`) |
+| `ticks_per_phase` | float64 | Ticks between each phase message (supports fractional via `engine.ToTicks`) |
+| `xp` | int | XP awarded for successfully completing this single obstacle |
+| `fail_damage` | [2]int | `[min, max]` damage on failure (HP clamped to minimum 1 — cannot kill) |
+| `messages` | []string | Exactly 3 strings for the 3-phase advancement system |
+
+### 3-Phase Message System
+
+Each obstacle advances through 3 phases, printing one message per phase:
+
+```
+Phase 0 (start): messages[0] printed immediately
+Phase 1 (middle): messages[1] printed — FAILURE CHECK happens here
+Phase 2 (end): messages[2] printed — XP awarded, teleport to next room
+```
+
+Failure only occurs at phase 1. Success chance is based on Agility level:
+- At required level: 70% success (30% fail)
+- Each level above reduces fail chance by 1% (down to minimum 5%)
+- Fail chance capped at 60%
+
+On failure, the player takes random damage in `[fail_damage[0], fail_damage[1]]`, is teleported back to `start_room`, and must restart the course.
+
+### Lap Counting
+
+Completing all obstacles in a course increments a lap counter stored as a player flag (`agility_laps_<course_id>`). The `completion_xp` bonus is awarded on the final obstacle only.
+
+### Obstacle Room YAML
+
+Each obstacle room should have an `on_enter` message telling the player which verb to use, and a `down` exit back to the course hub:
+
+```yaml
+id: 201
+name: "Ventilation Shaft - Corroded Wall"
+description: "A towering wall of corroded ventilation panels..."
+on_enter:
+ - message: "Type 'scramble' to climb the wall."
+exits:
+ down:
+ room: 200
+ blocked_message: ""
+```
+
+The hub room (e.g. room 200) links to the first obstacle of each course:
+
+```yaml
+id: 200
+name: "Agility Training Grounds"
+exits:
+ south: 17
+ north: 201 # Vent Shaft (level 1)
+ east: 210 # Rooftop (level 20)
+ west: 220 # Reactor (level 50)
+```
+
+### Supported Obstacle Verbs
+
+| Verb | Gerund (display) |
+| ---------- | ---------------- |
+| `scramble` | scrambling |
+| `jump` | jumping |
+| `swing` | swinging |
+| `balance` | balancing |
+| `climb` | climbing |
+| `crawl` | crawling |
+| `vault` | vaulting |
+| `leap` | leaping |
+| `slide` | sliding |
+
+Obstacle verbs are auto-registered at startup from all course YAML files. No changes to `cmd_registry.go` needed when adding new courses — any verb in a `data/courses/` file will work.