The Greifarm entry restriction was still shared across both multiball slots. An unrelated upper-playfield ball could clear the entering ball's latch during its own record-89 scan, while a shallow aborted entry could retain a stale choice. Store the latch owner with the capture-time restriction, permit only that slot to clear it when leaving the deep capture zone, and migrate the owner when a held secondary ball becomes primary. Test Plan: - `just --justfile tdkpin-rs/justfile test` -- passed (151 game, 8 service tests) - `just --justfile tdkpin-rs/justfile clippy` -- passed - `just --justfile tdkpin-rs/justfile build-production` -- passed - `just --justfile tdkpin-rs/justfile web-build` -- passed - `cargo +nightly fmt --manifest-path tdkpin-rs/Cargo.toml --all -- --check` -- passed - `rumdl check --flavor commonmark tdkpin-rs/CHANGELOG.md tdkpin-rs/AGENTS.md` -- passed - `git diff --cached --check` -- passed
TDK Pinball Machine web build
Build and serve the browser version from this directory with:
just web-serve
The game is compiled for wasm32-unknown-unknown and loaded into a fixed
640x460 canvas centered on the black page by index.html. Browser settings and
a fallback copy of the high-score table are saved in localStorage; native
builds continue to use their normal per-user save file.
The page includes the official Macroquad browser loader locally. The WASM
bootstrap is local as well, so the page does not require inline or third-party
JavaScript. The web page must be served over HTTP rather than opened directly
from a file: URL.
For a strict Content Security Policy, allow script-src 'self' 'wasm-unsafe-eval' for the browser's WebAssembly compilation and
connect-src 'self' for the local WASM and optional high-score API requests.
When the same-origin /api/highscores endpoint is available, the browser loads
and submits the shared top-ten table there. The small Axum service and an nginx
proxy example are in highscore-server.