clay-borg/history/260731-game-kernel-research.md

3.7 KiB

2026-07-31 — game-kernel research trail (CB-RES-0001, T03)

How the survey was actually conducted, per InnerLoop §Step 2. Session: custodian on claude-fable-5.

Sources and queries

  1. WebSearch boardgame.io maintained status 2026 alternative open source board game engine framework → Snyk maintenance page (key fact: Inactive, v0.50.2, last publish ~4 years ago), GitHub issue #1150 ("What's the state of the project?"), Vassal as the named alternative (module player for humans, no programmable rules kernel — not pursued as a kernel candidate).
  2. WebFetch github.com/boardgameio/boardgame.io → 12.4k stars, 830 forks, 1,894 commits; feature list (phases, log/time-travel, multiplayer sync).
  3. WebFetch boardgame.io/documentation/#/dead end: docsify SPA, no content server-side. Architecture facts were instead verified from the installed package source (node_modules/boardgame.io) during harness construction (Redux + Immer pipeline, plugins incl. seeded random, playerView/STRIP_SECRET, activePlayers stages).
  4. WebSearch Rune games SDK deterministic logic.js … → developers.rune.ai docs: deterministic-JS enforcement (patched Math.random, static checks), predict-rollback sync model.
  5. WebFetch api.tabletopsimulator.com → Global vs Object scripts, Lua state persisted as strings in save JSON; deeper pages not fetched — remaining TTS characterization (no move validation, hand zones, no replay) is prior knowledge, marked cited in the survey.
  6. Event-sourcing and bevy_ecs performance figures are cited/estimated from general engineering knowledge (cqrs-es aggregate pattern, EventStoreDB append throughput class, Bevy's published bench claims) — not fetched this session. Flagged as directional in the survey; parity-cap rule applies.

Harness (measured baseline)

research/CB-RES-0001-harness/boardgame-io/bench.js — boardgame.io 0.50.2, headless Client, synthetic 3-player GROUND-shaped workload (relationship map, hands, commit list, resolve step), seeded, SHA-256 state hash.

Dead ends and fixes:

  • v1 harness used turn.stages + setActivePlayers events to model the commit/reveal windows faithfully. The client rejected the moves ("disallowed move/event") — stage gating plus client-sent events needs more setup than the bench warrants. Rewrote with flat top-level moves and activePlayers: {all: Stage.NULL}. Fidelity cost: stage-machinery overhead is not measured; the reducer/log pipeline (the thing we benchmark) is. Noted in the survey's risk paragraph.
    • Side-effect: the v1 "8.4 s for 100k moves" figure was garbage — moves were being rejected, so it measured no-ops. Discarded.
  • 100k-move run did not finish in 300 s and was killed. Reran at 5k/10k/20k, which exposed the real story: throughput halves as history doubles (1,930 → 1,605 → 870 moves/s). The degradation is the finding; a single big-N number would have hidden it.
  • A stray broken edit left duplicate code in bench.js (syntax error); fixed before the measured runs. Measurements reported in the survey are from the clean file only.

Environment: Node v24.11.1, bnt-lap001 (WSL2), single process, no other load control — numbers are same-machine comparable per MetricsAndScenarios §3, not lab-grade.

What was deliberately not done

  • No local measurement of a Rust event-sourcing comparator (would harden the D3 ceiling row; candidate follow-up if the adversarial review demands it).
  • Vassal, Tabletopia, Phaser/Godot examined only far enough to exclude: none is a programmable authoritative rules kernel.
  • boardgame.io server-side master (no client subscription) not separately benchmarked; harness measures canonical client usage.