docs(roadmap): currency landed; M4 is next
Both roadmaps still described the copper currency change as pending. It is merged. The marker moves to M4, M8's line now says what it still owes (the price table — nothing is priced yet), and a "Landed out of band" section records the two items that shipped outside a milestone: the currency value type, and the once-per-reply move cap its review turned up. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QYa9u7Kdxv5gX4AnwWexy8
This commit is contained in:
@@ -128,16 +128,22 @@ six kings and their cults. All parked in the Backlog.
|
||||
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:
|
||||
**The value type landed ✅** ahead of M7, as its own item
|
||||
([spec](../docs/superpowers/specs/2026-07-12-currency-copper-design.md), merged to
|
||||
`dev`): a `Currency` value type storing **everything in copper** and formatting only
|
||||
at the display edge; `coin.json` replaced by `copper`/`silver`/`gold`; the purse as a
|
||||
single `GameState.purse_copper` int; the shell's command bar reading `◈ 3s 47c`.
|
||||
|
||||
- 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).
|
||||
Money is **not** an inventory item. `give_item`/`accept_item` carry no quantity and
|
||||
`gifts_given` is a global one-shot, so a lone `copper` id would be givable *once, for
|
||||
one copper, per campaign*. The denominations are **move tokens** instead —
|
||||
`give_item(gold)` is +10,000c — and currency routes to the purse, never the
|
||||
`inventory` dict, so it cannot surface in an inventory grid by construction.
|
||||
|
||||
*§2: state · depends on nothing · goal: money that means something.*
|
||||
**What is left is the numbers.** The **price table** (above) is content and belongs to
|
||||
M8's BOM. Nothing is priced yet.
|
||||
|
||||
*§2: state · done · goal: money that means something.*
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -35,14 +35,22 @@ M0–M2 built the **engine** (the contract, the client, the server loop, bounded
|
||||
| **M0 — Foundations** ✅ | The contract and the client-side engine exist and are trustworthy. |
|
||||
| **M1 — Prove the server loop** ✅ | A real model sits behind `/dm/narrate` and the pipeline is reusable. |
|
||||
| **M2 — Prove aliveness** ✅ | **Does bounded AI dialogue feel alive?** — answered; bounded NPC dialogue + DM loop live-proven. |
|
||||
| **M3 — Visual foundation & shell** ◀ *here* | The `Theme` + the exploration HUD; every screen inherits the look and lives in the shell. |
|
||||
| **M4 — Character creation** | The player enters the world; the proven stat/Luck model gets its UI. |
|
||||
| **M3 — Visual foundation & shell** ✅ | The `Theme` + the exploration HUD; every screen inherits the look and lives in the shell. |
|
||||
| **M4 — Character creation** ◀ *here* | The player enters the world; the proven stat/Luck model gets its UI. |
|
||||
| **M5 — Tactical combat (gridless)** | Real stakes: the Combat HUD turn manager. |
|
||||
| **M6 — Dialogue screen** | The proven NPC free-text loop inside the mock's conversation UI. |
|
||||
| **M7 — Inventory & character sheet** | State the player can see and manage. |
|
||||
| **M8 — World systems** | World-map travel, a shop economy, the quest log. |
|
||||
| **M9 — Framing, AI-flavor & persistence** | Title/pause, save/load, and the Improviser/Banter/Luck-drift roles + fallback sweep. |
|
||||
|
||||
### Landed out of band
|
||||
|
||||
Not every item is a milestone. These shipped on their own because a later milestone
|
||||
would have been more expensive to build on top of the old shape.
|
||||
|
||||
- ✅ **Currency — copper with real denominations** ([spec](superpowers/specs/2026-07-12-currency-copper-design.md)). `1g = 100s = 10,000c`, **stored entirely in copper** as one `GameState.purse_copper` int, formatted only at the display edge (`◈ 3s 47c`). `coin.json` → `copper`/`silver`/`gold`. Money is **not** an inventory item: `give_item`/`accept_item` carry no quantity and `gifts_given` is a global one-shot, so a lone `copper` id would have been givable once, for one copper, per campaign — the denominations are **move tokens** instead (`give_item(gold)` = +10,000c), routed to the purse and never into `inventory`, so money cannot surface in an inventory grid by construction. Taken before M7 while `content/world/items/` held two files. **Prices remain M8's content BOM — nothing is priced yet.** *§2: state · goal: money that means something.*
|
||||
- ✅ **A move applies at most once per reply** — found by the review of the above. `TagExtractor` returns *every* tag occurrence and `MoveValidator` is a membership test, so a model repeating a tag N times picked an amount **in unary** (§2 breach: the AI choosing a number). Now deduped by (name, id) across a reply, and `adjust_disposition`'s `MAX_DELTA` caps the reply's **net** swing rather than each tag — it was per-tag, so three `+15`s moved standing by 45, the exact "wholesale swing" the constant forbids. *§2: state · goal: the bounded vocabulary stays bounded.*
|
||||
|
||||
---
|
||||
|
||||
### M0 — Foundations ✅
|
||||
@@ -83,7 +91,7 @@ Each screen is recreated as a Godot 4.7 Control-node scene against the mockups (
|
||||
- ○ **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
|
||||
*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).*
|
||||
*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 value type already landed** (see *Landed out of band*, above) — everything is stored in copper and formatted at the display edge, so the Shop economy inherits a real purse. What M8 still owes is the **numbers**: nothing is priced yet.*
|
||||
- ○ **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.*
|
||||
- ○ **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.*
|
||||
|
||||
Reference in New Issue
Block a user