Commit Graph

6 Commits

Author SHA1 Message Date
bd49e118d5 feat(newgame): the seeded creation pipeline
construct() takes a seed, not a stat block. It rebuilds the RNG and rolls the
attributes itself, so it never trusts a number handed to it (§2) and the same seed
yields an identical character, hidden Luck included (§10). The whole character is
reproducible from four primitives: seed, race_id, calling_id, spend. The rng
parameter is dropped — the seed is now the only source of randomness.

The roll is 3d6 with a hard floor of 8. Straight 3d6 puts ~9% on a primary the +3
pool cannot rescue, and a character bad at the one thing he is FOR is not grit —
it is the fine §7 forbids, paid for twenty hours.

LCK is unspendable, not merely hidden: spending on it is a validation error.
GameState.stats becomes GameState.sheet.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QYa9u7Kdxv5gX4AnwWexy8
2026-07-12 20:43:51 -05:00
bb5d176262 feat(state): CharacterSheet — store the inputs, derive the rest
Stores only what was rolled or chosen, plus current hp/mp (the only two numbers
that genuinely mutate). Everything else is a function, so no derived number can
drift from its inputs and M5's level curve is a function change, not a migration.

LCK has no row and no accessor here — §7 holds by construction.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QYa9u7Kdxv5gX4AnwWexy8
2026-07-12 20:21:45 -05:00
8a71671df7 feat(currency): purse_copper on GameState, with grant/take routing
One int holds all money. grant/take are the sole routing point — currency ids
go to the purse, everything else to inventory. Money is never an inventory row.

The 'coin' stand-in in the two unrelated inventory tests becomes
worn_shortsword; they were never about money.
2026-07-12 18:29:10 -05:00
2a372bff2f feat(currency): the Currency value type — copper, ratios, formatting
One integer, stored in copper. The ratios are rules and live in code; prices
are content and land in M8. format() suppresses empty denominations so being
broke reads as '47c', not '0g 0s 47c'.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QYa9u7Kdxv5gX4AnwWexy8
2026-07-12 18:26:22 -05:00
1d1ae37281 feat(client): GameState move targets — remove_item, reveal/gift tracking
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-10 12:34:33 -05:00
0a9742a984 feat(client): Luck (deterministic gen/drift/descriptor) + GameState store
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-09 14:24:59 -05:00