25 KiB
25 KiB
Requirements: The Last Garden
Defined: 2026-05-08 Core Value: Every idle mechanic must function as a metaphor that the player absorbs without being told. When economy and meaning conflict, meaning wins.
v1 Requirements
Requirements for initial release. Each maps to roadmap phases. All are user-centric, testable, atomic.
CORE — Engine, Simulation, Save Persistence
- CORE-01: Player loads the game in a modern browser (Chrome, Firefox, Safari, Edge — last 2 stable releases) and reaches a playable state in under 5 seconds on a 25 Mbps connection.
- CORE-02: Game runs a deterministic, fixed-timestep simulation that advances by elapsed real time (not
setIntervalticks), so a player who switches tabs or sleeps their device returns to a correctly-advanced garden. - CORE-03: Player who closes the game and returns finds the garden has progressed by the elapsed time (capped at 24 hours) — no progression resumes from a stale snapshot.
- CORE-04: Player's progress saves to IndexedDB (with localStorage fallback), surviving browser refresh, browser updates, and at least 30 days of inactivity on Chrome and Firefox.
- CORE-05: Game requests persistent storage via
navigator.storage.persist()on first save and surfaces the result respectfully if the browser declines. - CORE-06: Saves are versioned (
{schemaVersion, payload, checksum}) and the game refuses to load a save with a checksum mismatch, presenting the player with a recovery option. - CORE-07: Game runs a
migrate_vN_to_vN+1chain on load, so a save from any prior version of the game upgrades cleanly to the current shape (validated by Vitest tests for every shipped migration). - CORE-08: Game keeps the last 3 pre-migration save snapshots and offers the player a "restore previous save" option in settings.
- CORE-09: Player can export their save as a Base64 text blob via Settings → Export and import it back into the same or a fresh browser via Settings → Import.
- CORE-10: Game's simulation core (
src/sim/) imports nothing fromsrc/render/orsrc/ui/— enforced by ESLint boundary rules in CI. - CORE-11: Simulation refuses negative time deltas (system-clock cheat defense) and caps any single offline progression at 24 hours, regardless of wall-clock claim.
GARDEN — Planting, Growing, Harvesting
- GARD-01: Player can plant a seed from their seed inventory into an unoccupied tile of the garden.
- GARD-02: Each plant has a visible growth state (sprout → mature → ready-to-harvest) that updates from save data on load and advances over time.
- GARD-03: Player can harvest a mature plant to receive a memory fragment; harvesting empties the tile.
- GARD-04: Player can compost an immature or unwanted plant, returning a portion of resources and triggering a tonal beat (acknowledging the choice to let go).
- GARD-05: Player unlocks new plant types as they progress through Seasons, with each plant type having distinct growth time, harvest yield, and visual identity.
- GARD-06: Tree plantings (Season 3+) are slow and expensive but produce place-memory vignettes when harvested.
- GARD-07: Cross-pollination (Season 2+): adjacent compatible plants can produce hybrid seeds with mixed memory traits.
- GARD-08: Ecosystem planting (Season 5+): clusters of compatible species produce yield bonuses, encouraging the player to think in ecosystems rather than individual crops.
- GARD-09: Memory Storms (Season 4+): periodic events accelerate decay of unprotected plants, requiring the player to plant resilient species, build windbreaks, or time harvests around them.
- GARD-10: Player sees the garden as a Phaser 4 canvas with watercolor-styled, hand-painted-feeling plants (no generic fantasy flora).
MEMORY — Fragments, Journal, Selection
- MEMR-01: Each harvest yields exactly one memory fragment, drawn from the authored content pool gated by current Season and unlocked progression.
- MEMR-02: Memory fragments are authored in plain text (Markdown with frontmatter) in the project's
/content/tree and compiled per-Season at build time. - MEMR-03: Each fragment has a stable string ID (e.g.,
season3.canopy.lura_07.vignette) — never numeric — so re-ordering or re-authoring does not break references. - MEMR-04: Player can open a Memory Journal (React DOM panel) listing every fragment they have collected, organized by Season.
- MEMR-05: Player can read any collected fragment in full at any time, including selecting and copying its text (DOM-based, not canvas-rendered).
- MEMR-06: Fragments are selected by a deterministic selector that respects authored gating rules (Season requirement, story-state requirement, player-progression requirement) and avoids duplicates within a single playthrough until the pool is exhausted.
- MEMR-07: Place-memory vignettes (Season 3+) deliver a fragment as a short interactive scene the player can walk through, not just a text block.
STORY — Characters, Dialogue, Choice
- STRY-01: Lura (the audience-surrogate carpenter from a Remembered town) appears at the garden gate during Season 1 and reacts to early fragments with text-message-cadence dialogue authored in Ink.
- STRY-02: Lura's dialogue continues across all 7 Seasons, contextualizes major story beats, and reflects player progression in Ink-driven branches tied to Zustand variables.
- STRY-03: The Nameless Man appears in Season 2, his dialogue progressively shortens and confuses across Seasons 2-4, and he vanishes mid-sentence in Season 4 with no fanfare or cutscene.
- STRY-04: The Archivist appears in Season 6, never gendered (they/them), speaks softly and reflectively, and asks the player a thematic question without forcing an answer.
- STRY-05: The Archivist responds (mechanically and tonally) when the player feeds the Loom a memory containing both joy and grief — the Loom holds the contradiction, ending the Unremembering's advance.
- STRY-06: All authored dialogue uses Ink (
.inkfiles) compiled to JSON for runtime via inkjs. - STRY-07: The Keeper (player character) has no name, no backstory, and no dialogue beyond the final binary choice in Season 7.
- STRY-08: The final scene of Season 7 presents the player with a 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.
- STRY-09: Every player-visible string is externalized in
/content/(not hardcoded in TypeScript), so localization can be retrofitted in v2 without code refactor. - STRY-10: Story progression gates on tick count, not on wall time — players cannot fast-forward through authored beats by manipulating their system clock.
SEAS — Seasons, Prestige, Roothold
- SEAS-01: The game presents the seven Seasons (Soil, Roots, Canopy, Storm, Depth, Loom, Return) as an authored sequence; the player progresses through them in order.
- SEAS-02: Each Season ends with a die-off event (frost in Season 1, escalating tonally; pulled-edit-out-of-existence in Season 3) that wipes surface plantings and triggers a Season transition.
- SEAS-03: Roothold persists across every Season transition; it is the only number that can never decrease.
- SEAS-04: Roothold has a finite ceiling tied to the narrative argument; the curve flattens deliberately as the player approaches the end of the authored arc.
- SEAS-05: Each Season introduces at most one new mechanic (composting, cross-pollination, place-memory vignettes, Memory Storms, ecosystem planting, the Loom interface, Return-mode expansion) per the scope-defense doctrine.
- SEAS-06: Season transitions crossfade visual palette and audio bed (Howler.js), shifting from golden/autumnal (early) → deep green/storm (middle) → dawn/silver (late).
- SEAS-07: The Below (accessible Season 5+) lets the player grow root structures into ancient memory layers and deliver content from a pre-Archivist civilization.
- SEAS-08: Season 6 shifts the primary gameplay loop to the Below, where the player feeds memories to the Loom rather than harvesting fragments.
- SEAS-09: Season 7 ("Return") shifts to a long, satisfying late-game in which collected memories become seeds that automatically reconstitute the world; the Pale recedes; the Heartsoil expands beyond the garden walls.
- SEAS-10: When the player reaches the end of the authored arc, the game transitions to a credits/coda rest state — not infinite prestige tiers — that the player can return to indefinitely without grinding.
AEST — Visual & Audio Aesthetic
- AEST-01: The garden renders in a watercolor-adjacent visual style (hand-painted textures, plants that look like real species made slightly wrong) on a Phaser 4 canvas with a watercolor post-process filter.
- AEST-02: The Pale renders as overexposed white silence — luminous, pearlescent, too bright — with a faint tinnitus-like high tone in audio.
- AEST-03: The main musical theme is a solo cello, looped and crossfaded across Seasons via Howler.js.
- AEST-04: Ambient garden sounds (wind, birdsong, the creak of a gate) thin and fade as the Unremembering draws closer to the player's region.
- AEST-05: Audio crossfades, never hard-cuts, between Seasons; the cello and ambient layers are independent buses with separate volume controls.
- AEST-06: Color palette shifts deliberately by Season — golden/autumnal → deep green/storm → dawn/silver.
- AEST-07: The first screen of the game is a hand-painted "Tend the garden" / "Begin" gesture gate that satisfies the Web Audio user-gesture requirement and explicitly calls
AudioContext.resume(). - AEST-08: All AI-assisted assets carry persisted provenance metadata (
{model_id, checkpoint_hash, prompt, seed, sampler, params}) and are produced from a pinned model and a locked north-star reference set. - AEST-09: All shipped assets pass a mandatory human curation gate before integration; no asset reaches the production manifest unreviewed.
UX — Onboarding, Settings, Accessibility, Return
- UX-01: First-time player sees a single, painted "Begin" screen with no UI clutter; the garden reveals itself as the player interacts (A Dark Room rule).
- UX-02: Player who returns after time away receives a "while you were away" letter from the garden — written in voice, not a stat dump — describing what grew, what bloomed, what the wind brought.
- UX-03: Player can buy plants/upgrades in multi-buy increments (×1 / ×10 / ×100 / Max) when the option is meaningful for the current scaling.
- UX-04: Player can adjust separate Music, Ambient, and SFX volume sliders, with a master mute keybind; settings persist in saves.
- UX-05: Player can toggle a reduced-motion option (respects
prefers-reduced-motionsystem setting by default) that disables non-essential particles and animation. - UX-06: Player can navigate all menus by keyboard (Tab, Enter, Escape, arrow keys) and the focus indicator is always visible.
- UX-07: All UI text is selectable, copy-pasteable, and supports browser zoom up to 200% without breaking layout.
- UX-08: Color is never the sole carrier of information — icons, labels, or patterns provide a redundant channel for color-blind players.
- UX-09: Tab title and favicon update to reflect a backgrounded state (e.g., a small bloom appears when a fragment is ready).
- UX-10: Game saves state on
visibilitychangeto hidden, onbeforeunload, and on Season transitions; behavior is identical between "tab backgrounded" and "tab closed." - UX-11: Numbers display in human-readable formats (1.2K, 4.5M, 8.9B, scientific notation past notation thresholds).
- UX-12: Game surfaces what Lura said yesterday in returning-player UI affordances — never fragments per hour or optimization metrics (mechanic-as-metaphor doctrine).
- UX-13: No daily login bonuses, no streaks, no limited-time content, no nag notifications, no loss-aversion copy — anti-FOMO doctrine is enforced in every UX review.
PIPE — Content Build & Asset Pipelines
- PIPE-01: Project ships a build step that compiles
/content/**/*.{md,yaml,ink}into per-Season JSON chunks via Zod-validated schemas; build fails on any schema violation. - PIPE-02: Player loads only the content for their current Season at runtime (lazy chunk loading); future Seasons are not in the initial bundle.
- PIPE-03: Project ships an AI asset pipeline that records provenance per asset and refuses to integrate an asset missing required provenance fields.
- PIPE-04: Project ships visual regression testing for the asset library that flags style drift before any model migration is merged.
- PIPE-05: Project ships an
anti-FOMO doctrinedocument and aSeason 7 end-statedesign document in.planning/(ordocs/) before economy code is written. - PIPE-06: Project ships unit tests (Vitest) covering all save migrations and core economy formulas, run on every CI build.
- PIPE-07: Project ships an end-to-end smoke test (Playwright) that loads the game, plants a seed, harvests a fragment, and verifies persistence across a page reload.
v2 Requirements
Deferred to v1.x or v2.0. Tracked but not in current roadmap.
MONE — Cosmetic Monetization
- MONE-01: Player can purchase cosmetic-only items (planters, walls, gates, tool skins) via fixed-price catalog (no gacha, no random drops).
- MONE-02: Player can purchase a one-time "Keeper's Journal" premium upgrade unlocking annotation, organization, and personal-scrapbook features for collected fragments.
- MONE-03: Player can purchase Season acceleration that accelerates waiting — never skips story beats; UI explicitly labels the distinction.
- MONE-04: Game uses a server-authoritative entitlements backend (Cloudflare Worker + Stripe webhooks) — no localStorage entitlement claims.
- MONE-05: Cosmetic catalog items are permanent (never time-limited), priced transparently, and aesthetic-coherent with the garden setting.
PWA — Offline-First & Notifications
- PWA-01: Player can install the game as a PWA with a service worker manifest.
- PWA-02: Player can opt in to push notifications for Memory Storm events only — no daily/marketing/streak notifications, ever.
- PWA-03: Service worker caches static assets and serves them offline; saves continue to work without a network connection.
CLOU — Cloud Save Sync
- CLOU-01: Player can sign in (anonymous or email) and sync their save across devices via PocketBase or equivalent backend.
- CLOU-02: Cloud save uses the same versioned snapshot format as local save; conflict resolution prompts the player rather than silently overwriting.
CONT — Post-Launch Content Patches
- CONT-01: Project ships free additive content patches post-launch (Hollow Knight model) — additional place-memory vignettes, garden cosmetics, and ambient-only Seasons that fit between authored beats.
PORT — Steam & Mobile Native Ports
- PORT-01: Game ships on Steam (PC/Mac) using Phaser 4 + Electron or equivalent wrapper.
- PORT-02: Game ships on iOS and Android as native or hybrid wrappers, with on-device save sync via cloud.
LOC — Localization
- LOC-01: Game supports localization (EN baseline, additional languages added based on community demand) — externalized strings already shipped in v1, only translation pass needed.
MOD — Modding & Community Content
- MOD-01: Project documents a community-content authoring spec that lets community writers contribute fragments respecting tone and provenance discipline.
- MOD-02: Project ships a community-content gallery (off-canon, opt-in) where players can browse and load community-authored gardens.
SOC — Garden Visiting (cautious — must not break tone)
- SOC-01: Player can opt in to visiting other players' gardens in read-only mode, viewing what fragments they have collected (without spoilers for unvisited Seasons).
Out of Scope
Explicit exclusions. Documented to prevent scope creep. Anti-features tied to the project's thematic constraints — these are not deferred features, they are excluded by design.
| Feature | Reason |
|---|---|
| Gacha mechanics | Directly contradicts the game's thematic argument that complex things cannot be reduced to simple transactions. |
| Lootboxes | Same reason as gacha — undermines the story's monetization-as-meaning argument. |
| Narrative gating behind purchase | The story IS the product; story content is never paid. |
| Season skipping (vs. accelerating) | Players must never miss authored story beats; acceleration is allowed, skipping is forbidden. |
| Daily login bonuses | FOMO mechanic; violates cozy/contemplative tone. |
| Login streaks | FOMO mechanic; same reason. |
| Limited-time / time-limited content | FOMO mechanic; same reason. |
| Energy / stamina systems | Anti-cozy gating that interrupts contemplative play. |
| Rewarded ads | Anti-cozy; tonally incoherent with a contemplative grief-narrative. |
| Push notification spam | Memory Storm opt-in is the only allowed notification — no daily/marketing/streak/re-engagement nags. |
| Lore codex / encyclopedia entries | Players should always feel almost understanding; world-building emerges through fragments alone. |
| Generic fantasy flora | Plants must look like real-world species made slightly wrong; no D&D-style fictional flora. |
| Combat / boss fights | The Archivist is not a boss; there is no enemy. Combat would violate the entire thematic frame. |
| Multiplayer / leaderboards (v1) | Solitary, contemplative experience; reconsider for v2 only if it does not break tone. |
| Voiced dialogue (v1) | Tone is "a friend texting you while you're at work"; text fits the medium. Reconsider v2+ only if cello-and-silence soundscape benefits. |
| Always-online | Local-first save model; game must work offline. |
| Named/personality-rich Keeper | Keeper is a presence, not a personality; player projects onto the system. |
| Hint system / objective tracker | Discovery-driven progression (A Dark Room rule); explicit objectives violate the tone. |
| Time-skip purchases that bypass real-time | Real-time is the metaphor for memory; skip-time purchases would violate mechanic-as-metaphor doctrine. |
| Unity / Godot / non-web engines (v1) | Web-first per PROJECT.md and lineage of A Dark Room / Universal Paperclips; install friction kills the audience. |
| Generic cosmetic items | Cosmetics must reinforce, not dilute, the garden aesthetic. No generic skins. |
| Random-drop cosmetics | All cosmetics must be deterministic catalog purchases. No RNG monetization. |
| Mobile-style nag UX | Cozy audience expects respect; nag patterns will tank reviews. |
Traceability
Populated by gsd-roadmapper during roadmap creation on 2026-05-08.
| Requirement | Phase | Status |
|---|---|---|
| CORE-01 | Phase 1 — Foundations & Doctrine | Pending |
| CORE-02 | Phase 2 — Season 1 Vertical Slice (Soil) | Pending |
| CORE-03 | Phase 2 — Season 1 Vertical Slice (Soil) | Pending |
| CORE-04 | Phase 1 — Foundations & Doctrine | Pending |
| CORE-05 | Phase 1 — Foundations & Doctrine | Pending |
| CORE-06 | Phase 1 — Foundations & Doctrine | Pending |
| CORE-07 | Phase 1 — Foundations & Doctrine | Pending |
| CORE-08 | Phase 1 — Foundations & Doctrine | Pending |
| CORE-09 | Phase 1 — Foundations & Doctrine | Pending |
| CORE-10 | Phase 1 — Foundations & Doctrine | Pending |
| CORE-11 | Phase 2 — Season 1 Vertical Slice (Soil) | Pending |
| GARD-01 | Phase 2 — Season 1 Vertical Slice (Soil) | Pending |
| GARD-02 | Phase 2 — Season 1 Vertical Slice (Soil) | Pending |
| GARD-03 | Phase 2 — Season 1 Vertical Slice (Soil) | Pending |
| GARD-04 | Phase 2 — Season 1 Vertical Slice (Soil) | Pending |
| GARD-05 | Phase 4 — Season-Prestige Cycle & Season 2 (Roots) | Pending |
| GARD-06 | Phase 5 — Seasons 3-4 (Canopy & Storm) | Pending |
| GARD-07 | Phase 4 — Season-Prestige Cycle & Season 2 (Roots) | Pending |
| GARD-08 | Phase 6 — Seasons 5-6 (Depth & Loom) | Pending |
| GARD-09 | Phase 5 — Seasons 3-4 (Canopy & Storm) | Pending |
| GARD-10 | Phase 3 — Watercolor & Cello Aesthetic | Pending |
| MEMR-01 | Phase 2 — Season 1 Vertical Slice (Soil) | Pending |
| MEMR-02 | Phase 2 — Season 1 Vertical Slice (Soil) | Pending |
| MEMR-03 | Phase 2 — Season 1 Vertical Slice (Soil) | Pending |
| MEMR-04 | Phase 2 — Season 1 Vertical Slice (Soil) | Pending |
| MEMR-05 | Phase 2 — Season 1 Vertical Slice (Soil) | Pending |
| MEMR-06 | Phase 2 — Season 1 Vertical Slice (Soil) | Pending |
| MEMR-07 | Phase 5 — Seasons 3-4 (Canopy & Storm) | Pending |
| STRY-01 | Phase 2 — Season 1 Vertical Slice (Soil) | Pending |
| STRY-02 | Phase 7 — Season 7 (Return) & Final Choice | Pending |
| STRY-03 | Phase 5 — Seasons 3-4 (Canopy & Storm) | Pending |
| STRY-04 | Phase 6 — Seasons 5-6 (Depth & Loom) | Pending |
| STRY-05 | Phase 6 — Seasons 5-6 (Depth & Loom) | Pending |
| STRY-06 | Phase 2 — Season 1 Vertical Slice (Soil) | Pending |
| STRY-07 | Phase 2 — Season 1 Vertical Slice (Soil) | Pending |
| STRY-08 | Phase 7 — Season 7 (Return) & Final Choice | Pending |
| STRY-09 | Phase 1 — Foundations & Doctrine | Pending |
| STRY-10 | Phase 2 — Season 1 Vertical Slice (Soil) | Pending |
| SEAS-01 | Phase 4 — Season-Prestige Cycle & Season 2 (Roots) | Pending |
| SEAS-02 | Phase 4 — Season-Prestige Cycle & Season 2 (Roots) | Pending |
| SEAS-03 | Phase 4 — Season-Prestige Cycle & Season 2 (Roots) | Pending |
| SEAS-04 | Phase 4 — Season-Prestige Cycle & Season 2 (Roots) | Pending |
| SEAS-05 | Phase 4 — Season-Prestige Cycle & Season 2 (Roots) | Pending |
| SEAS-06 | Phase 4 — Season-Prestige Cycle & Season 2 (Roots) | Pending |
| SEAS-07 | Phase 6 — Seasons 5-6 (Depth & Loom) | Pending |
| SEAS-08 | Phase 6 — Seasons 5-6 (Depth & Loom) | Pending |
| SEAS-09 | Phase 7 — Season 7 (Return) & Final Choice | Pending |
| SEAS-10 | Phase 7 — Season 7 (Return) & Final Choice | Pending |
| AEST-01 | Phase 3 — Watercolor & Cello Aesthetic | Pending |
| AEST-02 | Phase 3 — Watercolor & Cello Aesthetic | Pending |
| AEST-03 | Phase 3 — Watercolor & Cello Aesthetic | Pending |
| AEST-04 | Phase 3 — Watercolor & Cello Aesthetic | Pending |
| AEST-05 | Phase 3 — Watercolor & Cello Aesthetic | Pending |
| AEST-06 | Phase 3 — Watercolor & Cello Aesthetic | Pending |
| AEST-07 | Phase 2 — Season 1 Vertical Slice (Soil) | Pending |
| AEST-08 | Phase 1 — Foundations & Doctrine | Pending |
| AEST-09 | Phase 1 — Foundations & Doctrine | Pending |
| UX-01 | Phase 2 — Season 1 Vertical Slice (Soil) | Pending |
| UX-02 | Phase 2 — Season 1 Vertical Slice (Soil) | Pending |
| UX-03 | Phase 8 — UX, Accessibility & Launch Polish | Pending |
| UX-04 | Phase 8 — UX, Accessibility & Launch Polish | Pending |
| UX-05 | Phase 3 — Watercolor & Cello Aesthetic | Pending |
| UX-06 | Phase 8 — UX, Accessibility & Launch Polish | Pending |
| UX-07 | Phase 8 — UX, Accessibility & Launch Polish | Pending |
| UX-08 | Phase 8 — UX, Accessibility & Launch Polish | Pending |
| UX-09 | Phase 8 — UX, Accessibility & Launch Polish | Pending |
| UX-10 | Phase 2 — Season 1 Vertical Slice (Soil) | Pending |
| UX-11 | Phase 2 — Season 1 Vertical Slice (Soil) | Pending |
| UX-12 | Phase 8 — UX, Accessibility & Launch Polish | Pending |
| UX-13 | Phase 1 — Foundations & Doctrine | Pending |
| PIPE-01 | Phase 1 — Foundations & Doctrine | Pending |
| PIPE-02 | Phase 2 — Season 1 Vertical Slice (Soil) | Pending |
| PIPE-03 | Phase 1 — Foundations & Doctrine | Pending |
| PIPE-04 | Phase 8 — UX, Accessibility & Launch Polish | Pending |
| PIPE-05 | Phase 1 — Foundations & Doctrine | Pending |
| PIPE-06 | Phase 1 — Foundations & Doctrine | Pending |
| PIPE-07 | Phase 2 — Season 1 Vertical Slice (Soil) | Pending |
Per-Phase Counts:
| Phase | Requirements |
|---|---|
| Phase 1 — Foundations & Doctrine | 16 |
| Phase 2 — Season 1 Vertical Slice (Soil) | 24 |
| Phase 3 — Watercolor & Cello Aesthetic | 8 |
| Phase 4 — Season-Prestige Cycle & Season 2 (Roots) | 8 |
| Phase 5 — Seasons 3-4 (Canopy & Storm) | 4 |
| Phase 6 — Seasons 5-6 (Depth & Loom) | 5 |
| Phase 7 — Season 7 (Return) & Final Choice | 4 |
| Phase 8 — UX, Accessibility & Launch Polish | 8 |
| Total | 77 |
Coverage:
- v1 requirements: 77 total (the "78" in the prior coverage block was a counting error in initial drafting; categories sum to 11+10+7+10+10+9+13+7 = 77 numbered REQ-IDs)
- Mapped to phases: 77 (100%)
- Unmapped: 0
Requirements defined: 2026-05-08 Last updated: 2026-05-08 after roadmap traceability mapping