Sun Trap — Implementation Programme
Document status: Active plan
Scope The ordered, checkable programme that takes Sun Trap from design documents to a proven headless game. It coordinates work in this repository with the engine-owned
world-graphimplementation in SubZeroDev.GameEngine.
1. How to Use This Programme
This document is the implementation source of truth. The roadmap describes product phases, risks and open questions; this document defines dependency order, deliverables and completion evidence.
- Check a task only after its implementation and named verification have passed.
- Check a milestone only after every task in its Gate is complete.
- Record the pull request, commit or test that proves a cross-repository task when checking it. A statement that work exists is not evidence.
- Tasks marked GameEngine change the companion engine repository. Tasks marked Sun Trap change this repository.
- A milestone may be split into smaller pull requests, but no later milestone may depend on an unchecked gate.
- Balance values remain provisional until M9. Completing an earlier milestone proves mechanics, not fun or balance.
1.1 Verified Starting Point
- GameEngine: the shared engine MVP is implemented and its authoritative roadmap marks W1–W19 complete.
- GameEngine: the 2026-08-02 implementation baseline passed build, typecheck, lint and 677 tests across 57 test files (verified 2026-08-02).
- GameEngine: the
world-graphseam, tick order, actions, determinism rules, projection boundary, reason codes and events are specified. - Sun Trap: the vision, game design, client contract, MVP and field-level design are documented.
- GameEngine: a production
world-graphkind exists inv0.5.0. - GameEngine: the public
@the-running-dev/[email protected]package exposes the supported companion-game surface. - Sun Trap: this repository contains executable TypeScript game content or a client.
2. Architecture for Implementation
flowchart TD
Core["GameEngine core — implemented"]
Kind["GameEngine world-graph kind — engine-owned mechanics"]
Package["Versioned engine package and public exports"]
Campaign["Sun Trap campaign — maps, definitions, balance, strings"]
CLI["Sun Trap proving CLI — SessionStore client"]
Visual["Sun Trap visual client — projection only"]
Core --> Kind --> Package --> Campaign
Campaign --> CLI
Campaign --> Visual
2.1 Ownership Boundary
| Concern | Owner | Rule |
|---|---|---|
| Envelope, RNG, serialization, sessions, saves, replay | GameEngine core | Never reimplemented here |
| Tick pipeline, pathfinding, utility selection, queues, staff work | GameEngine world-graph kind | Reviewed engine code, not campaign data |
| Minimum state and content interfaces interpreted by the kind | GameEngine world-graph kind | One authoritative type definition |
| Maps, scenarios, definitions, strings and balance values | Sun Trap | Concrete campaign data satisfying engine types |
| Proving CLI and visual client | Sun Trap | Calls the session surface and renders projections only |
| Long-running balance search | Sun Trap | Never part of registry validation |
The engine must own the minimum TypeScript interfaces its kind reads. Sun Trap owns the values that satisfy those interfaces and may add authoring helpers, but it must not copy or fork the engine's mechanical types.
2.2 Dependency Rule
Sun Trap depends on a versioned GameEngine package. GameEngine never imports Sun Trap. During local development the package may be linked from the sibling checkout, but CI must resolve an immutable version or commit and must not depend on a developer's directory layout.
2.3 The Acceptance Thread
Every milestone advances one executable thread:
small beach map
→ place a drink stand and toilet
→ spawn a thirsty guest
→ choose a reachable drink stand
→ walk and queue
→ buy a drink and create litter
→ dispatch a cleaner
→ restore cleanliness
→ meet the revenue/cleanliness objective or fail financially
Features that do not help prove this thread stay outside the MVP.
3. Milestones
M0 — Contract and Programme Reconciliation
Outcome: implementation begins from current facts and one agreed boundary.
- Sun Trap: add this implementation programme and make it the checklist source of truth.
- Sun Trap: keep repository status text aligned with the implemented engine core,
shipped
world-graphkind and published package surface. - GameEngine: resolve the
tick_limit_exceededversustick_limit_reachedreason code inconsistency in the World Graph contract. GameEnginev0.5.0usestick_limit_reachedin both contract and runtime. - GameEngine: record that mechanical interfaces interpreted by
world-graphare engine-owned while concrete Sun Trap values remain game-owned. GameEnginev0.5.0exports the authoritativeWorldGraphCampaigninterfaces. - GameEngine: choose and document the companion-package delivery mechanism. W41, delivered by PR #108, chose an exact-version GitHub Packages dependency and consumer smoke test.
- Sun Trap: decide the MVP questions in §4 before their owning milestone begins; the settled decisions are recorded in the roadmap.
Gate
- Both repositories describe the same ownership boundary and use the same reason-code vocabulary.
- The package strategy is explicit enough for M1 to implement without another architectural decision.
M1 — Engine Consumer Boundary
Outcome: a companion repository can build against a supported, versioned GameEngine surface.
Evidence: GameEngine W41 was delivered by
PR #108. The resulting
public package now includes the completed world-graph surface at version 0.5.0.
- GameEngine: add a public package entry point.
- GameEngine: export the core construction, registry, session, projection and client types required by a game without exposing test fixtures as public API.
- GameEngine: define package
exports, declarations and build artefacts. - GameEngine: publish the package publicly through GitHub Packages at immutable exact versions.
- GameEngine: add a consumer smoke fixture that imports only public exports.
- GameEngine: make package build and consumer smoke verification required in CI.
- Sun Trap: add the immutable engine dependency only after the public surface exists.
Gate
- A clean consumer project installs, imports, typechecks and constructs the engine using only supported exports.
- CI does not rely on a sibling checkout or mutable branch.
M2 — World Graph Types and Kind Skeleton
Outcome: GameEngine recognizes a real world-graph kind and can create and validate a
minimal world.
Audited evidence: PR #116,
PR #119,
PR #125,
PR #134, and
PR #173. The
v0.5.0 engine job passed with 67 files and 959 tests, package inspection, and a consumer
smoke test.
- GameEngine: define authoritative map, entity, finance and world-state types.
- GameEngine: define the minimum campaign/content interfaces required by the MVP.
- GameEngine: define
WorldGraphViewand terminal outcome types. - GameEngine: implement the reason-code and event-name registries.
- GameEngine: implement campaign narrowing and pure Tier 1/Tier 2 validation.
- GameEngine: implement
initialState,outcomeand the productionworldGraphKindassembly. - GameEngine: register a synthetic one-map campaign fixture for engine tests only.
- GameEngine: reject malformed campaign content without throwing.
Gate
-
createGameproduces a deterministic tick-zero world through the real kind. - A broken map, missing reference and invalid tick cap each fail with the expected validation result.
- The engine's build, typecheck, lint and complete test suite pass.
M3 — Map Placement and Preview
Outcome: the player can inspect and place the MVP buildings through authoritative engine rules.
Audited evidence: PR #125 and PR #133.
- GameEngine: implement footprint rotation and entrance resolution.
- GameEngine: implement bounds, overlap, terrain, unlock and affordability checks.
- GameEngine: implement
buildwith immediate MVP construction. - GameEngine: derive building and queue ids from
nextEntityOrdinal. - GameEngine: add
previewActionas the real action path with discarded state. - GameEngine: add
previewActionto the session surface, text client coverage and MCP surface in the same change. - GameEngine: project the build catalogue, costs, unlock state and price ranges.
- GameEngine: test every placement reason code and preview/submit parity.
Gate
- The same parameters accepted by preview are accepted by submit from the same state.
- Preview never changes state or appends to the action log.
- No placement rule exists in a client.
M4 — Deterministic Ticks and Guest Decisions
Outcome: time advances and a guest develops a need and chooses a destination deterministically.
Audited evidence: PR #128, PR #131, and PR #134.
- GameEngine: implement the normative 20-step pipeline with unimplemented systems as explicit no-ops in their fixed positions.
- GameEngine: implement bounded
advance_ticksand tick incrementing. - GameEngine: implement deterministic guest spawning from tick streams.
- GameEngine: implement thirst and toilet need drift for the MVP archetype.
- GameEngine: implement integer utility scoring for reachable drink/toilet options.
- GameEngine: key guest draws by guest id and guest-owned draw count.
- GameEngine: expose guest intent and needs through the projection.
- GameEngine: add split-batch and event-sink-independence tests.
Gate
- One batch of
nticks reaches the same kind state as every tested split ofn. - Repeating the same seed and actions produces byte-identical serialized state.
- Changing player action batching does not change a guest's unrelated random draws.
M5 — Pathfinding, Movement, Queue and Service
Outcome: the guest reaches the drink stand, waits, pays and receives service.
Audited evidence: PR #125 and PR #131.
- GameEngine: implement integer-cost deterministic A* with fixed neighbour order.
- GameEngine: break all pathfinding ties by entity id and canonical position order.
- GameEngine: persist a committed route while keeping pathfinding caches out of state.
- GameEngine: implement movement, arrival and unreachable-target handling.
- GameEngine: implement stable queue insertion, capacity and abandonment.
- GameEngine: implement service timing and queue progression.
- GameEngine: implement
set_pricevalidation and integer-cent payment. - GameEngine: record batch-grain financial changes and per-guest service events.
Gate
- A guest spawns, selects, reaches, queues at and buys from a drink stand.
- An unreachable stand emits the diagnosable path-failure event and receives no sale.
- Equal-cost paths and equal-utility destinations resolve identically across runs.
M6 — Litter, Cleaner, Objectives and Failure
Outcome: the complete MVP simulation can be won and lost headlessly.
Audited evidence: PR #131,
PR #134,
PR #136, and
PR #138. On the
v0.5.0 tag the World Graph replay passed. The release-tag replay job failed only because
newer Stable Life fixtures were absent from the older baseline; PR #257
fixed that CI comparison mechanism.
- GameEngine: generate litter and reduce cleanliness after service.
- GameEngine: implement
hire_stafffor the cleaner role. - GameEngine: generate, prioritize and assign cleaning tasks deterministically.
- GameEngine: path the cleaner to litter and restore cleanliness.
- GameEngine: charge cleaner wages using the chosen MVP cadence.
- GameEngine: evaluate the revenue/cleanliness objective and failure conditions.
- GameEngine: publish objective and failure ids through terminal outcome.
- GameEngine: project finances, cleanliness, cleaner state and objective progress.
- GameEngine: add win, loss, save/load and replay fixtures.
Gate
- The synthetic engine fixture is playable to both the expected win and expected loss.
- Save/load mid-run reaches the same result as uninterrupted play.
- Removing every event sink changes no state or outcome.
Retained post-MVP engine gaps
These gaps do not block Sun Trap's documented MVP, but they prevent a claim that the complete game design is implemented: timed construction, a building lifecycle, alerts, complete cleanliness and wear, and spontaneous incident rolls. They remain engine follow-up work.
M7 — Sun Trap Package and MVP Campaign
Outcome: this repository contains the real campaign data, tests and build gates.
- Sun Trap: scaffold a Node 24 strict-TypeScript package with a committed lockfile.
- Sun Trap: add build, typecheck, lint and test scripts and corresponding CI.
- Sun Trap: consume GameEngine only through its public package surface.
- Sun Trap: author the small beach map, spawn, exit and terrain definitions.
- Sun Trap: author drink stand, toilet and waste-point definitions.
- Sun Trap: author the MVP guest archetype and cleaner role.
- Sun Trap: author prices, construction costs, wages and scenario thresholds as clearly marked provisional balance.
- Sun Trap: author localization strings in the deadpan narrative voice.
- Sun Trap: assemble the
sun-trap-mvpcampaign without duplicating campaign envelope identity inside content. - Sun Trap: add deliberately broken content fixtures for validation tests.
Gate
- A clean checkout installs, builds, typechecks, lints and tests without a sibling directory dependency.
- The real campaign loads through the engine registry with no Tier 1 errors.
- Every authored id and localization key passes validation.
M8 — Proving CLI and End-to-End Scenario
Outcome: a human can prove every MVP operation without a visual client.
- Sun Trap: implement the CLI as a
SessionStoreclient with no engine or kind imports below the session boundary. - Sun Trap: support campaign listing, new/resume, scene/view, strings, preview, action submission, save and load.
- Sun Trap: support the MVP commands for build, price, hire, advance and inspect.
- Sun Trap: display engine validation reasons rather than recomputing them.
- Sun Trap: add a scripted winning playthrough.
- Sun Trap: add a scripted losing playthrough.
- Sun Trap: capture replay fixtures for both paths.
- Sun Trap: prove CLI-driven state matches direct session-store submissions.
Gate
- A clean terminal session can start, win, save, load and replay the MVP scenario.
- The CLI never receives raw
GameStateor computes a gameplay decision. - Every session operation required by the spatial client has CLI coverage.
M9 — MVP Proof, Performance and Balance Baseline
Outcome: every MVP Definition-of-Done box is evidenced and the game is ready for the first visual client.
- Sun Trap: map every checkbox in the MVP to a named automated test or scripted acceptance run.
- Sun Trap: add deterministic scenarios for queue formation and clearing.
- Sun Trap: add batch-invariance coverage across representative tick splits.
- Sun Trap: establish tick-call performance baselines at 100, 500 and 1,000 guests.
- Sun Trap: implement the first balance harness for bankruptcy, dominant pricing, queue deadlock and infinite-profit loops.
- Sun Trap: playtest the vertical slice and record findings separately from engine defects.
- Sun Trap: revise provisional balance without changing published mechanical ids.
- Sun Trap: update the roadmap and MVP status from evidence.
Gate
- Every MVP Definition-of-Done checkbox is checked with evidence.
- No unresolved Tier 1 validation issue, determinism failure or replay regression remains.
- Performance is measured and acceptable for the MVP scale; no target is claimed without a recorded measurement.
M10 — First Visual Client
Outcome: the proven headless game becomes a playable visual product.
- Sun Trap: decide renderer technology from a working spike and recorded criteria.
- Sun Trap: decide grid versus isometric presentation.
- Sun Trap: implement map rendering, selection, build preview and placement errors.
- Sun Trap: implement guest, building and cleaner inspectors.
- Sun Trap: implement finances, objectives, alerts and initial overlays.
- Sun Trap: implement pause/speed controls as tick-request scheduling only.
- Sun Trap: meet the accessibility requirements in the client specification.
- Sun Trap: prove visual-client and CLI submissions serialize identically.
Gate
- Every client acceptance criterion is met.
- No client-side gameplay or validation rule exists.
- The MVP can be won and lost through the visual client.
4. MVP Decision Gates
These questions are deliberately not answered by implementation convenience. Check each one only after the decision is recorded in the game design or roadmap.
Before M2
- Fix the authored content-id convention.
- Decide how building entrances are authored.
- Decide whether MVP building rotation is
0only or all four contract rotations. - Confirm one tick's provisional simulated duration.
Before M3
- Confirm immediate construction for the MVP.
- Confirm that product inventory is omitted from the MVP.
- Confirm that utilities are omitted from the MVP.
Before M4
- Decide guest intent reconsideration cadence.
- Decide whether MVP guests know every available building.
- Decide queue-abandonment rules.
- Confirm groups remain out of scope.
Before M6
- Confirm automatic global cleaner dispatch for the MVP.
- Confirm shifts, staff needs and staff fatigue remain out of scope.
- Decide whether drink-stand service capacity is implicit or requires a service worker.
- Decide wage-charging cadence.
- Decide whether MVP bankruptcy is immediate or uses an escalation threshold.
Before M10
- Choose the renderer.
- Choose grid or isometric presentation.
- Choose snapshots or deltas for visual updates.
- Choose local engine execution or a local API process.
5. Immediate Next Work Packet
M0's cross-repository gate and the engine-owned portion of M1 are complete. The M2–M6
evidence audit is complete; GameEngine v0.5.0 is sufficient for the Sun Trap MVP. The next
packet is therefore:
- Pin
@the-running-dev/[email protected]and scaffold the Sun Trap package in M7. - Author and validate the real campaign through the supported package surface.
- After M7 is merged and pins the package, reconcile GameEngine's T4 documentation status.
This order keeps the first Sun Trap code dependent on the immutable published contract while preserving the programme's evidence standard for the engine work already delivered.