docs(content): create the content roadmap — Spine, BOM, Backlog

Implements the docs restructure half of the content-track design (the
currency item is code and stays unbuilt). Content stops being unbounded:
the work is now a countable checklist with an end.

content/roadmap.md — new. Three sections, only one of which is ever the
work:
  Spine     Greywater Docks + one dungeon, patron Ghaul the Yoke; the
            cosmology touching ground. Plus what is already canon.
  BOM       ~57 discrete pieces for a complete, playable game, per
            milestone. Numbers, not vibes.
  Backlog   Everything the slice does not need. Not a debt — where ideas
            go to be safe.

Its rule: never author anything that is not in the Bill of Materials.

The BOM carries a Fixed/Variable column — the seven-campaign saga spec's
only ask of this table. ~37 fixed / ~20 variable: a second town costs the
20, not the 57. That is also the exact split v2 generation would need.

content/lore/canon-roadmap.md becomes a pointer (older specs and plans
reference the old path). An items-and-prices table does not belong under
lore/.

docs/roadmap.md — M4..M9 each gain a "Content it consumes →" line into
the BOM.

world-building skill — SKILL.md and evals.json now point at
content/roadmap.md, and the skill is told to respect the BOM rule: ideas
that arrive during authoring go to the Backlog, not into the world.

Build + --check green; generated content/world and content/server are
byte-identical. No Python touched.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-12 17:31:30 -05:00
parent ef335a93c3
commit 9e8fc55a44
6 changed files with 207 additions and 66 deletions

View File

@@ -148,8 +148,13 @@ touched those, just confirm they're valid JSON.)
Summarize: new ids added (by layer), any existing id you reused in `related`, Summarize: new ids added (by layer), any existing id you reused in `related`,
anything you flagged for approval, and confirmation the build + check + tests are anything you flagged for approval, and confirmation the build + check + tests are
green. Update `content/lore/canon-roadmap.md`'s Authored/Pending lists if you green. Update [`content/roadmap.md`](../../../content/roadmap.md) if you added a new
added a new bible file or closed out a pending thread. bible file or closed out a thread — its Spine list, or the Bill of Materials line
you just satisfied.
**Respect its rule: never author anything that is not in the Bill of Materials.**
An idea that arrives during authoring goes to that doc's Backlog, not into the
world.
## Reference files ## Reference files

View File

@@ -33,13 +33,13 @@
"id": 3, "id": 3,
"name": "new-storyline-file", "name": "new-storyline-file",
"prompt": "Start a new storyline about a roadside cult bleeding travelers to feed one of the Seven: who they are, and a rumor the player might hear. Make it its own file.", "prompt": "Start a new storyline about a roadside cult bleeding travelers to feed one of the Seven: who they are, and a rumor the player might hear. Make it its own file.",
"expected_output": "A new content/lore/*.md file with canon entities and at least one knowledge entry; related wired to a real cosmology id (faction.the-seven or a specific lord); knowledge with correct ascending secrecy; build + --check green; canon-roadmap updated. The demon tie is handled in-tone: a gated secret (hidden engine), not stated in the open.", "expected_output": "A new content/lore/*.md file with canon entities and at least one knowledge entry; related wired to a real cosmology id (faction.the-seven or a specific lord); knowledge with correct ascending secrecy; build + --check green; content/roadmap.md updated. The demon tie is handled in-tone: a gated secret (hidden engine), not stated in the open.",
"assertions": [ "assertions": [
"Authored a new content/lore/*.md file (its own file)", "Authored a new content/lore/*.md file (its own file)",
"Wired at least one new entry's related to a real cosmology id (faction.the-seven or a lord)", "Wired at least one new entry's related to a real cosmology id (faction.the-seven or a lord)",
"Includes at least one knowledge entry (rumor/fact/secret) with correct ascending secrecy", "Includes at least one knowledge entry (rumor/fact/secret) with correct ascending secrecy",
"python -m content_build --check exits 0 after the change", "python -m content_build --check exits 0 after the change",
"content/lore/canon-roadmap.md updated to reflect the new content", "content/roadmap.md updated to reflect the new content",
"The demonic connection is a gated secret, not open surface text" "The demonic connection is a gated secret, not open surface text"
], ],
"files": [] "files": []

