Files
coorl-lost-cities/web
coolguyandClaude Opus 4.8 c8fa89dab9 Pause between rounds, summarise the match, and localise to Korean
Three-round match is now the default. The bigger fix is that round transitions
were invisible: the engine advances rounds atomically, so a round-ending move
flashed straight to the next round's board and its scores were never shown.

The client now holds at each round end (matchStep sets roundComplete instead of
rolling over; matchAdvanceRound continues on a button). While held, the finished
board stays up and an overlay shows that round's per-expedition breakdown and the
running match total -- no legal move, the rival waits, and nothing advances until
you choose to. The last round ends the match rather than pausing.

The end panel now summarises the whole match in one table -- each round's total
and the sum -- built from a new roundHistory on the match state. A single deal
still shows its per-expedition breakdown as before.

All UI text is Korean now: 승리 / 패배 / 무승부, the prompts, the menu, the score
plaques, both score tables. Removed the explanatory noise that was cluttering the
menu (the "seed shuffles the deck" and "match is decided on the total" blurbs, the
policy/provider line). Verified end to end in a browser: default is three rounds,
each round end pauses on its colour scores, and the final panel shows the
three-round summary.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XBQKgvBbxbheiTF1AVy1Sh
2026-07-15 18:11:19 +09:00
..
2026-07-14 19:49:03 +09:00
2026-07-14 19:49:03 +09:00
2026-07-14 19:49:03 +09:00
2026-07-14 19:49:03 +09:00
2026-07-14 19:49:03 +09:00
2026-07-14 19:49:03 +09:00
2026-07-14 19:49:03 +09:00

COOLRL Lost Cities Web

Browser-only Lost Cities client. The rules engine, observation builder, and PPO inference all run on the device; there is no application server.

The verified final JAX PPO policy is committed at public/models/jax-ppo.onnx (3.1 MB). Vite copies it to the static build, and the app resolves the asset relative to the deployed site so it works on GitHub Pages, GitLab Pages, or a normal web root. Its size and SHA-256 are recorded in public/models/jax-ppo.json.

Pushes to main build and publish the client through the repository's GitHub Pages and GitLab Pages workflows. Each workflow supplies the correct base URL for its host.

Seeded deals

Every game is dealt from a seed, shown in the menu and kept in the URL as ?seed=<seed>. Loading that URL — or typing the seed into the menu — replays the exact same deal, so a game can be shared, replayed, or reported with a bug. Seeds are arbitrary text; the deal is derived from a deterministic PRNG in src/game/random.ts and is independent of the Python shuffle bank.

The seed shuffles the deck and nothing else. The policy is deterministic: it always plays its highest-logit legal action, so the same deal and the same moves reproduce the same game.

Hints, undo, and review

HINT asks the same policy that drives the rival what it would play in your seat, and highlights the card, its destination, and the draw source (with the policy's confidence when the ONNX model is loaded).

Undo and redo work per action, not per turn: choosing a card, choosing its destination, and drawing are separate steps, and each is undone on its own. The rival's moves are steps too, so a finished game can be stepped through from the result screen (REVIEW GAME) all the way back to the deal. While undone moves are pending the rival is suspended; PLAY FROM HERE drops them and resumes play from the position on screen.

Setup

Install and run the checked-in final policy:

cd web
npm ci
npm run dev

Build the same static bundle used by a host:

npm run build
npm run preview

To replace the shipped policy, export a verified Orbax checkpoint from the repository root. The exporter writes both the ONNX file and its public metadata manifest:

uv run --with onnx scripts/export_jax_ppo_onnx.py \
  --checkpoint /path/to/checkpoint \
  --output web/public/models/jax-ppo.onnx

The policy tries WebGPU first and falls back to ONNX Runtime WebAssembly. If the model asset is absent, the UI remains playable using a simple local heuristic and reports that fallback in the header.

Checks

cd web
npm test
npm run build

The TypeScript engine follows src/lost_cities_jax/engine.py and its 96-action atomic action space. Cross-runtime fixtures can be regenerated with:

uv run python scripts/generate_web_parity_fixture.py