Wave 1 of Phase 1 complete. Phaser 4 + React 19 + Vite 8 + TypeScript 6 scaffold builds (npm run build green); 15 Phase-1 deps installed at locked versions; 7 architectural-firewall directories ready under src/; repo-root /content/ + /assets/ trees ready; Vitest (happy-dom) + Playwright wired with passing sentinel; package.json scripts pre-declared for the entire Phase 1 plan-set so Wave 2 can run in parallel without colliding on package.json. 3 deviations auto-fixed (1 blocking, 2 missing-critical): 1. Built scaffold by hand because @phaserjs/create-game v1.3.2 is interactive-only — plan's documented fallback path was used. 2. build script wraps tsc -b before vite build so strict-TS gates every build (CLAUDE.md Code Style invariant). 3. Added *.tsbuildinfo to .gitignore (TS 6 incremental cache files). Wave 2 readiness: Plan 02 must use ESLint 9 flat-config format (eslint.config.js); legacy .eslintrc.* not supported. fake-indexeddb pre-installed for Plan 03 IDB tests. inkjs + inklecate installed but no .ink files compiled (Phase 2 PIPE-02 owns that).
21 KiB
Roadmap: The Last Garden
Overview
The Last Garden is a 7-Season browser narrative idle game that ships its entire authored arc at v1. The roadmap takes a vertical-slice approach inside an MVP shell: Phase 1 lays the retrofit-hostile foundations (versioned saves, content pipeline, AI provenance discipline, anti-FOMO doctrine, Season 7 end-state design) so that no later phase has to rework architecture. Phase 2 is the load-bearing vertical slice — Season 1 ("Soil") shipped end-to-end with Lura, real fragments, working offline progression, and a "begin gesture" cello bootstrap — which is structured so it could plausibly ship publicly as a free standalone prologue ahead of Seasons 2-7. Phase 3 layers the watercolor + cello aesthetic onto the working loop. Phases 4-7 deliver the remaining six Seasons as paired vertical slices, each introducing at most one new mechanic and completing one arc beat (Roots/cross-pollination → Canopy + Storm → Depth + Loom → Return + binary choice). Phase 8 is launch-readiness polish — UX affordances, accessibility, performance, and visual regression for the asset library — gated behind the full content arc landing intact. The structure carries three banner concerns forward at every phase: the 7-Season scope risk (defended by the standalone-Season-1 escape hatch and the one-mechanic-per-Season cap), the "story ends but the loop doesn't" pitfall (Season 7 end-state designed in Phase 1, finite Roothold ceiling enforced in Phase 4, credits/coda rest-state landed in Phase 7), and AI asset pipeline discipline (provenance + curation gate + locked north-star reference set landed in Phase 1 before any production-volume asset generation in Phase 5+).
Phases
Phase Numbering:
- Integer phases (1, 2, 3): Planned milestone work
- Decimal phases (2.1, 2.2): Urgent insertions (marked with INSERTED)
Decimal phases appear between their surrounding integers in numeric order.
- Phase 1: Foundations & Doctrine - Versioned saves, content/asset pipelines, anti-FOMO + Season 7 end-state docs, sim/render firewall — all retrofit-hostile decisions landed before any feature code
- Phase 2: Season 1 Vertical Slice (Soil) - Player can plant, wait, harvest fragments, meet Lura, and return to a "letter from the garden" — the loop and content pipeline proven end-to-end on real Season 1 content
- Phase 3: Watercolor & Cello Aesthetic - The working garden becomes the painted garden: watercolor post-process, hand-painted plants, solo cello + ambient layers, the Pale rendered as overexposed silence
- Phase 4: Season-Prestige Cycle & Season 2 (Roots) - Players experience their first die-off, Roothold persists across the reset with a finite ceiling, cross-pollination unlocks, and the Nameless Man arrives at the gate
- Phase 5: Seasons 3-4 (Canopy & Storm) - Canopy trees deliver place-memory vignettes, Memory Storms test the player's resilience, the Nameless Man's dialogue unravels and he vanishes mid-sentence
- Phase 6: Seasons 5-6 (Depth & Loom) - The Below opens beneath the garden, ecosystem planting introduces clustered yields, the Archivist appears in Season 6 and accepts a memory containing both joy and grief
- Phase 7: Season 7 (Return) & Final Choice - The long, redemptive late-game where memories reseed the world, the player makes the binary narrative choice, and "The garden persists." rests as a coda the player can return to indefinitely
- Phase 8: UX, Accessibility & Launch Polish - Multi-buy, audio sliders, keyboard navigation, color-redundant icons, tab-title bloom indicator, visual regression for the asset library, the Lura-not-numbers UX doctrine enforced
Phase Details
Phase 1: Foundations & Doctrine
Goal: Developer can ship Phase 2 without architectural rework — versioned saves, content/asset pipelines, sim/render firewall, anti-FOMO doctrine, and Season 7 end-state design are all in place before any user-facing feature code is written. Mode: mvp Depends on: Nothing (first phase) Requirements: CORE-01, CORE-04, CORE-05, CORE-06, CORE-07, CORE-08, CORE-09, CORE-10, PIPE-01, PIPE-03, PIPE-05, PIPE-06, AEST-08, AEST-09, STRY-09, UX-13 Success Criteria (what must be TRUE):
- Game scaffold loads in under 5 seconds in Chrome, Firefox, Safari, and Edge on a 25 Mbps connection (CORE-01) — proving the Phaser 4 + React 19 + Vite + TypeScript stack and bundle budget are correctly set up.
- A round-trip save test passes: a synthetic save written via IndexedDB (with localStorage fallback and
navigator.storage.persist()) can be exported as Base64, re-imported into a fresh browser profile, migrated through the registeredmigrate_vN_to_vN+1chain, and verified by checksum — Vitest covers every shipped migration and the last 3 pre-migration snapshots are retained. - CI fails the build if
src/sim/imports anything fromsrc/render/orsrc/ui/(ESLint boundary rule) and fails the build if any/content/**/*.{md,yaml,ink}file violates its Zod schema or any AI-generated asset is missing required provenance fields ({model_id, checkpoint_hash, prompt, seed, sampler, params}). - The repository contains a written
anti-FOMO doctrinedocument and a writtenSeason 7 end-statedesign document in.planning/, both reviewed and committed — the project has a canonical answer to "the story ends but the loop doesn't" before any economy code is written. - A locked 10-20 painting "north star" reference set is committed to the repo and a documented human curation gate exists in the asset pipeline; sample assets prove the gate refuses unreviewed material. Plans: 7 plans Plans:
- 01-01-scaffold-and-test-infra-PLAN.md — Bootstrap Phaser 4 official template, install Phase-1 deps, restructure src/ into 7 firewall directories, configure Vitest (happy-dom) + Playwright, pre-declare every package.json script downstream plans need ✓ 2026-05-09 (6 min) — see 01-01-scaffold-and-test-infra-SUMMARY.md
- 01-02-eslint-firewall-PLAN.md — Migrate to ESLint flat config + eslint-plugin-boundaries, declare 9 element types, enforce CORE-10 (sim cannot import render or ui) with a Vitest-tested deliberate-violation fixture
- 01-03-save-layer-PLAN.md — Save envelope {schemaVersion, payload, checksum} with CRC-32 over canonical JSON, idb-wrapped IndexedDB with last-3 snapshot retention, synthetic v0→v1 migration chain, navigator.storage.persist API, Base64 export/import with 50MB DoS cap, full round-trip test (CORE-04 through CORE-09)
- 01-04-content-pipeline-PLAN.md — Vite-native content pipeline using import.meta.glob, Zod schemas for Fragment + SeasonContent, demo fragment under /content/seasons/00-demo/, content/README.md documenting the convention, no-op compile:ink stub for Phase 2 (PIPE-01, STRY-09)
- 01-05-asset-provenance-PLAN.md — 30-line Node validator script walking /assets/ + Zod sidecar schema covering 6 required fields + optional schema_version, refused-sample fixture proves the gate, Vitest integration test, 10–20 hand-curated north-star reference images committed via human curation checkpoint (AEST-08, AEST-09, PIPE-03)
- 01-06-doctrine-docs-PLAN.md — Author .planning/anti-fomo-doctrine.md (consolidation per CONTEXT D-07) and .planning/season-7-end-state.md (principle-level per CONTEXT D-08), Vitest doc-lint test enforces structural integrity (PIPE-05, UX-13)
- 01-07-ci-workflow-PLAN.md — Minimum-viable .github/workflows/ci.yml running npm ci + npm run ci on push to main and PR; structurally enforces every Phase 1 success criterion on every commit going forward (PIPE-06)
Phase 2: Season 1 Vertical Slice (Soil)
Goal: Player can launch the game, plant a seed, watch it grow, harvest a memory fragment authored in real Season 1 content, meet Lura at the gate, leave the tab for hours, and return to a letter-from-the-garden describing what bloomed — the entire core loop and content pipeline proven on Season 1 with no aesthetic polish required. Mode: mvp Depends on: Phase 1 Requirements: CORE-02, CORE-03, CORE-11, GARD-01, GARD-02, GARD-03, GARD-04, MEMR-01, MEMR-02, MEMR-03, MEMR-04, MEMR-05, MEMR-06, STRY-01, STRY-06, STRY-07, STRY-10, AEST-07, UX-01, UX-02, UX-10, UX-11, PIPE-02, PIPE-07 Success Criteria (what must be TRUE):
- A new player sees a single hand-painted "Tend the garden / Begin" screen, presses it, the AudioContext resumes, and the painted garden reveals itself with no UI clutter — the A Dark Room rule is honored from frame one.
- Player can plant a seed into an unoccupied tile, watch it advance through sprout → mature → ready-to-harvest growth states (advancing correctly from saved state across browser refresh), harvest it for exactly one memory fragment authored in
/content/Markdown with frontmatter and a stable string ID, and read that fragment in full inside a React DOM Memory Journal where the text is selectable and copy-pasteable. - Player can compost an immature plant and receive a tonal beat acknowledging the choice to let go; the deterministic fragment selector never duplicates a fragment within a playthrough until the pool is exhausted, respects authored Season/story-state gating, and Lura appears at the garden gate with text-message-cadence dialogue authored in Ink and compiled to JSON.
- Player who closes the tab and returns up to 24 hours later finds the garden has progressed by elapsed real time (not
setIntervalticks), with the simulation refusing negative deltas and capping any single offline catch-up at 24 hours; the return screen is a letter from the garden (not a stat dump) describing what bloomed and what Lura said, and saves fire correctly onvisibilitychangeto hidden, onbeforeunload, and on Season transitions. - A Playwright e2e smoke test passes: it loads the game, dismisses the begin gate, plants a seed, fast-forwards growth, harvests a fragment, verifies the fragment text appears in the journal, refreshes the page, and verifies the harvested fragment persists. Story progression gates on tick count (not wall time), so manipulating the system clock cannot fast-forward through Lura's authored beats. Plans: TBD UI hint: yes
Phase 3: Watercolor & Cello Aesthetic
Goal: The working garden becomes the painted garden — every plant renders in watercolor-adjacent style on a Phaser 4 canvas with the post-process filter applied, the solo cello main theme plays through Howler.js with independent music/ambient/SFX buses that crossfade rather than hard-cut, and the player can toggle reduced motion to disable non-essential particles. Mode: mvp Depends on: Phase 2 Requirements: GARD-10, AEST-01, AEST-02, AEST-03, AEST-04, AEST-05, AEST-06, UX-05 Success Criteria (what must be TRUE):
- Player sees the garden rendered in a watercolor-adjacent visual style on a Phaser 4 canvas with the watercolor post-process filter active; every plant looks like a real-world species made slightly wrong (no D&D-style fictional flora), and the Pale renders as overexposed white silence — luminous, pearlescent, too bright — accompanied by a faint tinnitus-like high tone.
- Player hears a solo cello main theme on the music bus, ambient garden sounds (wind, birdsong, gate creak) on the ambient bus that thin and fade as the Unremembering's region draws closer, and per-plant SFX on the SFX bus — three independent buses, never hard-cutting, always crossfading.
- Player progresses through a Season transition (using Phase 2's loop) and observes the visual palette and audio bed crossfade together — golden/autumnal early-game shifting toward the next Season's tonal register — with no audible click or visible flash.
- Player who has
prefers-reduced-motionset in their OS sees the game respect it by default; the player can also toggle a reduced-motion option in settings that disables non-essential particles and animation while preserving the painted look. Plans: TBD UI hint: yes
Phase 4: Season-Prestige Cycle & Season 2 (Roots)
Goal: Player experiences their first die-off as the end of Season 1, watches Roothold persist across the reset toward a finite narrative-tied ceiling, unlocks cross-pollination as Season 2's single new mechanic, and meets the Nameless Man arriving at the garden gate — proving the Season state machine, save migration on real player saves, per-Season content lazy-loading, and the at-most-one-mechanic-per-Season scope-defense doctrine all work together. Mode: mvp Depends on: Phase 3 Requirements: SEAS-01, SEAS-02, SEAS-03, SEAS-04, SEAS-05, SEAS-06, GARD-05, GARD-07 Success Criteria (what must be TRUE):
- Player progresses through the Season 1 → Season 2 transition: a frost die-off wipes surface plantings, the visual palette and audio bed crossfade per Phase 3, and Roothold persists with a value that demonstrably moved toward (not past) the finite ceiling tied to the Season 7 end-state design from Phase 1.
- Player loads a save written under the Season 1 schema and watches it migrate cleanly into a Season-2-aware shape via the registered migration chain; the last 3 pre-migration snapshots are retained and the "restore previous save" option is reachable from settings.
- Player unlocks Season 2 plant types absent from Season 1 (each with distinct growth time, harvest yield, and visual identity) and successfully cross-pollinates two adjacent compatible plants to produce a hybrid seed with mixed memory traits — the one and only new mechanic Season 2 introduces.
- The Nameless Man appears at the gate during Season 2 with his own Ink-driven dialogue arc; only the current Season's content is in the runtime bundle (Seasons 3-7 are not in the initial chunk and load lazily on Season transition). Plans: TBD UI hint: yes
Phase 5: Seasons 3-4 (Canopy & Storm)
Goal: Player tends the garden through the canopy era and the storm era — slow, expensive tree plantings yield short interactive place-memory vignettes; periodic Memory Storms accelerate decay of unprotected plants and demand resilient species or windbreaks; the Nameless Man's dialogue progressively shortens and confuses across Seasons 2-4 and he vanishes mid-sentence in Season 4 with no fanfare. Mode: mvp Depends on: Phase 4 Requirements: GARD-06, GARD-09, MEMR-07, STRY-03 Success Criteria (what must be TRUE):
- Player can plant a tree in Season 3+ — slow and expensive — and when it matures, harvesting yields a place-memory vignette delivered as a short interactive scene the player walks through (not just a text block).
- Player encounters a Memory Storm in Season 4+ as a periodic event with visual + audio cues; unprotected plants decay faster, and the player can plant resilient species, build windbreaks, or time harvests around storms to mitigate the damage.
- Player witnesses the Nameless Man's full arc: his Season 2 introduction, his progressively shortening and confusing dialogue across Seasons 2-4, and his Season 4 vanishing mid-sentence — no cutscene, no fanfare, the narrative weight carried by his absence at the next gate visit.
- The Memory Storm event mechanic respects the "at most one new mechanic per Season" cap from Phase 4 (Storm is Season 4's one new mechanic; place-memory vignettes are Season 3's one new mechanic), validating that the scope-defense doctrine holds at the midpoint of the arc. Plans: TBD UI hint: yes
Phase 6: Seasons 5-6 (Depth & Loom)
Goal: Player descends into the Below in Season 5 — root structures grow into ancient memory layers, ecosystem planting introduces clustered-yield depth, content from a pre-Archivist civilization surfaces — and Season 6 shifts the primary loop to feeding the Loom; the Archivist appears, never gendered, and responds when the player feeds the Loom a memory containing both joy and grief. Mode: mvp Depends on: Phase 5 Requirements: GARD-08, SEAS-07, SEAS-08, STRY-04, STRY-05 Success Criteria (what must be TRUE):
- Player accesses the Below in Season 5+ and grows root structures into ancient memory layers, harvesting fragments that read as content from a pre-Archivist civilization (tonally distinct from surface-garden fragments).
- Player plants clusters of compatible species and observes ecosystem planting yield bonuses kick in — the Season 5 mechanic that rewards thinking in ecosystems rather than individual crops, the one and only new mechanic Season 5 introduces.
- In Season 6, the primary gameplay loop shifts to the Below: instead of harvesting fragments, the player feeds memories to the Loom; the Archivist appears, is never gendered (they/them) in any UI string or dialogue, speaks softly and reflectively, and asks the player a thematic question without forcing an answer.
- Player feeds the Loom a memory containing both joy and grief and observes the Archivist's mechanical and tonal response: the Loom holds the contradiction, ending the Unremembering's advance — the load-bearing Season 6 narrative beat that gates Season 7. Plans: TBD UI hint: yes
Phase 7: Season 7 (Return) & Final Choice
Goal: Player experiences the long, satisfying late-game of Season 7 where collected memories become seeds that automatically reconstitute the world, the Pale recedes, the Heartsoil expands beyond the garden walls, Lura's complete 7-Season arc resolves, the player makes the binary narrative choice and reads "The garden persists." — and the game transitions to a credits/coda rest state the player can return to indefinitely without grinding. Mode: mvp Depends on: Phase 6 Requirements: SEAS-09, SEAS-10, STRY-02, STRY-08 Success Criteria (what must be TRUE):
- Player who reaches Season 7 sees collected memories automatically reconstitute the world as seeds, the Pale recede, and the Heartsoil expand beyond the garden walls — a long, satisfying late-game pace, not a sprint to credits.
- Lura's dialogue spans all 7 Seasons with her complete arc resolved in Season 7; her dialogue across the entire game has reflected player progression in Ink-driven branches tied to Zustand variables (validating Phase 4-6's narrative-state plumbing on the longest arc in the game).
- The final scene presents the binary narrative choice ("They help us remember" / "They help us grow"); both endings display the line "The garden persists." and both are tonally complete; neither unlocks alternate post-credits content (the Keeper, having no name, no backstory, and no dialogue beyond this choice, projects onto the player throughout).
- After credits, the game enters a credits/coda rest state — not infinite prestige tiers — that the player can return to indefinitely without grinding; the finite Roothold ceiling from Phase 4 has held the line, and the game has ended the way A Dark Room and Universal Paperclips ended. Plans: TBD UI hint: yes
Phase 8: UX, Accessibility & Launch Polish
Goal: The complete arc that landed in Phases 2-7 becomes a launch-ready product — multi-buy and audio sliders for power affordances, keyboard navigation and color-redundant icons for accessibility, a tab-title bloom for backgrounded play, the "what Lura said yesterday" UX doctrine enforced over any "fragments per hour" temptation, and visual regression coverage for the asset library so future model migrations cannot drift the watercolor consistency. Mode: mvp Depends on: Phase 7 Requirements: UX-03, UX-04, UX-06, UX-07, UX-08, UX-09, UX-12, PIPE-04 Success Criteria (what must be TRUE):
- Player can buy plants and upgrades in multi-buy increments (×1 / ×10 / ×100 / Max) when meaningful for the current scaling, and can adjust separate Music, Ambient, and SFX volume sliders with a master mute keybind; settings persist across saves.
- Player can navigate every menu and game surface using only the keyboard (Tab, Enter, Escape, arrow keys) with a always-visible focus indicator; all UI text is selectable, copy-pasteable, and supports browser zoom up to 200% without breaking layout; color is never the sole carrier of information — icons, labels, or patterns provide a redundant channel for color-blind players.
- When the tab is backgrounded, the tab title and favicon update to reflect the backgrounded state (e.g., a small bloom appears when a fragment is ready), and returning-player UI affordances surface what Lura said yesterday — never fragments per hour or optimization metrics (mechanic-as-metaphor doctrine enforced in the final UX review).
- Visual regression testing covers the full asset library and would flag any style drift before a model migration is merged — the AI asset pipeline discipline established in Phase 1 has end-to-end CI coverage by launch. Plans: TBD UI hint: yes
Progress
Execution Order: Phases execute in numeric order: 1 → 2 → 3 → 4 → 5 → 6 → 7 → 8
| Phase | Plans Complete | Status | Completed |
|---|---|---|---|
| 1. Foundations & Doctrine | 1/7 | In Progress | - |
| 2. Season 1 Vertical Slice (Soil) | 0/TBD | Not started | - |
| 3. Watercolor & Cello Aesthetic | 0/TBD | Not started | - |
| 4. Season-Prestige Cycle & Season 2 (Roots) | 0/TBD | Not started | - |
| 5. Seasons 3-4 (Canopy & Storm) | 0/TBD | Not started | - |
| 6. Seasons 5-6 (Depth & Loom) | 0/TBD | Not started | - |
| 7. Season 7 (Return) & Final Choice | 0/TBD | Not started | - |
| 8. UX, Accessibility & Launch Polish | 0/TBD | Not started | - |