View File

@@ -4,15 +4,21 @@ Cross-cutting authored writing, split by role in the data model (see the canon
log spec in [`/docs`](../docs)): log spec in [`/docs`](../docs)):
``` ```
/world Static, ID-referenced game content. Identical every playthrough. roadmap.md The content track — Spine · Bill of Materials · Backlog. START HERE.
/lore Authored Markdown bibles. THE SOURCE OF TRUTH; world/ + server/ are built from it.
/world Static, ID-referenced game content. Identical every playthrough. BUILT.
/locations The map — towns, dungeons, points of interest (by id) /locations The map — towns, dungeons, points of interest (by id)
/npcs Per-NPC persona + knowledge lists (charter §6) /npcs Per-NPC persona + knowledge lists (charter §6)
/quests Story skeletons and quest definitions (charter §17) /quests Story skeletons and quest definitions (charter §17)
/items Item definitions — gear, consumables, cursed items (§7) /items Item definitions — gear, consumables, cursed items (§7)
/server Spoiler bodies + personas. API-only; excluded from the client export. BUILT.
/origins Thin starting-state seeds. One per starting point. POC authors one. /origins Thin starting-state seeds. One per starting point. POC authors one.
/fallback Authored degraded-DM text for every AI surface (charter §13) /fallback Authored degraded-DM text for every AI surface (charter §13)
``` ```
**[`roadmap.md`](roadmap.md) governs what gets authored.** Its rule: *never author
anything that is not in the Bill of Materials.* Ideas that arrive go to its Backlog.
## The three layers ## The three layers
- **`world/`** is static content the origin and the canon log reference by stable - **`world/`** is static content the origin and the canon log reference by stable

View File

