Render the board as SVG, laid out from the graph data

Adds public/boardRender.js: a layout algorithm that derives every space's
position purely from shared/board.js (column = longest-path distance from
Start, lane = branch offset that fans out at a choice space and re-centers
wherever branches rejoin), so it keeps working unmodified as the board data
grows — no hand-placed coordinates to maintain.

Renders spaces as styled SVG nodes (color/shape by type), connects them with
curved path lines, and animates player tokens between positions. Pending
choices glow and are clickable directly on the board, in addition to the
existing text buttons. Game view widens the card on desktop for the board
and scrolls horizontally on narrow viewports.

Also repicks the player color palette (server/index.js) to avoid the board's
own semantic colors (green/gold/red), after a token nearly disappeared into
the same-colored Start space during visual testing.

Verified with a headless-browser run (Playwright, off-screen — not a desktop
screenshot): two players through lobby -> live join update -> board -> a
fork choice, no console errors, reducer tests still green.
This commit is contained in:
2026-07-21 18:12:01 -07:00
parent d40bc09867
commit 8df4859696
4 changed files with 353 additions and 5 deletions
+3 -1
View File
@@ -29,7 +29,9 @@ fs.mkdirSync(DATA_DIR, { recursive: true });
db.initDb(path.join(DATA_DIR, 'lifegame.db'));
const DEFAULT_CONFIG = { minPlayers: 2, maxPlayers: 6, diceSides: 6, startingCash: 0 };
const PLAYER_COLORS = ['#e8a12a', '#3f8f5f', '#2f6f9f', '#c1452f', '#7a4fae', '#2f8f8f'];
// Deliberately avoids the board's own semantic colors (green=start,
// marigold=finish, red=choice) so a player's token never blends into a space.
const PLAYER_COLORS = ['#2f6f9f', '#7a4fae', '#2f8f8f', '#c15fa0', '#a6752c', '#5a6b8c'];
const AUTH_TIMEOUT_MS = 10_000;
const app = express();