fuzzyworld

dm / files / plan.md

plan.md

Blame: the commit that last changed each line · file · history

efa9a3e4 2026-05-28 Pavel Safronov1# Cypher System (CSRD) Migration Plan
2
3## Background
4
4aedf3e4 2026-05-28 Pavel Safronov5The app migrated from D&D 5e to the Cypher System Reference Document (CSRD) — Monte Cook Games' open ruleset used in Numenera, The Strange, and others. The migration is complete. `SAVE_VERSION` is currently **3**.
efa9a3e4 2026-05-28 Pavel Safronov6
7Every phase that changes `gameState` shape must increment `SAVE_VERSION` in `public/index.html`. Old saves are automatically offered for export and discarded.
8
9---
10
11## Source material
12
13All content is available under the [Cypher System Open License (CSOL)](https://www.montecookgames.com/cypher-system-open-license/) — free for digital use.
14
15| Source | URL | Used for |
16| --- | --- | --- |
17| Cypher-System-JSON-DB | github.com/Jon-Davis/Cypher-System-JSON-DB | **Data arrays** — types (with pool values), descriptors, foci, abilities, cyphers. 1.74 MB JSON; too large to bundle directly, so we extract just the fields we need into compact inline JS arrays during development. |
18| cyphersrd.quest | cyphersrd.quest | **System prompt** — authoritative rules text for task resolution, damage track, effort, GM intrusions, advancement. We write a tight summary (~800 tokens) from this. |
19| Obsidian CSRD Markdown | github.com/Obsidian-TTRPG-Community/Cypher-SRD-Markdown | Cross-reference during development. |
20
21**Workflow for data extraction:** download CSRD.json from JSON-DB, run a small local script to pull the specific fields needed (type name + starting pools + cypher limit + starting abilities summary; descriptor name + stat bonus; focus name + one-line summary + tier 1 ability), and paste the result as inline JS arrays in `index.html`. No build step needed.
22
23---
24
25## Phase 1 — Character foundation
26
27The biggest structural change. D&D's Race + Class becomes Cypher's **Descriptor + Type + Focus** sentence: *"I am a Clever Adept who Talks to Machines."*
28
29### 1a — Data definitions
30
4aedf3e4 2026-05-28 Pavel Safronov31- [x] Replace `RACES` array with `DESCRIPTORS` (34 entries, each with pool bonus and starting skills)
32- [x] Replace `CLASSES` array with `TYPES` (4 entries: Warrior, Adept, Explorer, Speaker — each with starting pools, Cypher Limit, starting abilities, and starting skills)
33- [x] Add `FOCI` array (69 entries, each with settings tags, playstyle description, and Tier 1 ability)
efa9a3e4 2026-05-28 Pavel Safronov34
35### 1b — New `gameState.character` shape
36
37Replace current `{ name, race, class, level, hp, maxHp, xp, gold, inventory }` with:
38
39```js
40{
41 name, descriptor, type, focus,
42 tier, // 1–6
43 effort, // = tier
44 might: { pool, max, edge },
45 speed: { pool, max, edge },
46 intellect: { pool, max, edge },
47 xp,
48 damageTrack, // 'hale' | 'impaired' | 'debilitated'
49 recoveryUsed, // 0–4, resets each full rest
50 cypherLimit, // from type (usually 2)
51 cyphers, // [{ name, level, effect }]
52 skills, // [{ name, rank: 'trained'|'specialized'|'inability' }]
53 abilities, // [{ name, cost, description }] — from type + focus
54 equipment, // string[] (replaces inventory)
55 shins, // currency (or 'gold' for generic settings)
56}
57```
58
59- [x] Update `beginAdventure()` to build this shape from Type + Descriptor + Focus selections
60- [x] Bump `SAVE_VERSION` to 2
61
62### 1c — Creation screen
63
64- [x] Replace two-grid layout (Race + Class) with three-grid layout (Descriptor + Type + Focus)
3207a0e0 2026-05-28 Pavel Safronov65- [x] The sentence "I am a `___` `___` who `___`" assembles live as user picks each
efa9a3e4 2026-05-28 Pavel Safronov66- [x] Type cards show starting pool values and Cypher Limit, not HP
67- [x] Focus cards show a one-line flavour summary
68- [x] Descriptor cards show the key stat bonus it provides
69
70### 1d — Header title format
71
72- [x] Update `header-title` from `"Name — Race Class"` to `"Name — Descriptor Type who Focus"`
73
74---
75
76## Phase 2 — Core mechanics
77
78### 2a — New `UPDATE_TOOL` schema
79
80Replace current fields entirely:
81
3207a0e0 2026-05-28 Pavel Safronov82```text
efa9a3e4 2026-05-28 Pavel Safronov83might_damage // number — damage to Might pool
84speed_damage // number — damage to Speed pool
85intellect_damage // number — damage to Intellect pool
86might_restore // number — points restored to Might pool
87speed_restore // number — points restored to Speed pool
88intellect_restore // number — points restored to Intellect pool
89xp_gain // number
90shins_change // number
91cyphers_add // [{ name, level, effect }]
92cyphers_remove // string[] — names of used/lost cyphers
93abilities_add // [{ name, cost, description }]
94equipment_add // string[]
95equipment_remove // string[]
96skills_add // [{ name, rank }]
97tier_advance // boolean
98recovery_used // boolean — mark one recovery slot as spent
99reason // string
100```
101
102### 2b — New `applyStatUpdate()` logic
103
104- [x] Apply pool damage/restore, clamping to 0 and max
105- [x] Recalculate `damageTrack` after every pool change:
106 - Hale → one pool at 0 → Impaired (−1 step to all rolls)
107 - Impaired → two pools at 0 → Debilitated (can barely act)
108 - Debilitated → all pools at 0 → Dead (end screen)
109- [x] Enforce Cypher Limit: if `cyphers.length > cypherLimit`, warn player to use one
110- [x] Handle `tier_advance`: increment `tier`, recalculate `effort = tier`, show tier-up fanfare
1e438f26 2026-05-28 Pavel Safronov111- [x] Handle `recovery_used`: increment `recoveryUsed` (max 4; fourth resets all and marks 10-hour rest taken)
efa9a3e4 2026-05-28 Pavel Safronov112- [x] Replace level-up toast with Tier-up toast (text: "TIER [N]!")
113
114### 2c — System prompt rewrite ✅
115
116Complete replacement of `buildSystemPrompt`. Claude needs to understand:
117
118- **Character sentence** — what Descriptor, Type, and Focus each contribute
119- **Task difficulty** — 0–10 scale; target = difficulty × 3; player rolls d20
120- **Special roll results** — 1 = GM intrusion (free); 17 = minor effect; 18 = minor effect; 19 = major effect or +1 damage; 20 = major effect
121- **Effort** — costs 3 from a pool per level (minus Edge); reduces difficulty by 1 per level applied
122- **Assets** — each relevant asset reduces difficulty by 1 (max 2 from assets)
123- **Skills** — trained = −1 difficulty; specialized = −2 difficulty; inability = +1 difficulty
124- **Damage track** — Impaired penalty (−1 step = difficulty +1 to all rolls); Debilitated behavior
125- **GM Intrusions** — Claude should offer them occasionally; player accepts (gains 2 XP, gives 1 away) or rejects (spends 1 XP); if player has no XP they must accept
126- **Recovery rolls** — 1d6 + Tier; progression: 1 action → 10 min → 1 hour → 10 hours; after four the character must sleep to reset
127- **Cyphers** — found during play; Claude should introduce them narratively; remind player when at Cypher Limit; one-use
128- **XP flow** — earned via intrusions and discoveries; spent on advancement (4 per step) or short-term benefits (1 each: reroll, refuse intrusion, add +2 to any roll)
129- **Advancement steps** (any 4 to advance a tier): increase pool max by 4; add +1 Edge to a stat; train a skill; other improvement
130- **Stat tracking** — call `update_character` before narrative text, same as current
131
132---
133
134## Phase 3 — Sidebar UI redesign
135
136### 3a — Three pool bars
137
138- [x] Replace HP bar with three bars: Might, Speed, Intellect
139- [x] Each bar shows `current / max` and `Edge: N`
140- [x] Bar colour shifts: green (full) → amber (half) → red (low) — same as current HP logic
141- [x] Damage Track indicator below the bars: coloured badge — green "Hale" / amber "Impaired" / red "Debilitated"
142
143### 3b — XP & advancement panel
144
145- [x] Replace XP progress bar (which tracked D&D level thresholds) with a plain XP counter
146- [x] Tier shown as Roman numeral next to XP
eabebeea 2026-05-28 Pavel Safronov147- [x] Show advancement progress: 4 dot pips below XP/Tier row
4aedf3e4 2026-05-28 Pavel Safronov148- [x] "Spend 4 XP" button — disabled when XP < 4 or Tier 6; opens advancement modal (see Phase 5c); four steps advances the Tier and resets dots
efa9a3e4 2026-05-28 Pavel Safronov149
150### 3c — Cyphers panel
151
152- [x] New sidebar section "Cyphers" (replaces or extends Inventory)
153- [x] Each cypher shows name, level, effect summary
eabebeea 2026-05-28 Pavel Safronov154- [x] "Use" button per cypher — removes it and sends activation message to Claude
efa9a3e4 2026-05-28 Pavel Safronov155- [x] Cypher Limit displayed; section border turns orange when at limit
156- [x] Equipment (non-cypher items) stays as a separate Inventory list
157
158### 3d — Recovery roll button
159
eabebeea 2026-05-28 Pavel Safronov160- [x] Recovery section showing 4 slot pips (empty → filled as used)
161- [x] "Recovery Roll (1d6 + Tier)" button — rolls and adds to most depleted pool
162- [x] Marks one slot used per roll; when all 4 used button becomes "Full rest (reset slots)"
163- [x] Clicking reset button clears all slots
efa9a3e4 2026-05-28 Pavel Safronov164
165---
166
eabebeea 2026-05-28 Pavel Safronov167## Phase 4 — Setting / genre selector ✅
efa9a3e4 2026-05-28 Pavel Safronov168
169Cypher System is genre-neutral. Offer a setting choice at creation that adjusts tone, vocabulary, and available Foci.
170
eabebeea 2026-05-28 Pavel Safronov171- [x] Setting selector on creation screen: Fantasy / Numenera / Modern / Sci-Fi
172- [x] Each setting customises: currency name, special abilities vocabulary, DM tone paragraph
173- [x] System prompt includes setting context; currency label shown in sidebar
174- [ ] Curated subset of Foci per setting (deferred — all foci remain available for now)
efa9a3e4 2026-05-28 Pavel Safronov175
176---
177
4aedf3e4 2026-05-28 Pavel Safronov178## Phase 5 — Skill system ✅
1b8688e1 2026-05-28 Pavel Safronov179
4aedf3e4 2026-05-28 Pavel Safronov180The `skills` array in `gameState.character` is fully implemented: populated from Type and Descriptor starting skills, displayed in the sidebar with rank badges, managed via the advancement modal, and passed to Claude in the system prompt.
1b8688e1 2026-05-28 Pavel Safronov181
182### 5a — Display
183
86441da6 2026-05-28 Pavel Safronov184- [x] New "Skills" section in the sidebar (between Abilities and Equipment)
185- [x] Each skill shows name + rank badge: green "Trained" / gold "Specialized" / red "Inability"
186- [x] Empty state: "No skills yet"
1b8688e1 2026-05-28 Pavel Safronov187
188### 5b — Type and Descriptor starting skills
189
190Several Type Tier 1 abilities grant skill training ("Physical Skills", "Interaction Skills", "Danger Sense", etc.) but currently these are stored as narrative text in `abilities`, not as actual entries in `skills`. Fix by:
191
86441da6 2026-05-28 Pavel Safronov192- [x] Add a `startingSkills` field to each Type (parallel to `startingAbilities`)
193- [x] Add `startingSkills` field to each Descriptor for their trained skills
194- [x] Populate `character.skills` from both in `beginAdventure()` — overlapping trained skills promote to specialized
1b8688e1 2026-05-28 Pavel Safronov195
196### 5c — Skill advancement
197
198The XP advancement path ("train a skill") is currently only narrated. To make it mechanical:
199
7aa0370d 2026-05-28 Pavel Safronov200- [x] Add a "Train a Skill" option to the Spend 4 XP flow — prompts for skill name, adds it as trained
201- [x] Allow upgrading trained → specialized for another advancement step
202- [x] Specialization cap at 2 levels; inability cannot be trained away (only reduced to trained via advancement)
203- [x] Full advancement modal: pool +4, edge +1, train skill, specialize skill, other improvement
1b8688e1 2026-05-28 Pavel Safronov204
205### 5d — Skill lookup in task resolution
206
207When a player's message mentions an action, Claude already references skills in its narration. Future enhancement:
208
86441da6 2026-05-28 Pavel Safronov209- [x] Pass `character.skills` in the system prompt so Claude can cite which skills apply to a given roll
1b8688e1 2026-05-28 Pavel Safronov210- [ ] Expose "I am trained in X" as a quick action or structured input so the player can assert relevant skills before rolling
211
212---
213
efa9a3e4 2026-05-28 Pavel Safronov214## Notes
215
216- Phases 1–2 land together (one `SAVE_VERSION` bump to 2) — they're too intertwined to separate safely
217- Phase 3 can ship independently after Phase 2 (UI only, no `gameState` shape change)
218- Phase 4 is cosmetic and can go in any order
86441da6 2026-05-28 Pavel Safronov219- Phase 5a/5b/5d landed together with `SAVE_VERSION` bump to 3
12d22f8f 2026-05-28 Pavel Safronov220- The CSRD is available at [cyphersrd.quest](https://cyphersrd.quest) for rules reference