docs: canon log schema + origin seed design
Design spec for the §11 canon log, plus origin seeds as thin initial-state
overlays over a single static world. Three layers (world content / origin seed /
runtime canon log), the in/out boundary (numeric Luck never enters the AI
payload, §7), field-level schemas, new-game construction order, turn-to-turn
maintenance, and JSON storage validated on both client and api.
Folds content/npcs and content/quests under content/world/; adds
content/world/{locations,items} and content/origins. fallback/ kept outside
world/ (authored prose, not id-referenced).
Spec: docs/superpowers/specs/2026-07-09-canon-log-schema-design.md
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,15 +1,37 @@
|
||||
# /content — authored game data
|
||||
|
||||
Cross-cutting authored writing. Consumed by **both** sides: the client ships fallback text and quest/story data; the api reads NPC knowledge lists to build prompts. That shared ownership is why it sits at the repo root, not inside either folder.
|
||||
Cross-cutting authored writing, split by role in the data model (see the canon
|
||||
log spec in [`/docs`](../docs)):
|
||||
|
||||
```
|
||||
/quests Story skeletons and quest definitions (authored, not AI-generated — §17)
|
||||
/npcs Per-NPC knowledge lists — the entire content an NPC can draw on (§6)
|
||||
/fallback Authored degraded-DM text for every AI surface (§13)
|
||||
/world Static, ID-referenced game content. Identical every playthrough.
|
||||
/locations The map — towns, dungeons, points of interest (by id)
|
||||
/npcs Per-NPC persona + knowledge lists (charter §6)
|
||||
/quests Story skeletons and quest definitions (charter §17)
|
||||
/items Item definitions — gear, consumables, cursed items (§7)
|
||||
/origins Thin starting-state seeds. One per starting point. POC authors one.
|
||||
/fallback Authored degraded-DM text for every AI surface (charter §13)
|
||||
```
|
||||
|
||||
## The three layers
|
||||
|
||||
- **`world/`** is static content the origin and the canon log reference by stable
|
||||
string **id**. Authored once; the same for every play.
|
||||
- **`origins/`** are thin seeds — where the player starts, the situation, and
|
||||
disposition/quest/item/build seeds. Values, not maps. Increase replayability
|
||||
without multiplying authoring work.
|
||||
- **`fallback/`** is not world content — it is degraded-DM prose (§13), consumed
|
||||
when the API is down. It sits outside `world/` on purpose: nothing resolves an
|
||||
id against it.
|
||||
|
||||
At new-game, code constructs the runtime **canon log** from a chosen origin +
|
||||
world content + character creation. See [`/docs/canon-log.md`](../docs) (spec) —
|
||||
authored via the design under [`/docs/superpowers/specs`](../docs/superpowers/specs).
|
||||
|
||||
## Authoring notes
|
||||
|
||||
- **NPC knowledge lists are the whole design** (§6). They are the only thing stopping the blacksmith from revealing the twist. Real authoring work — budget for it.
|
||||
- **Fallback text is content, not error handling** (§13). Written in the DM's voice, lives beside the rest of the writing. Every AI-dependent surface needs one before it ships.
|
||||
- Story skeletons are authored for now. AI-generated skeletons are v2, out of POC scope (§17).
|
||||
- **NPC knowledge lists are the whole design** (§6). The only thing stopping the
|
||||
blacksmith from revealing the twist. Real authoring work — budget for it.
|
||||
- **Fallback text is content, not error handling** (§13). Every AI-dependent
|
||||
surface needs one before it ships.
|
||||
- Story skeletons are authored for now. AI-generated skeletons are v2 (§17).
|
||||
|
||||
26
content/origins/README.md
Normal file
26
content/origins/README.md
Normal file
@@ -0,0 +1,26 @@
|
||||
# /content/origins — starting-state seeds
|
||||
|
||||
Thin authored files, one per starting point. An origin is an **initial-state
|
||||
overlay** on the static shared world (`/content/world`): where the player begins,
|
||||
the opening situation, and seeds for dispositions, inventory, starting quest, and
|
||||
character-creation constraints. Values and id references — never maps or personas.
|
||||
|
||||
At new-game the player picks an origin; code constructs the runtime canon log
|
||||
from origin + world content + character creation. See the spec in
|
||||
[`/docs/canon-log.md`](../../docs) (design under
|
||||
[`/docs/superpowers/specs`](../../docs/superpowers/specs)).
|
||||
|
||||
## Scope (§17)
|
||||
|
||||
Schema supports **N** origins; the POC authors **one**. One world, one map, fixed
|
||||
NPCs — origins change only the player's starting point and situation. More
|
||||
replayability, flat authoring cost.
|
||||
|
||||
## Fields (summary)
|
||||
|
||||
`id` · `display_name` · `description` · `start_location_id` · `situation[]` ·
|
||||
`opening_facts[]` · `disposition_overrides{}` · `inventory_grants[]` ·
|
||||
`start_quest_id` · `build_constraints{}`
|
||||
|
||||
`humiliations` are never seeded — they are earned in play (§7/§9). Validated
|
||||
against `origin.schema.json`; every id must resolve in `/content/world`.
|
||||
16
content/world/README.md
Normal file
16
content/world/README.md
Normal file
@@ -0,0 +1,16 @@
|
||||
# /content/world — static, ID-referenced content
|
||||
|
||||
The shared world. Authored once, identical every playthrough. Everything here
|
||||
carries a stable string **id** that origins and the canon log reference. Never
|
||||
seed initial *state* here — that is an origin's job (`/content/origins`).
|
||||
|
||||
```
|
||||
/locations Towns, dungeons, points of interest. id → location
|
||||
/npcs Persona + knowledge lists (charter §6). id → npc
|
||||
/quests Story skeletons and quest definitions (charter §17). id → quest
|
||||
/items Gear, consumables, cursed items (charter §7). id → item
|
||||
```
|
||||
|
||||
New-game construction resolves every id an origin references (start location,
|
||||
start quest, granted items, seeded companions) against this content, and fails
|
||||
loudly if one is missing. Keep ids stable — a rename is a breaking change.
|
||||
9
content/world/items/README.md
Normal file
9
content/world/items/README.md
Normal file
@@ -0,0 +1,9 @@
|
||||
# /content/world/items
|
||||
|
||||
Item definitions — gear, consumables, cursed items — each with a stable **id**.
|
||||
An origin's `inventory_grants` resolves item ids here.
|
||||
|
||||
Cursed/blessed items move Luck (charter §7): *a cursed blade granting +4 STR and
|
||||
−5 LCK is the most interesting item in this game.* The item system supports the
|
||||
STR/LCK split on day one. Numeric effects live in game state; only narrative-worthy
|
||||
items surface as canon-log facts.
|
||||
8
content/world/locations/README.md
Normal file
8
content/world/locations/README.md
Normal file
@@ -0,0 +1,8 @@
|
||||
# /content/world/locations
|
||||
|
||||
The map — towns, dungeons, points of interest, each with a stable **id**. An
|
||||
origin's `start_location_id` resolves here; the canon log's `location` mirrors
|
||||
the current one (id + display name).
|
||||
|
||||
POC scope (§17): one town, one dungeon (three fights, one boss). One reusable
|
||||
world; origins vary only where the player begins within it.
|
||||
Reference in New Issue
Block a user