v0.4.8 — the Limits bound the whole district, the nine spots really are nine, and an action points at its square

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YQAJ4dND7enLj54eLyiF2C
This commit is contained in:
Jesse
2026-08-19 13:38:06 -04:00
co-authored by Claude Opus 5
parent 9f3b92d08e
commit 461c4d9bac
25 changed files with 3264 additions and 4524 deletions
+10
View File
@@ -356,6 +356,15 @@ export type Frame = {
cells: CellView[];
/** Which grid row is the Running Track — the spine the district hangs beneath. */
runningRow: number;
/**
* The columns the Limits signs stand in — the district's east and west edges, at EVERY row.
*
* Track may not be laid outside them (§2.1), so a player looking at open ground beyond a sign is
* looking at ground no card of his will ever go on. Two signs on one row could not say that; the
* board draws the boundary down the whole district instead. Carried on the Frame rather than read
* off the area for the usual reason: a remote client holds no `GameState`.
*/
limits: { west: number; east: number };
/**
* Moves left in this Local Operations turn, or null outside a switching turn.
*
@@ -1201,6 +1210,7 @@ export function snapshot(
handCount: (s.decks.hands.get(viewer) ?? []).length,
objective: objectiveOf(s, viewer),
runningRow: area.runningRow,
limits: { west: area.limitsWest.col, east: area.limitsEast.col },
movesLeft: s.clock.phase === 'localOps' && turnOf(s, viewer).option === 'switch' ? turnOf(s, viewer).movesRemaining : null,
moves: switchingMoves(s, viewer),
blocked: impediments(s, viewer),