@@ -1,64 +1,11 @@
# Canon Roadmap # Moved
The world's answer to `docs/roadmap.md`: what is authored vs pending, and the The canon roadmap is now the **content roadmap**: [`content/roadmap.md`](../roadmap.md).
order the Margreave is being written. Source of truth is `content/lore/*.md`;
`content/world` + `content/server` are BUILT from it (`python -m content_build`).
## Authored (status: canon) It grew past canon — it holds the Spine, a Bill of Materials (items, prices,
quests, the map), and a Backlog. An items-and-prices table does not belong under
`lore/`. See the
[content-track design](../../docs/superpowers/specs/2026-07-12-content-track-design.md).
- **cosmology.md** — the overarching theme: the Warden (distant good god), the This pointer exists because older specs and plans reference the old path. It holds
Sent (his angels), the Seven (demonic host), and the two economies + no canon and emits nothing.
possession (`rule.the-pact`, `rule.blood-price`, `rule.possession`). The
backdrop every future piece of content reconciles against.
- **the-seven.md** — the seven demon kings, one `person.*` each: Kareth (Red
King), Vael (Quiet Knife), Morren (Grey Mother), Ghaul (the Yoke), Ishri (Open
Mouth), Nuun (Hollow Choir), Draeth (Crowned Worm).
- **FTH-axis callings** (folded into the cosmology, from the races/classes
spec): the Bonesetter channels the Warden, the **Bloodsworn** (resolves the
warlock's former `[CANON-TBD]` name) pacts one of the Seven. Applying `Bloodsworn` to calling
data and a Bloodsworn's patron choice are M4; any Luck effect is an M5/
Improviser reconcile.
- **mechanics.md** — hosts `rule.disposition-ladder` (the required-once gate
vocabulary), reparented out of the retired Duncarrow scaffolding.
- **specimen.md** — a synthetic `status: candidate` disposition-gate specimen
(validated by `--check`, emitted nowhere); the world-building skill's structure
example. Not game canon. The Duncarrow scaffolding (Crell chain, Mera Fenn) is
deleted.
## Lesson from the Duncarrow purge
Generated content under `content/world/` has a client-side consumer:
`client/scripts/content/content_db.gd` (loaded via `client/scripts/harness/npc_harness.gd`)
and its GUT tests in `client/tests/unit/test_content_db.gd`. Deleting generated
content — a whole namespace of topics/npcs/canon — is a **client change**, not
just a content change; check `client/` before purging.
## The seven-campaign saga — what it asks of content
The saga direction spec
([`docs/superpowers/specs/2026-07-12-character-reuse-seven-arc-design.md`](../../docs/superpowers/specs/2026-07-12-character-reuse-seven-arc-design.md))
authors **no content** and adds **no BOM line**. It asks two things of the content
track, both of which land inside work already sequenced:
- **`tier: 1..7` on the entry envelope**, validated by the build tool — added at the
moment the `item` and `quest` namespaces land (already an M7/M8 prerequisite in the
content-track design). Schema, not content.
- **When the Bill of Materials is written, mark each line fixed vs variable.**
*Fixed substrate* (identical in every campaign): currency, the price table,
abilities, callings, the cosmology, the Seven, the disposition ladder.
*Per-campaign variable*: the town, its NPCs, their gated knowledge, the quest
chain, the king. This tells you which BOM lines town #2 reuses verbatim — useful
now, and the exact split v2 generation will need.
Pleasant accident: **the Greywater slice is already campaign 1** — tier 1, patron
Ghaul the Yoke. Nothing in the content-track design changes.
## Pending (not yet authored)
- Per-town knowledge that grounds the cosmology: possessed NPCs, blood-harvest
sites, shrine fronts — authored as gated `rumor`/`fact`/`secret`.
- The Barbarian ⚔ calling name (`[CANON-TBD]`); the Bloodsworn's patron-choice
detail (M4). Regions/towns of the Margreave beyond the scaffolding.
- **Backlog (saga, tiers 27):** the other six kings as campaign patrons; tiered
enemy families; the three story-shapes (cult cell → cult that owns a city → the
king). Parked, not lost.

177
content/roadmap.md Normal file
View File

@@ -0,0 +1,177 @@
# Content Roadmap
The world's answer to [`docs/roadmap.md`](../docs/roadmap.md). That doc sequences
**systems**; this one sequences **content** — lore, the economy, items, quests, the
map — and makes it **countable rather than open-ended**.
Source of truth is `content/lore/*.md`; `content/world` + `content/server` are
BUILT from it (`python3 -m content_build`). Realizes the
[content-track design](../docs/superpowers/specs/2026-07-12-content-track-design.md).
Three sections. **Only one of them is ever the work.**
1. **[Spine](#1-the-spine)** — the slice's world. Authored once; gates everything downstream.
2. **[Bill of Materials](#2-bill-of-materials)** — a countable checklist, per milestone. Numbers, not vibes.
3. **[Backlog](#3-backlog)** — everything the slice does not need. Named so it is not lost; parked so it is not looming.
> ## The rule
>
> **Never author anything that is not in the Bill of Materials.**
>
> An idea that arrives goes to the Backlog, and is then no longer carried. The
> Backlog is not a debt. It is where ideas go to be safe.
---
## 1. The Spine
**Greywater Docks and one dungeon** — the smallest thing that is a *game*. Every
system (creation, combat, dialogue, inventory, shop, quest log, map) is exercised
exactly once, against real content. The cosmology touching ground for the first
time.
- **The town — Greywater Docks.** A rot-black wharf where the river meets the sea
trade; everyone owes someone. **~6 NPCs:** Fenn (promoted from M2 test fixture to
real NPC), the harbourmaster, a fence, an innkeeper, a dock rough, one more.
- **The chain — "The Missing Ledger,"** extended from the existing hook. Town → road
→ dungeon → back. **Four objectives.**
- **The turn.** The debt Fenn cannot cover is a **blood** debt. The harbourmaster is
named in the ledger because he is the one *collecting*. The dungeon is the harvest
site.
- **The patron — Ghaul the Yoke.** Already, by name, the king of debt and bondage; a
ledger of what men owe is his liturgy. This makes the quest chain and the cosmology
**the same object** rather than two things bolted together, and gives
`rule.blood-price` its first concrete instance.
- **The dungeon** — the harvest site. One enemy family (the yoked) + a boss.
**Adopting Greywater, not replacing it.** Fenn is the NPC the aliveness question was
actually answered with (M2, live-proven). The slice's job is to make Greywater
*deep*, not *new*.
Breadth afterwards is **repetition of a proven shape**, not invention.
### Already authored (status: canon)
- **`lore/cosmology.md`** — the overarching theme: the Warden (distant good god), the
Sent (his angels), the Seven (demonic host), and the two economies + possession
(`rule.the-pact`, `rule.blood-price`, `rule.possession`). The backdrop every future
piece of content reconciles against.
- **`lore/the-seven.md`** — the seven demon kings, one `person.*` each: Kareth (Red
King), Vael (Quiet Knife), Morren (Grey Mother), Ghaul (the Yoke), Ishri (Open
Mouth), Nuun (Hollow Choir), Draeth (Crowned Worm).
- **FTH-axis callings** (folded into the cosmology, from the races/classes spec): the
Bonesetter channels the Warden, the **Bloodsworn** pacts one of the Seven.
- **`lore/mechanics.md`** — hosts `rule.disposition-ladder` (the required-once gate
vocabulary).
- **`lore/specimen.md`** — a synthetic `status: candidate` disposition-gate specimen
(validated by `--check`, emitted nowhere); the world-building skill's structure
example. **Not game canon.**
### Still to author for the slice
Greywater itself — the town, its ~6 NPCs, the ledger chain's four objectives, and
Ghaul's harvest site — as `content/lore/greywater.md`. The hand-written JSON under
`content/world/{locations,quests,npcs,items}` gets **authored upward** into that
bible, and `python3 -m content_build` emits `world/` from it.
Per-town knowledge that grounds the cosmology (possessed NPCs, blood-harvest sites,
shrine fronts) is authored as gated `rumor`/`fact`/`secret`.
---
## 2. Bill of Materials
Countable. This is the anti-overwhelm device.
The **Fixed/Variable** column is the [seven-campaign
saga](../docs/superpowers/specs/2026-07-12-character-reuse-seven-arc-design.md)'s only
ask of this table. **Fixed substrate** is identical in every campaign of every saga —
authored once, reused verbatim. **Variable** is per-campaign: the part a second town
would have to re-author, and the part v2 generation would produce. The column costs
nothing and tells you exactly what town #2 does *not* pay for.
| Milestone | Content it consumes | Count | Fixed / Variable |
|---|---|---|---|
| **M4** creation | Calling blurbs; the Bloodsworn's patron choice | ~2 | **Fixed** |
| **M4** creation | Origins (they reference world ids) | ~2 | **Variable** |
| **M5** combat | Abilities for the 3 POC classes | ~10 | **Fixed** |
| **M5** combat | 1 enemy family (4 units) + boss — **tier 1** | ~5 | **Variable** (per tier) |
| **M6** dialogue | 6 NPCs — persona + `knowledge[]` + gated topics (§6) | ~6 | **Variable** |
| **M7** inventory | 6 weapons, 4 armour, 3 consumables, **1 cursed item** (+STR / LCK — §7 says day-one) | ~14 | **Fixed** |
| **M8** world | The **price table in copper** | ~1 | **Fixed** |
| **M8** world | 3 map locations + the road; shop stock; the quest chain | ~7 | **Variable** |
| **M9** flavour | Authored fallback per AI surface (§13); shrine + Luck-drift events; humiliation seeds | ~10 | **Fixed** |
**≈57 discrete authored pieces for a complete, playable game.** An estimate, and
likely optimistic — but an estimate with an end, which is the entire point.
Roughly **37 fixed / 20 variable**: a second town costs the ~20, not the ~57.
Explicitly **not** in the slice: rings, amulets, trinkets. A second town. The other
six kings and their cults. All parked in the Backlog.
### The economy is two systems (§18)
- **The loop is code** (§2: state) — purse, buy/sell, the ~40% fence rate, gritty
disabled-CTA reasons. Sequenced as M8's *Shop economy*.
- **The numbers are content** — what a shortsword costs, a night at the inn, an ale,
the quest's purse. The **price table**, above.
**Currency model:**
```
1 gold = 100 silver = 10,000 copper
1 silver = 100 copper
```
**Gold is scary.** A peasant's whole life is copper, a mercenary's fee is silver, and
a gold coin is a plot point. The party counting coppers for an inn bed is §3 grit,
and Brannoc has an opinion about it.
**This is a change, not a new thing — and it has a client consumer. It lands as its
own small item before M7**, cheapest now while `content/world/items/` holds exactly
two files:
- A `Currency` value type — **store everything in copper**, format only at the
display edge (`12g 40s 8c`).
- `coin.json` → real denominations; all prices re-denominated.
- The Main Window shell's command-bar purse (it currently shows a flat gold value).
*§2: state · depends on nothing · goal: money that means something.*
---
## 3. Backlog
Not a debt. Where ideas go to be safe.
- **Items:** rings, amulets, trinkets.
- **Places:** a second town. Regions of the Margreave beyond the slice.
- **The saga (tiers 27)** — from the [character-reuse
spec](../docs/superpowers/specs/2026-07-12-character-reuse-seven-arc-design.md): the
other six kings as campaign patrons; tiered enemy families (proximity to a king *is*
the power scale); the three story-shapes (cult cell → cult that owns a city → the
king himself).
- **The Barbarian ⚔ calling name** (`[CANON-TBD]`).
- **AI-generated worlds** (v2, charter §17). The saga spec guarantees the `Saga`
object is what will feed it. Nothing else about it is decided.
---
## Notes for whoever authors next
- Each BOM line is authored through the **`/world-building` skill** — it reconciles
against existing canon, writes the build tool's source format, and verifies the
build stays green.
- **The build tool needs two new namespaces: `item` and `quest`.** Its legal
namespaces today (`tools/content_build/model.py`) are `town`, `place`, `region`,
`faction`, `person`, `rule`, `rumor`, `fact`, `secret`, `npc` — so **locations are
already modeled** (`town`/`place`/`region`) and only items and quests fall outside
it. Adding those two (model, emit, resolve) is a prerequisite of the M7 and M8 BOM
lines. **Add `tier: 1..7` to the entry envelope at the same moment** — the saga
spec's only schema ask, free while the model is already open.
- **Moving or deleting generated content is a client change.** `content/world/**` has
a client consumer: `client/scripts/content/content_db.gd` (via
`client/scripts/harness/npc_harness.gd`) and its GUT tests in
`client/tests/unit/test_content_db.gd`. That is the Duncarrow lesson — check
`client/` before any content move.

View File

@@ -66,24 +66,30 @@ Each screen is recreated as a Godot 4.7 Control-node scene against the mockups (
-**Title screen** — new game / continue / load / settings; the entry point. Author it editor-first (ADR 0001). **⛨ saga:** a fourth entry path (*begin the next campaign of an existing saga*) lands later — don't build it, just don't hardcode the flow as `new game → creation → world` so it can't be added. *§2: n/a · depends on the Theme · goal: first impression, into the world.* -**Title screen** — new game / continue / load / settings; the entry point. Author it editor-first (ADR 0001). **⛨ saga:** a fourth entry path (*begin the next campaign of an existing saga*) lands later — don't build it, just don't hardcode the flow as `new game → creation → world` so it can't be added. *§2: n/a · depends on the Theme · goal: first impression, into the world.*
### M4 — Character creation ### M4 — Character creation
*Content it consumes → [BOM](../content/roadmap.md#2-bill-of-materials): calling blurbs + the Bloodsworn's patron choice (fixed); origins (variable). **~4 pieces.***
-**Character creation UI** — the mock's screen over our proven model: race + calling cards, six stats with **LCK hidden entirely** (§7), 3d6 floors, the **+3 additive-only spend-up** pool (§8, matches the `character-creation-stats` model), live origin blurb + nameplate. **Reconcile class names** here (§8 vs the mock's callings). Feeds new-game canon-log construction (already built). **⛨ saga:** `NewGame.construct` takes `creation` as a plain `Dictionary` — keep it that way. The creation *scene* produces that dict but must not become the only thing that can (a saga synthesizes it and skips the UI). Emit `race_id` + `calling_id` into it. *§2: state · depends on the creation model (M0) + Theme · goal: build a character.* -**Character creation UI** — the mock's screen over our proven model: race + calling cards, six stats with **LCK hidden entirely** (§7), 3d6 floors, the **+3 additive-only spend-up** pool (§8, matches the `character-creation-stats` model), live origin blurb + nameplate. **Reconcile class names** here (§8 vs the mock's callings). Feeds new-game canon-log construction (already built). **⛨ saga:** `NewGame.construct` takes `creation` as a plain `Dictionary` — keep it that way. The creation *scene* produces that dict but must not become the only thing that can (a saga synthesizes it and skips the UI). Emit `race_id` + `calling_id` into it. *§2: state · depends on the creation model (M0) + Theme · goal: build a character.*
### M5 — Tactical combat (gridless) ### M5 — Tactical combat (gridless)
*Content it consumes → [BOM](../content/roadmap.md#2-bill-of-materials): abilities for the 3 POC classes (fixed); 1 enemy family (4 units) + boss, **tier 1** (variable per tier). **~15 pieces.***
-**Combat turn manager + HUD** — the Combat HUD `Component` state machine as GDScript: initiative order, the action economy (Action/Bonus/Move), ability resolution, click-to-target, victory/defeat; tokens on the iso board as **flavor only, no movement grid** (§10). Seeded per encounter (§10). **Reconcile damage determinism** here (§7/§10 vs the mock's ranges). Combat flavor is async optional Narrator calls (reuses M1). **⛨ saga — the level curve is no longer open:** design it to a **ceiling of L20 across 7 tiers** (tier N ≈ levels 3N2 … 3N; exact bands tunable, the ceiling is not). **Enemy stat blocks carry `tier: 1..7`; there is no scaling multiplier, and there never will be** — a tier-6 world has *different monsters* (proximity to a king is the power scale), not a rat with 40× HP. Class abilities are planned to L20. The M5 content BOM (1 enemy family + boss) is **tier 1**. *§2: state (flavor text a thin AI layer) · depends on the pipeline for flavor · goal: real stakes.* -**Combat turn manager + HUD** — the Combat HUD `Component` state machine as GDScript: initiative order, the action economy (Action/Bonus/Move), ability resolution, click-to-target, victory/defeat; tokens on the iso board as **flavor only, no movement grid** (§10). Seeded per encounter (§10). **Reconcile damage determinism** here (§7/§10 vs the mock's ranges). Combat flavor is async optional Narrator calls (reuses M1). **⛨ saga — the level curve is no longer open:** design it to a **ceiling of L20 across 7 tiers** (tier N ≈ levels 3N2 … 3N; exact bands tunable, the ceiling is not). **Enemy stat blocks carry `tier: 1..7`; there is no scaling multiplier, and there never will be** — a tier-6 world has *different monsters* (proximity to a king is the power scale), not a rat with 40× HP. Class abilities are planned to L20. The M5 content BOM (1 enemy family + boss) is **tier 1**. *§2: state (flavor text a thin AI layer) · depends on the pipeline for flavor · goal: real stakes.*
### M6 — Dialogue screen ### M6 — Dialogue screen
*Content it consumes → [BOM](../content/roadmap.md#2-bill-of-materials): 6 NPCs — persona + `knowledge[]` + gated topics (§6), variable. **~6 pieces.***
-**Dialogue UI + reshaped Adjudicator** — wrap the *proven* NPC free-text loop (`/npc/speak`, M2) in the mock's conversation screen: NPC portrait, live disposition meter, the NPC's spoken line + DM narration beat, and the **hybrid** input (choice chips with skill/approach tags **plus** the free-text line, §15). The **Adjudicator** (`/dm/adjudicate`, strict JSON §12, one-retry) lands here as the interpreter for the free-text "describe your own action" escape hatch — most turns use buttons. *§2: both (text = NPC voice · state = validated moves/actions) · depends on the NPC role (M2) · goal: conversation inside the game's UI.* -**Dialogue UI + reshaped Adjudicator** — wrap the *proven* NPC free-text loop (`/npc/speak`, M2) in the mock's conversation screen: NPC portrait, live disposition meter, the NPC's spoken line + DM narration beat, and the **hybrid** input (choice chips with skill/approach tags **plus** the free-text line, §15). The **Adjudicator** (`/dm/adjudicate`, strict JSON §12, one-retry) lands here as the interpreter for the free-text "describe your own action" escape hatch — most turns use buttons. *§2: both (text = NPC voice · state = validated moves/actions) · depends on the NPC role (M2) · goal: conversation inside the game's UI.*
### M7 — Inventory & character sheet ### M7 — Inventory & character sheet
*Content it consumes → [BOM](../content/roadmap.md#2-bill-of-materials): 6 weapons, 4 armour, 3 consumables, **1 cursed item** (+STR / LCK — §7 says day-one). All fixed. **~14 pieces.** Prerequisite: the build tool gains `item` + `quest` namespaces (and `tier: 1..7`).*
-**Inventory & equipment** — the paper-doll (12 slots) + Satchel grid, category tabs, item detail, encumbrance, derived stats; item seed-data from the mock's `items()` map as `Resource`s. *§2: state · depends on the Theme + item model · goal: gear the player manages.* -**Inventory & equipment** — the paper-doll (12 slots) + Satchel grid, category tabs, item detail, encumbrance, derived stats; item seed-data from the mock's `items()` map as `Resource`s. *§2: state · depends on the Theme + item model · goal: gear the player manages.*
-**Character sheet** — attributes (modifier-forward, LCK still hidden), saving throws, the "in a fight" derived grid, skills, talents, afflictions/conditions, the DM's-notes bio. *§2: state (display) · depends on the stat model · goal: the character, legible.* -**Character sheet** — attributes (modifier-forward, LCK still hidden), saving throws, the "in a fight" derived grid, skills, talents, afflictions/conditions, the DM's-notes bio. *§2: state (display) · depends on the stat model · goal: the character, legible.*
### M8 — World systems ### M8 — World systems
*Content it consumes → [BOM](../content/roadmap.md#2-bill-of-materials): the **price table in copper** (fixed); 3 map locations + the road, shop stock, the quest chain (variable). **~8 pieces.** The **currency change lands before M7** — store everything in copper, format at the display edge; it has a client consumer (the shell's purse).*
-**World-map travel** — region map, location markers (settlement/dungeon/fog), roads + planned route, danger ratings, travel time, set-out. *§2: state · depends on the shell · goal: move between places.* -**World-map travel** — region map, location markers (settlement/dungeon/fog), roads + planned route, danger ratings, travel time, set-out. *§2: state · depends on the shell · goal: move between places.*
-**Shop economy** — buy/sell with a fence: purses, stock/owned, the ~40%-sell loop, gritty disabled-CTA reasons, merchant reaction lines. *§2: state (merchant reaction = a thin authored/AI layer) · depends on inventory · goal: an economy loop.* -**Shop economy** — buy/sell with a fence: purses, stock/owned, the ~40%-sell loop, gritty disabled-CTA reasons, merchant reaction lines. *§2: state (merchant reaction = a thin authored/AI layer) · depends on inventory · goal: an economy loop.*
-**Quest log** — active/completed/failed tabs, objectives checklists, rewards, tracked quest; reads the canon log's `active_quests` (§11). *§2: state · depends on the quest model · goal: track the story.* -**Quest log** — active/completed/failed tabs, objectives checklists, rewards, tracked quest; reads the canon log's `active_quests` (§11). *§2: state · depends on the quest model · goal: track the story.*
### M9 — Framing, AI-flavor & persistence ### M9 — Framing, AI-flavor & persistence
*Content it consumes → [BOM](../content/roadmap.md#2-bill-of-materials): authored fallback per AI surface (§13); shrine + Luck-drift events; humiliation seeds. All fixed. **~10 pieces.***
-**Save / load + pause / settings** — the pause overlay + data-driven settings; save/load over the canon log + game state (seeds preserved, §10). **⛨ saga — the save is two objects, not one:** a durable **`Saga`** (sheet, level, companions + approval, humiliations, deeds, `kings_slain`, `campaigns_completed`, signature item) and a per-campaign **`Campaign`** (`CanonLog` + `GameState` + world + seed). **Humiliations move to the `Saga`** and are *projected* into the canon log — today they live in the log and would die with the campaign. This is the §10 seed argument applied to persistence: cheap now, a rewrite once saves exist in the wild. *§2: state · depends on the systems existing · goal: persistence + framing.* -**Save / load + pause / settings** — the pause overlay + data-driven settings; save/load over the canon log + game state (seeds preserved, §10). **⛨ saga — the save is two objects, not one:** a durable **`Saga`** (sheet, level, companions + approval, humiliations, deeds, `kings_slain`, `campaigns_completed`, signature item) and a per-campaign **`Campaign`** (`CanonLog` + `GameState` + world + seed). **Humiliations move to the `Saga`** and are *projected* into the canon log — today they live in the log and would die with the campaign. This is the §10 seed argument applied to persistence: cheap now, a rewrite once saves exist in the wild. *§2: state · depends on the systems existing · goal: persistence + framing.*
-**Luck fully wired** — generation exists (Plan B); this adds **drift events** (real bed, shrine blessing, killing something praying), **one shrine**, **one cursed item** (+STR / LCK). Visible only in prose (§7). Gates the Improviser. *§2: state · depends on the item + event systems · goal: the signature system, live.* -**Luck fully wired** — generation exists (Plan B); this adds **drift events** (real bed, shrine blessing, killing something praying), **one shrine**, **one cursed item** (+STR / LCK). Visible only in prose (§7). Gates the Improviser. *§2: state · depends on the item + event systems · goal: the signature system, live.*
-**Improviser**`/dm/improvise`: minor off-script events, **§7-sandboxed by construction** — a validator that only applies whitelisted state changes (dignity, never progress; structurally incapable of ending a quest). Fires on Luck; hooks Cadwyn. *§2: both · depends on Luck being wired · goal: bad luck as a story, not a fine.* -**Improviser**`/dm/improvise`: minor off-script events, **§7-sandboxed by construction** — a validator that only applies whitelisted state changes (dignity, never progress; structurally incapable of ending a quest). Fires on Luck; hooks Cadwyn. *§2: both · depends on Luck being wired · goal: bad luck as a story, not a fine.*