rimlike/docs/implementation.md
megaproxy daf26ed27a Add phased implementation plan (docs/implementation.md)
21 phases from clean-slate to MVP, dependency-ordered with each
phase ending in a runnable demo state. Includes:

- Pre-implementation audit (the 75-min asset checks from memory.md)
- Phases 0–20 with checklist + acceptance criteria + spec-doc refs
- Two DECIDE points (Phase 13 big-room UX, Phase 19 onboarding)
- Out-of-scope list (procgen, biomes, butchering, surgery, etc.)
- Scope-cut levers ranked by gameplay-cost-per-week-saved
- De-risking spikes per phase
- Wired into memory.md index + session log; current Status =
  Phase 0 (gated by the 75-min audit)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-10 19:53:39 +01:00

473 lines
29 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Implementation plan — rimlike
Phased build plan from clean-slate to MVP. Phases are ordered by dependency, and each ends with a runnable demo state so the project never sits in "everything's stubbed" territory for long.
Effort estimates are wall-time at **focused solo pace**. Scale up generously for context-switches, life, and the occasional rabbit hole. Ranges are deliberately wide.
| Status | Phase |
|---|---|
| ⏳ next | **Phase 0 — Project scaffold & foundations** |
Use this doc as a checklist: tick boxes as items complete, and update the **Status** row above whenever a phase rolls over. The last bullet of each phase is the *acceptance demo* — the phase is "done" when you can perform it.
Refs to `docs/` files are linked so each item lands in the right spec.
---
## Pre-implementation audit (~75 min)
The five items from `memory.md` *Open questions / Audit*. None of these need code, but several of them gate Phase 1+ (autotile drives the wall pipeline; aesthetic harmony decides whether Ventilatore stays in active use). Knock these out before Phase 0.
- [ ] **Aesthetic harmony test** — ElvGames Forest vs Ventilatore tile, side-by-side. Decide use-both or drop-Ventilatore. (~15 min)
- [ ] **ElvGames autotile audit** — count corner / T / cap pieces in `Houses Tileset 2 Seasons/FG_Houses.png` and `Fortress Tileset 2 Seasons/FG_Fortress.png`. ≥16 wall variants → autotile is solvable; <8 fall back to Iconic Homestead ($19.99) or custom-author. (~1530 min)
- [ ] **Wolf sprite source** bundle's Animal Sprites lacks wolves. Browse EvoMonster Packs 0115 or Turn-Based RPG Monster packs. Or plan custom (~few hours). (~15 min)
- [ ] **Grave marker source** Retro Graveyard 16×16 (Tier 3) probably has it. (~10 min)
- [ ] **License compilation start** kick off the credits string list now; add to it as packs come in. (open across phases)
---
## Phase 0 — Project scaffold & foundations (~1 week)
**Goal:** a Godot project that opens cleanly, has all the autoloads and folder structure committed, and runs an empty test scene.
- [ ] `godot --headless` (or editor) New Project at repo root, Forward+ renderer (mobile-friendly path TBD; check what export complains about)
- [ ] Re-copy `addons/godot_mcp/` from `/mnt/d/godot/mcp/addons/godot_mcp` and enable in Project Settings Plugins. Verify green dot in MCP Pro bottom panel.
- [ ] Folder layout:
- `scenes/` (`world/`, `pawn/`, `ui/`, `entities/`, `effects/`)
- `scripts/` (mirrors scenes/, plus `autoloads/`, `systems/`, `ai/`, `data/`)
- `data/` (`recipes/`, `thoughts/`, `events/`, `weather/`, `pawns/`)
- `art/` (`tiles/`, `sprites/`, `ui/`, `fx/`)
- `audio/` (`sfx/`, `music/`)
- `tests/` (GUT or built-in test runner pick later)
- [ ] Autoloads (empty stubs, real bodies land in later phases):
- `World` entity registry, tile state, signals
- `Sim` tick loop owner, speed/pause state
- `GameState` current map, save metadata, game-mode flags
- `EventBus` global signal bus
- `Strings` i18n string table (string keys EN values; load from `data/strings.en.tres`)
- `Audit` debug-only logging, perf counters
- [ ] Input map: `tap`, `long_press`, `pinch_in`, `pinch_out`, `drag`, `pause`, `speed_cycle`. Touch + gamepad mappings.
- [ ] Save/load skeleton: `SaveSystem.save(slot)` / `SaveSystem.load(slot)` version field, file IO, save-between-ticks contract enforced (no save calls allowed mid-tick). Round-trip a literal "hello" for now.
- [ ] `.gitignore` already covers Godot output; verify `.godot/`, `*.import`, `addons/godot_mcp/`, exports are all excluded
- [ ] Smoke-test scene: blank `World.tscn` with a `Camera2D`, hit Play, see a coloured background. Done.
- [ ] **Acceptance:** `godot --headless --quit` exits 0; clicking Play in editor opens a blank world without errors; `MCP Pro` panel shows the green dot.
---
## Phase 1 — World, tilemap, camera (~2 weeks)
**Goal:** an 80×80 map with the locked camera UX. No pawns yet; just a navigable empty world.
- [ ] `TileMap` with 6 layers per `architecture.md`: 0 Terrain · 1 Floor · 2 Wall · 3 Designation · 4 Roof · 5 Fog. Set z-indices, modulate, etc.
- [ ] Tileset import: at least one terrain (grass) + one floor + one wall material from ElvGames bundle. Skip autotile for now if Phase 0.5 audit hasn't completed.
- [ ] Generate an 80×80 placeholder map (procgen later for now, a hand-painted test map saved as a `.tscn` is fine)
- [ ] Tick loop: `Sim` runs at 20 Hz, render free-runs at 60 Hz, decoupled. Pawn-position lerping comes in Phase 2.
- [ ] Speed control: 1× / Fast (5×) / Ultra (12×) / Pause. Buttons fixed top-bar. Per `architecture.md` table sim-tick queue scales by speed factor.
- [ ] **Camera (per `ui.md` "World view camera (locked)"):**
- Pinch-zoom (smooth, between strategic and close no fixed levels)
- One-finger drag-pan on empty world
- Double-tap-centre on tap target
- No follow-cam; selection persists across pans
- Camera reads viewport, clamps to map bounds with a small bleed
- [ ] Indoor tint shader skeleton uniform on/off per tile, hooked up but always off (real driver lands in Phase 13)
- [ ] **Acceptance:** open project on phone (or phone-sized resize on desktop), pan and zoom an 80² map smoothly, hit pause/speed buttons. Speed feel matches the table in `architecture.md`.
---
## Phase 2 — Pawn skeleton, pathfinding, movement (~2 weeks)
**Goal:** 3 pawns on the map, click-to-move them around. No AI yet.
- [ ] Pawn scene: `CharacterBody2D` (or `Node2D` if we don't use built-in physics for movement TBD), sprite, name label, debug state badge
- [ ] Pawn registry on `World`: `pawns: Array[Pawn]`
- [ ] `AStarGrid2D` over the 80² map; walkable derived from terrain passability + furniture occupancy. Update affected cells on build/destroy/door-state-change (one cell per change O(1)).
- [ ] Walk-to-tile: pawn requests a path, follows, lerps between sim ticks for smooth render
- [ ] Click-to-move test: tap empty tile while pawn selected pawn walks there
- [ ] **Spike (~30 min):** AStarGrid2D path-query timing at 80² with 6 pawns simultaneously requesting paths. Confirm sub-millisecond per query.
- [ ] **Acceptance:** spawn 3 pawns, tap-select, tap-destination, watch them path around walls and reach the spot. Smooth motion at all speeds.
---
## Phase 3 — AI core: Decision → WorkProvider → JobRunner (~3 weeks)
**Goal:** the 5-layer pipeline from `architecture.md` is real, but with one dummy work category. **Save round-trip for JobRunner mid-toil state is required to land in this phase, not later.**
- [ ] `Decision` layer: priority-ordered checks (incapacitation forced job status interrupt work idle)
- [ ] `WorkProvider` interface `find_best_for(pawn) -> Job?`
- [ ] `Job` + `JobRunner` multi-step toils, each toil is `{action, predicate, on_complete}`
- [ ] Player overrides: forced job (e.g. "go here") preempts work
- [ ] Status interrupts skeleton only `Bleeding` for now (rest land at Phase 9)
- [ ] Idle behavior: stand still or wander locally (per `architecture.md:72`, idle is v2; MVP just stands)
- [ ] First WorkProvider: `RestProvider` sends pawn to a hardcoded "rest tile". Just a smoke test for the pipeline.
- [ ] **Save round-trip:** kill the app mid-toil-2-of-4, reopen, pawn resumes the same toil at the same position
- [ ] **Acceptance:** 3 pawns idle around a rest tile; force-move one with a tap-and-hold-issue-order; suspend mid-walk and resume seamlessly.
---
## Phase 4 — First verbs: chop, mine, hauling, stockpiles (~3 weeks)
**Goal:** the foundational gameplay loop pawns harvest things and pile them up.
- [ ] Tree entity (chop 3 logs drop), stone-tile mining (mine 1 stone drop), iron-ore-tile mining
- [ ] Item entity: position, type, stack size, on-floor sprite
- [ ] `ChopProvider`, `MineProvider` (subset of Construction work)
- [ ] **Hauling:**
- `HaulingProvider` + Hauling job toils (`walk → pick → walk → deposit`)
- `items_needing_haul` dirty set on `World` (per `architecture.md:243`)
- `StorageDestination` interface (zones first; containers Phase 5)
- **No-destination fallback** (locked decision): drop after 3 retry passes + passive `No stockpile accepts X` alert
- [ ] **Floor stockpile zones:**
- Zone-paint UI (designation paint mode reuses Phase 5 paint controller for now, a quick zone-paint button)
- 16-chip filter grid (Wd/St/Ir/Cu/Ag/Au/Cl/Veg/Mt/Gr/Ck/Md/Tl/Wp/Ar/Co)
- 5-priority cycle (Critical/High/Normal/Low/Off) on the zone
- One-stack-per-tile, one-type-per-tile rule
- [ ] Carry capacity = 1 stack, 1 type (multi-type carry is v2)
- [ ] **Spike (~1 hr):** 16-chip grid mockup on a 720×1280 viewport does it cram? Adjust before building.
- [ ] **Acceptance:** 3 pawns chop / mine / haul to a stockpile. Set the stockpile to wood-only pawns leave stone alone. Set a second stockpile to higher priority and watch wood flow upward.
---
## Phase 5 — Building, walls, floors, containers (~23 weeks)
**Goal:** the player can shape the world. End of phase: build a functional cabin.
- [ ] Designation paint mode (controller reused later by stockpile-paint, no-roof, etc.) drag-paints ghosts on Layer 3, green-if-placeable / red-if-blocked
- [ ] `BuildJob` queue on `World`, with material requirements
- [ ] Construction WorkProvider: nearest-job-first, hauls materials walks to ghost works N ticks swaps Layer 3 ghost for real Layer 2 wall (autotile fixes neighbours) updates pathfinder
- [ ] **Walls:** wood, stone (autotile per Phase 0.5 audit outcome fall back to manually-painted variants if autotile pieces are missing)
- [ ] **Floors:** wood plank, stone, dirt-cleared
- [ ] **Doors:** simple swing-open furniture; pawns walk through; pathfinder treats as walkable, walls don't
- [ ] **Containers (crates):** furniture entity, 4 stacks, 16-chip filter, 5 priorities, all-neighbours-blocked fallback (locked: hold then drop after ~5 sim sec)
- [ ] Deconstruction (reverse build job)
- [ ] **Acceptance:** Player paints a 6×4 cabin outline pawns haul wood walls go up floor + door drop a crate inside set crate filter to "tools" tools auto-flow into it.
---
## Phase 6 — Production: workbenches, recipes, bills, quality (~3 weeks)
**Goal:** crafting chains end-to-end with the full Rimworld bill semantics.
- [ ] **5 workbenches:** carpenter, smelter, smithy, cooking hearth, millstone
- [ ] **Recipe registry** `data/recipes/*.tres`, ~22 recipes per `design.md`
- [ ] Recipe DSL: ingredients (with optional quality filter), product (count, type), workTime, skill (Crafting or Cooking), skillThreshold
- [ ] **Bill semantics:**
- Modes: one-shot count / forever / until-N-in-stockpile
- Ingredient quality minimum filter (e.g. "Excellent+ iron ingots only")
- Skill threshold gate
- Bill round-trip in saves
- "Bill blocked" alert when no ingredients qualify (open question drives Phase 17 alerts)
- [ ] CraftingProvider + CookingProvider (per `architecture.md:559` 9-list)
- [ ] **Quality system** (Shoddy/Normal/Excellent/Masterwork/Legendary) additive: skill × 0.04 + RNG; multiplicative stat bonus; quality stamped on every crafted item
- [ ] **Spike (~2 hr):** prototype the recipe-as-Resource format. Does the bill UI fit in a single bottom-sheet? Adjust before authoring 22 recipes.
- [ ] **Acceptance:** smelt iron, smith a sword. Watch quality vary by smith skill. Set a bill "until 5 swords in stockpile" pawns stop at 5, restart when one is taken.
---
## Phase 7 — Plants, cooking, hunger (~2 weeks)
**Goal:** food loop from seed to belly.
- [ ] 34 crops: wheat, potato, berry-bush, hop (final picks TBD; ElvGames bundle pickings audit-driven)
- [ ] Plant tile state machine: tilled sown growing (4 stages) ready
- [ ] Plant WorkProvider: till + sow + harvest (matches the 9-category list)
- [ ] **"Plants don't grow indoors"** rule depends on Layer-4 Roof flag, which doesn't exist yet at this phase. Stub it (always-outdoor) and revisit in Phase 13.
- [ ] Cooking: hearth recipes (raw ingredient meal), shelf-life on meals
- [ ] Eating: pawn walks to nearest meal, consumes, hunger drops
- [ ] **Hunger need** + thought (`design.md` mood section)
- [ ] **Acceptance:** full grain flour (millstone) bread (hearth) eat loop. Hungry pawn auto-prioritises eating.
---
## Phase 8 — Sleep, mood, thoughts (~3 weeks)
**Goal:** pawns have an interior life. Mood swings drive behaviour.
- [ ] Beds (furniture, "owned by pawn", quality affects sleep)
- [ ] Sleep need + sleep-mood gradient (placeholder numbers `+5/+0/2/5/8` from `design.md` Tunables)
- [ ] Tired status, decision-pipeline override (sleep when low)
- [ ] **Mood thought registry** data-driven, ~13 thoughts per `design.md`
- [ ] Mood compute (`architecture.md:318`): base 50 + sum(modifier × min(stacks, MAX_STACKS_PER_THOUGHT)). **`MAX_STACKS_PER_THOUGHT = 5`** (locked).
- [ ] Thoughts: persistent (state-driven) or event (decay over hours), with stacking rules
- [ ] **Soft breaks** Sulking and Wandering, fire when mood < 25 sustained for 30 in-game min, recover at mood 35
- [ ] Mood UI: small mood bar on pawn portrait, breakdown in pawn-detail (Phase 17)
- [ ] **Acceptance:** Force-create misery (cold, hungry, no bed, sees corpse): mood plummets, pawn enters Sulking, meet needs, recovers.
---
## Phase 9 — Status effects + Medicine (~23 weeks)
**Goal:** the full status-driven drama from `design.md` Health section.
- [ ] **Status registry:** Hungry, Tired, Bleeding, Sick, Downed, Wet (Damp/Soaked), Cold
- [ ] Each status: trigger condition, decay rate, gameplay effect (move-speed, work-speed, mood thought, threshold-flips)
- [ ] **Bleed-out timer** (`BLEED_OUT_TICKS` = 6 in-game hours from `design.md:418`, locked)
- [ ] Doctor work category (already in 9-list; provider lands here)
- [ ] **Medical bed** furniture
- [ ] Treatment job: walk fetch supplies walk treat (timed by Medicine skill)
- [ ] Doctor interrupt prioritization Combat=Off doctors still volunteer for medicine
- [ ] **Downed → rescue model:** Downed pawns get a timer; doctor walks them to medical bed; if timer expires before bed, pawn dies
- [ ] **Acceptance:** Wound a pawn bleeds second pawn breaks off work carries to medical bed treats recovery thoughts fire. Try with no doctor available pawn dies, watch the death pipeline run (Phase 14 closes the loop).
---
## Phase 10 — Combat + Wolves (~3 weeks)
**Goal:** real threat, real defense, real consequences.
- [ ] **3 weapons:** sword (melee), axe (melee, slow), bow (ranged) stats per `design.md`
- [ ] **3 armor slots:** helm, cuirass, boots
- [ ] Equipment system on pawn (carry + active slots)
- [ ] **Hit math:** two-roll resolution (hit roll damage roll, armor reduces damage). Bonuses: skill ×5%, range ×5%, cover 40/20%. Numbers placeholder, tune in Phase 20.
- [ ] **Cover:** walls = 40%, trees = 20%. Cover lookup is per-shooter, per-target line.
- [ ] Combat priority semantics: Off "won't fight" Off = "defends if cornered, won't volunteer" (per `design.md:64`)
- [ ] **Friendly fire ON** bow pawns can hit teammates in line
- [ ] **Wolf entity:** Animal class, 4-state machine (APPROACH ENGAGE FLEE DEAD per `architecture.md:700`)
- [ ] Wolf spawn: storyteller-driven, at map edge, in packs of 14, **night only**, season-weighted (more in winter)
- [ ] **Spike (~half day):** combat feel 3 pawns vs 3 wolves on a small map. Does the two-roll resolution feel good? If not, dial numbers before Phase 20.
- [ ] **Acceptance:** Wolf raid at night pawns auto-fight (or flee per priorities) some get downed doctor saves who they can bodies on the field.
---
## Phase 11 — Day/night + Lighting (~12 weeks)
**Goal:** the world has a rhythm; night feels different.
- [ ] Time-of-day clock (already in tick loop surface to UI)
- [ ] Top-bar clock + day counter ("Day 14, 6 AM")
- [ ] **Light sources:** torch furniture, hearth furniture (already exists for cooking), candle. Each has radius (max 8) and on/off state.
- [ ] `light_map` compute (per `architecture.md:366`) recompute on light-source-change only, not every tick. Touches 200 cells per change.
- [ ] **Night shader:** sample `light_map`, brighten lit tiles, darken unlit. Smooth dawn/dusk transition (~30 in-game min each)
- [ ] "In darkness" mood thought integration fires for pawns standing in unlit cells at night
- [ ] **Acceptance:** Day dusk night dawn cycle visible. Indoor lit areas glow; outdoor unlit areas are dim. Pawn in a dark room at midnight gets the mood thought.
---
## Phase 12 — Seasons + Weather (~12 weeks)
**Goal:** 48-day year cycle with daily weather variety.
- [ ] **48-day year:** 4 seasons × 12 days. Seasonal palette modulate on tilemap (subtle).
- [ ] **Daily weather roll** (`design.md:582`): clear / rain / storm / cold-snap, season-weighted (placeholder weights, tune Phase 20)
- [ ] Rain visual + ambient sfx (sourced from bundle SFX packs)
- [ ] Storm = rain + lightning flashes + dampness rate ×2
- [ ] Cold snap = winter-only, applies Cold status faster
- [ ] **Wet status** accumulation outdoors in rain (Damp at 25, Soaked at 60), decays indoors. Mood thought tiers.
- [ ] **Cold status** in winter outdoors, slower decay than wet
- [ ] **Season indicator UI** (top bar): "Spring 4/12", tap forecast tooltip
- [ ] **Acceptance:** Run 1 in-game year, see all 4 seasons cycle. Trigger rain watch outdoor pawns get Damp, then Soaked. They head indoors and dry off.
---
## Phase 13 — Rooms, roofing, beauty, dirtiness, cleaning (~23 weeks)
**Goal:** built-environment systems your cabin matters now.
- [ ] **EnclosureDetector** + **RoomDetector** (per `architecture.md:967` and 982)
- [ ] **Auto-roof BFS** (≤8 cells, per `architecture.md:983`) sets Layer-4 Roof flag
- [ ] **No-Roof designation** (paint mode) courtyards stay open
- [ ] **`room_too_large` signal** when BFS hits the cap on an enclosed area (locked decision from this session)
- [ ] **DECIDE: big-room UX** (open question in `memory.md`):
- (a) Keep 8 cap, surface "split with an interior wall" banner minimal scope
- (b) Bump cap to ~16, banner at the new threshold
- (c) Detect any enclosed area regardless of size bigger architectural shift
- Recommendation lands here; deferring past Phase 13 means bugs.
- [ ] **Indoor tint** driven by Roof flag wires to the shader skeleton from Phase 1
- [ ] Plants-don't-grow-indoors rule wires up properly (was stubbed in Phase 7)
- [ ] **Beauty score** per cell, derived from nearby furniture × Quality multiplier
- [ ] **Dirtiness** accumulation, traffic-weighted, spike events (blood from combat = +20, corpse decay = +5/h)
- [ ] **Cleaning WorkProvider** (the 9-list category earlier doc text said "8th"; that's stale)
- [ ] Room thoughts: clean/dirty, beautiful/ugly, ate-without-table, slept-in-room
- [ ] **Spike (~1 hr):** room detection on a stress map (50+ rooms). Does it stutter on rebuild?
- [ ] **Acceptance:** Build a kitchen mood reflects it (table, beauty). Bloody combat in bedroom room turns ugly until cleaned. Build a 12-cell enclosed room big-room banner fires (per (a)/(b)/(c) decision).
---
## Phase 14 — Death, corpses, burial (~12 weeks)
**Goal:** close the death loop properly.
- [ ] **Corpse entity** + decay timer: 050 fresh / 50100 rotting / 100 rotted
- [ ] **Graveyard stockpile** special filter: Corpses-only chip
- [ ] **Grave dig job** (Manual Labor) produces a grave slot
- [ ] **Permanent grave marker** entity: tap opens deceased-pawn detail (Phase 17)
- [ ] **Cremation pyre** furniture + recipe (1 corpse + 5 wood ash + brief mood thought for pawns nearby)
- [ ] Mood thoughts: "saw corpse", "buried friend", "cremated friend", "rotting body in colony" (severity scales)
- [ ] Death triggers in pawn pipeline (already wired in Phase 9) end here corpse drops, hauler fires.
- [ ] **Acceptance:** Pawn dies (combat or untreated illness) corpse on the floor graveyard zone painted hauler takes corpse to grave slot digger digs marker placed. Tap marker, see deceased pawn's portrait + 1-line backstory + mood-thought legacy.
---
## Phase 15 — Storyteller (~23 weeks)
**Goal:** the world prods the player without overwhelming them.
- [ ] **Event registry:** 25 prompts authored in `design.md` ported to `data/events/*.tres`
- [ ] **Daily 6 AM roll** picks one event from a weighted pool
- [ ] Weighted pool builder: trigger predicate, **per-event AND per-category cooldowns** (locked: both gates must pass), tension modifier
- [ ] **Cooldowns:** per-event from event def; per-category from `CATEGORY_COOLDOWN` (3 days threats, 5 days wanderers, etc.)
- [ ] **Tension model:** running tension score (0100), high tension reduces threat weight (×0.3), low tension boosts (×2.0)
- [ ] State-triggered events ("First Beds" while no beds exist) at higher weight than random
- [ ] **Banner UI** (ambient, dismissible, no pause) for nudges/seasonal/lore
- [ ] **Modal auto-pause** for wanderer/threat/disease/milestone (player choice)
- [ ] **"Go there" jump-to-alert** integration every alert/banner includes the camera-pan tap (locked)
- [ ] **Ghost state + Wanderer event recovery** when all colonists dead/gone, sim half-speed, wanderer fires in 35 days
- [ ] **Acceptance:** Play a full season, all event categories fire at least once. Trigger ghost state by killing all 3 pawns wanderer arrives within the window.
---
## Phase 16 — Save/load full coverage (~12 weeks)
**Goal:** the save round-trip from Phase 3 expanded to every system. Mid-tick suspend safe.
- [ ] All entity types serialize (pawn, item, furniture, container, corpse, wolf, plant tile)
- [ ] Tilemap layers serialize via `get_used_cells_by_id`
- [ ] Storyteller state (current tension, recent-fired log per event + per category, scheduled events)
- [ ] Bill states (mid-fetch, mid-craft)
- [ ] Pawn deep state: thoughts, statuses, equipment, current job + JobRunner toil index
- [ ] **Autosave on suspend** (mobile platforms `NOTIFICATION_APPLICATION_PAUSED`)
- [ ] **"You've been away X minutes" toast** on resume (no fast-forward in MVP)
- [ ] Slot management: single slot for MVP, manual save + autosave file
- [ ] Save version number; load barfs gracefully on mismatch
- [ ] **Acceptance:** Kill the app mid-anything (mid-haul, mid-craft, mid-bleed-out, mid-storyteller-modal). Reopen. Everything resumes seamlessly. No exceptions, no visual desync.
---
## Phase 17 — Touch UX completion (~34 weeks)
**Goal:** every interaction has a touch path. No desktop-only gestures.
- [ ] **Work-priority matrix** (9 cols × N pawns, sticky pawn-name column, horizontal scroll on phone, tap-to-cycle priority, long-press 5-chip picker, swipe-column bulk-set)
- [ ] **Per-pawn / per-job views** layered on the matrix
- [ ] **Stockpile / container UI** 4×4 chip grid, priority cycle, allow/forbid all
- [ ] **Build drawer** bottom-sheet tabs (Walls / Floors / Furniture / Production / Designate). Material-pick UI when multiple materials match.
- [ ] **Storyteller event modal** vs ambient banner UX
- [ ] **Pawn detail** screen (bottom-sheet, full-height): needs bars, status effects, current job, equipment, mood thoughts breakdown, skill table, deceased-state
- [ ] **Settings** speeds, auto-pause toggles, audio volumes, accessibility
- [ ] **Day-summary card** recap at end-of-day, gives short sessions a stopping point (`ui.md:620`)
- [ ] **Alerts log** + **storyteller event history**
- [ ] **Bill UI** for workbenches (created in Phase 6 stub; full UX here)
- [ ] **"No stockpile accepts X"** alert from Phase 4 hauling fallback wires up here
- [ ] **"Bill blocked"** alert from Phase 6 quality-filter wires up here
- [ ] **Acceptance:** every screen in `ui.md` "Screens still to design" exists and is touch-driven. Hand the device to someone who's never played they can navigate without instruction.
---
## Phase 18 — Audio (~1 week)
**Goal:** the game has soundscape; not silent.
- [ ] Ambient day loop, ambient night loop (bundle music packs)
- [ ] UI clicks (tap, long-press confirm, error)
- [ ] Combat stings: hit, miss, downed, kill
- [ ] Alert stings: storyteller modal, ambient banner, raid warning, pawn-down
- [ ] Volume sliders in Settings (master / music / sfx / ambient)
- [ ] Audio mute on suspend; fade in on resume
- [ ] **Acceptance:** play through a normal in-game day. Sounds fire at the right moments, mute toggles work.
---
## Phase 19 — Onboarding & first-60-seconds (~12 weeks)
**Goal:** resolve the open question in `memory.md` a new mobile player gets productive in <60 seconds.
- [ ] **DECIDE:** approach (open question, not enough thinking yet):
- (a) Hint system contextual tooltips during first session, dismissible, no replay
- (b) Guided first-day scripted storyteller events on day 1 walking through chop / haul / build / sleep
- (c) Tutorial scene separate from main game, opt-in
- Recommendation lands when this phase begins.
- [ ] First-time-player flag persisted
- [ ] **Acceptance:** hand the game to a tester cold. They are doing useful colony work within 60 seconds without you saying anything.
---
## Phase 20 — Balance, polish, export (~24 weeks)
**Goal:** ship-ready.
- [ ] **Tune all placeholders** (`memory.md` Tunable list):
- Sleep mood gradient `+5/+0/2/5/8`
- Wet thresholds 25 / 60 + accumulation rates
- Season weather weights
- Hit-chance bonuses (skill ×5%, range ×5%, cover 40/20%)
- Bleed-out timer (6h)
- Mood thought magnitudes + decay times
- [ ] iOS export setup (needs Mac/Xcode this is the long tail)
- [ ] Android export from Linux
- [ ] **Steam Deck input parity** open question (`memory.md`): gamepad-cursor or D-pad menus or both?
- [ ] **Credits screen** every art pack, every audio pack, every font (compiled across all phases)
- [ ] Bug pass known issues from each phase's parking lot
- [ ] Performance pass profile on a real low-end Android device
- [ ] **Acceptance:** TestFlight build for iOS, signed APK for Android, Steam Deck verified launch. Credits screen complete.
---
## Out of scope (v2+ / explicit cuts)
These are *not* in MVP. Pulling any of them in adds weeks. Each is a known v2 candidate.
- Procgen maps (MVP: fixed seed)
- Multiple biomes (MVP: temperate forest only)
- Bandit raids (MVP: wolves only)
- Butchering animals for meat
- Surgery / limb damage / specific body parts (MVP: single HP + status)
- Background simulation when app is backgrounded
- Fast-forward on long absence
- Tech / research progression tree
- Pawn name / backstory generator (MVP: hand-curated list)
- Multi-pawn carry, multi-type carry
- Per-bench ingredient radius restriction
- Localization beyond English (architecture supports it; content stays EN)
- Post-launch monetization decisions (premium / PWYW / free)
- Multiplayer in any form
- Pets / tame animals
- Trade caravans
- Drugs / alcohol / festivals
- Prisoner mechanics
---
## Scope-cut levers
If 612 months calendar is too long, these are sane reductions ranked by gameplay-cost-per-week-saved:
| Cut | Saves | Cost |
|---|---|---|
| Drop seasons & weather (keep day/night) | ~2 wk | Big kills atmospheric variety |
| Drop dirtiness + Cleaning category | ~1 wk | Small but loses one mood lever |
| Drop combat entirely (no wolves) | ~3 wk | Huge only quiet events left |
| Drop quality system (everything is Normal) | ~1 wk | Medium flattens late game |
| Drop cremation, keep burial only | 0.5 wk | Tiny |
| Reduce skills 5 3 (Labor, Combat, Medicine) | 0.5 wk | Tiny tightens design |
| Drop room beauty score (rooms still detected) | 0.5 wk | Small loses one mood lever |
| Single workbench instead of 5 | ~1.5 wk | Big collapses production design |
| Drop ranged weapons (sword/axe only) | ~0.5 wk | Small loses cover-relevance |
---
## De-risking spikes (run *before* the relevant phase)
| Spike | Phase | Effort | Question to answer |
|---|---|---|---|
| AStarGrid2D timing at 80² with 6 concurrent path queries | Phase 2 | ~30 min | Sub-millisecond per query? |
| 16-chip filter UI mockup on phone viewport | Phase 4 | ~1 hr | Does it cram or fit cleanly? |
| Recipe-as-Resource format prototype | Phase 6 | ~2 hr | Does the bill UI fit a single bottom-sheet? |
| Combat feel test (3 vs 3 on small map) | Phase 10 | ~half day | Does two-roll resolution feel good? |
| Room detection on stress map (50+ rooms) | Phase 13 | ~1 hr | Does rebuild stutter? |
---
## How to use this doc going forward
- **At session start:** check the Status row at top, then jump to the current phase. Read its goal + current open boxes.
- **During a session:** tick boxes as they complete. If the work uncovers something not on the list, add it as a new box (don't silently expand scope across phases).
- **At session end:** if a phase rolled over, update the Status row and add a `### YYYY-MM-DD` entry to `memory.md` Session log noting what landed.
- **DECIDE points** (currently in Phases 13 and 19): when you hit one, propose options + pick before continuing past it. Don't paper over.
- **Spikes:** treat the de-risking spikes as bona-fide tasks, not optional. Skipping them invites the cost-per-week to balloon.
## What lives elsewhere
- **Game design / mechanics** see [`design.md`](./design.md).
- **Tech / engine layout / pawn AI** see [`architecture.md`](./architecture.md).
- **Touch UI / camera** see [`ui.md`](./ui.md).
- **Tilesets / art / license** see [`art.md`](./art.md).
- **Decisions index / open questions** see [`memory.md`](../memory.md).