diff --git a/docs/implementation.md b/docs/implementation.md new file mode 100644 index 0000000..723f9b1 --- /dev/null +++ b/docs/implementation.md @@ -0,0 +1,473 @@ +# 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. (~15–30 min) +- [ ] **Wolf sprite source** — bundle's Animal Sprites lacks wolves. Browse EvoMonster Packs 01–15 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 (~2–3 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. + +- [ ] 3–4 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 (~2–3 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 1–4, **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 (~1–2 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 (~1–2 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 (~2–3 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 (~1–2 weeks) + +**Goal:** close the death loop properly. + +- [ ] **Corpse entity** + decay timer: 0–50 fresh / 50–100 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 (~2–3 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 (0–100), 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 3–5 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 (~1–2 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 (~3–4 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 (~1–2 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 (~2–4 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 6–12 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). diff --git a/memory.md b/memory.md index 819fea6..6e6940b 100644 --- a/memory.md +++ b/memory.md @@ -14,8 +14,9 @@ A 2D, tile-based **cute-farming-RPG-meets-colony-sim** — Rimworld DNA, Going M | [`docs/architecture.md`](./docs/architecture.md) | Tech — pawn AI / job system, time/tick model, Godot 4 engine layout, TileMap split, all subsystems (mood, lighting, rooms, hauling, production, combat, storyteller) | | [`docs/ui.md`](./docs/ui.md) | Touch UX — work-priority matrix, stockpile/container screens, mood/lighting/rooms cues, combat banners, storyteller event UI, screens still to design | | [`docs/art.md`](./docs/art.md) | Owned assets (ElvGames bundle primary, Ventilatore secondary), license, autotile gotcha, audit list, candidates kept for record | +| [`docs/implementation.md`](./docs/implementation.md) | **Phased build plan** — 21 phases (audit → P0 scaffold → … → P20 export). Checklists, acceptance demos, scope-cut levers, de-risking spikes. Track progress here. | -When working on a feature, read `memory.md` first, then the relevant `docs/` file(s). +When working on a feature, read `memory.md` first, then the relevant `docs/` file(s). For "what do I build next?" check the **Status** row at the top of `docs/implementation.md`. ## Decisions & rationale @@ -156,6 +157,7 @@ Same scope as locked in `~/claude/ideas/rimlike/plan.md`. Realistic timeline 3 - Updated `docs/architecture.md` perf assumptions (60² → 80² with 120² ceiling). - `docs/ui.md` got a new **World view camera (locked)** section; removed the world-view bullet from "Screens still to design". - Open: auto-roof big-room UX (added to TODOs above) — the ≤8-cell BFS cap silently fails on bigger rooms; player feedback path needs a decision before EnclosureDetector lands. +- Wrote `docs/implementation.md` — 21-phase build plan with checkboxes, acceptance demos, scope-cut levers, and de-risking spikes. Status row at the top of that file is the canonical "where are we now" pointer; current value is **Phase 0 — Project scaffold & foundations** (gated by the 75-min pre-implementation audit). Wired into the index table above. ## External references