About the project
The task was to build a short but complete game with routing, limited visibility, events and replay. Domain logic had to remain independent of canvas and UI components.
Moon Courier Crisis separates domain simulation from presentation. SimulationEngine accepts commands and produces events and snapshots; a seeded RNG makes runs reproducible. React/Zustand manage mission UI while Phaser renders the current state as a projection.
What sets the implementation apart
Routes use Dijkstra over visible nodes, events change visibility, and Zod validates content before launch. Commands and snapshots allow mission outcomes to be tested without a browser; Phaser owns no game rules and can be rebuilt from state.
Application-code composition
Shares use Git application-file bytes at pinned revisions. Each file belongs to one subsystem under scripts/generate-stack-share.mjs rules; tests, assets, dependencies and generated files are excluded. Rounded to 0.1%. This describes code composition, not proficiency.
- Route control is designed for a mouse and keyboard. Mobile screens are responsive, but full touch-based routing is not claimed.
- The first available commit is a baseline of an already completed stage, so it does not establish when development began.
- No external integrations or server database: the mission runs in the browser.
Screenshots, diagrams and source evidence retain their original language; captions and descriptions are translated.
Architecture and diagrams
- React handles the interface; Phaser handles the canvas and game loop.
- Level selection, briefing, mission and result are separate states.
- After a defeat, replay returns to the briefing; a new shift starts through an explicit action.
Code map: files and dependencies
This map is tied to version b6b24e121536. The table lists the screen or API, related module and data.
| Feature | Screen / API | Module | Data / verification |
|---|---|---|---|
| Startup | Selection / briefing | src/ui/store/gameStore.ts; src/game/createGame.ts | level config; production browser QA |
| Route | Canvas | src/game/MapScene.ts; simulation/routing/confirmRouteDraft.ts | routeDraft / findWeightedRoute; actual route |
| Events | Radio panel | simulation/radio/createRadioJournal.ts | formatRadioEvent; game history |
| Simulation | Mission / result | simulation/createSimulationEngine.ts; clock/fixedStepClock.ts | courier and hub states; unit suite |
| Mobile view | Preflight / radio | React styles / src/ui | 390px; no-overflow QA |
Using the code map
- Before making a change, find the feature and trace its links to the API, state and storage.
- Check inputs, errors, repeated events and dependent workflows.
- After making a change, update the map and affected diagrams alongside the code.
- Run the related checks and link the new evidence to the source version.
Workflows and API
- Choose a level and read the briefing.
- Start a shift, select a courier and assign a route.
- Open the radio panel and follow a mission event.
- Wait for the result, select replay and start a new shift from the briefing.
Verification of the published version
- Original full suite: 464 unit tests, 20 E2E tests and one skipped test. Production build, asset checks and mobile QA were repeated after the CSS change.
- Production build / assets
- Desktop route and actual defeat/replay
- Mobile levels, briefing, radio; no overflow
- No verified GitHub CI run is available for this SHA; the listed evidence covers local checks and published-version scenarios. Historical CI links, where available, are labeled separately.
These checks apply to the listed version. Business metrics and model quality on an independent dataset were not measured.
Measurements
- 15 meaningful screenshots of the actual interface retained.
- Each screenshot includes its date, scenario and code revision.
- No separate backend process runs on the VPS: Nginx serves static files. Shared Nginx resources cannot fairly be attributed to a single site.
- 6 scenario repetitions measured; median 61.0 ms, maximum 1770 ms. Timing includes the browser and HTTPS; methodology and limitations are included.
Running and operating
The game runs in the browser. The server serves static files; there are no payment or AI integrations.
The production build, TypeScript checks and asset checks run outside the VPS. Nginx serves the resulting directory; there is no persistent backend.
Verify actual mission states without replacing the outcome through test hooks. Evidence includes a real defeat and replay. Screenshots from different releases are labeled individually; the mobile change affects layout rather than game mechanics.
Builds run outside the VPS; the server receives static files and versioned images. Secrets are kept separately. Logs rotate; changing log options requires recreating the container. No server-wide docker prune.
The code map links a screen or API to its module and data. A change needs those links checked, the map updated and the affected flows rerun: normal path, error, retry and reset. Diagrams can go stale, so their version is listed alongside them.
Rollback checked at 2026-09-07T00:59:40.423436+00:00: 20260907-verified → 20260907b → 20260907-verified. HTTPS, readiness and SHA were confirmed after each switch. This checks configuration and artifacts at one verified SHA; no reverse database migration was performed.
Stack
| React | Briefing, panels, hints and mission result. |
|---|---|
| Phaser | Canvas, game loop, scenes, routes and objects. |
| TypeScript / Vite | Game model, production build and asset checks. |
Materials and source code
Retained stage history: August 2026; development start is unknown. Demo published: 7 September 2026.
The evidence archive retains its original language.