v0.4.1 - bug fixes. initial d12 rolls determine what player in which seat.

This commit is contained in:
Jesse
2026-08-13 15:28:53 -04:00
parent 49f8504b05
commit a7221dcf20
22 changed files with 736 additions and 237 deletions
+7 -3
View File
@@ -9,8 +9,8 @@
* - `execute` reads state and emits events; it never mutates either.
* - `reduce` is the only thing that mutates, folding events into state.
*
* That keeps `state = fold(events)` true by construction, which is what makes replay and restart
* recovery work. It also lets component 6 (legalActions) call these very same `check` functions,
* That keeps every INTENT-driven change reducible by construction. Replay and restart recovery run
* on the intents themselves (`protocol.md` §3), not on folding the log. It also lets component 6 (legalActions) call these very same `check` functions,
* so the two can never drift apart — see legal.ts.
*/
@@ -1380,7 +1380,11 @@ function findTimetableSlot(s: GameState, from: number): number | null {
}
// ---------------------------------------------------------------------------
// reduce — the ONLY mutator. state = fold(events).
// reduce — the only mutator on the INTENT path.
//
// `applyIntent` never touches state except through here, so everything a player does is reducible.
// The phase driver (`advance.ts`) does not: it mutates and then describes, so folding the whole log
// does NOT reconstruct a game. `protocol.md` §3 has the consequence — the intents are canonical.
// ---------------------------------------------------------------------------
export function reduce(s: GameState, e: GameEvent): void {