Back to Devlog
    v0.9.19
    EngineJuly 18, 2026Release notes

    Making the Gates Tell the Truth

    A QA programme in thirteen items: exit codes that exit, a timing contract, discriminated unions, dependency injection, and five dangerous silent catches de-silenced.

    The Programme

    Thirteen numbered items, QA-WO1 through WO13, plus CI. The theme is not features. The theme is that a passing test was not evidence.

    WO11 — the gates tell the truth. runCli now exits non-zero on a top-level throw, with explicit CommandFailure/executeChecked, and an assets preflight gate for headless runs.

    WO1 / WO2 — a protocol smoke suite against a real GameServer on an ephemeral port driven by a socket client, including a chat→echo regression guard. Lobby lifecycle tests: create, join, full-reject, empty-destroy versus keep-alive grace, server-exit reset, match start and revert.

    WO12 — one clock. A single ServerTiming contract, with 7 subsystems moved off hardcoded tickRate: 125, and demos recording the effective snapshot cadence rather than the requested one.

    WO3 — handleReliable collapsed into handleDatagram, which kills the silent chat-drop class. A dead KillFeed widget was removed.

    WO4 / WO5 — wire-type de-duplication. MatchStateManager imports shared match types instead of a drifted hand-copy. ClientEntityKey owns the player_<id> format across ~20 sites. SnapshotEvent becomes a discriminated union with exhaustive switch dispatch at the client boundary — which is what kills "the silent-unrouted-event class".

    WO6 / WO8 — CI with a pre-commit hook and a biome count-ratchet gate. shared/ becomes downward-only: the net cluster and collision contract moved into it, the engine keeps re-export shims, and SharedCollisionWorld is pure structural math behind a SweepBackendAdapter. Determinism bit-identical.

    WO9 / WO10 / WO13 — a live/demo split in WeaponViewManager so demoplay stop cannot destroy the live viewmodel; ServiceLocator.dispose() now clears 9 stateful singletons; a GameFrameHook DI seam with SpectatorController fully game-free; a leveled log façade with rate-limited warnings and 5 dangerous silent catches de-silenced; hidden source maps and production console.log/debug stripping.

    The Numbers

    text
    122 files / 1415 tests, three consecutive clean runs
    determinism checksum 2768943778  (unchanged)
    biome baseline 932 errors / 586 warnings

    That biome number is wrong, and finding out why is the next release's story.

    Two pre-existing playtest bugs fixed: the lobby bounced back to gametype cards after a match, and the post-game winner model was a black silhouette until made self-lit.

    Also: a flaky test where GamePaths.test.ts leaked a browser-shaped global.window, and 34 hidden source maps relocated out of dist/ with 0 dangling `sourceMappingURL`.

    Known Unverified Items

    Browser and visual passes owed for WO9 in-game viewmodel after demoplay stop, demo POV weapon persistence when switching followed players mid-demo, WO13 scene reloads building fresh services, WO7 spectator and freefly through the GameFrameHook seam, the showcase fullbright intensity of 0.6, and the lobby rematch flow.