rimlike/memory.md
megaproxy a4163ba222 Chop/mine designation gate + reachability gates on Doctor & Eat
Player reported pawns ignoring chop designations. Root cause:
ChopProvider/MineProvider iterated World.trees/World.rocks
unconditionally — paint set a null sentinel and never touched the entity,
so designation was cosmetic only. Pawns auto-chopped nearest unfelled tree.

* Added chop_designated: bool to Tree, mine_designated: bool to Rock and
  BigRock (footprint-aware: paint on any of the 4 footprint cells flags
  the boulder). Save/load round-trips the flag.

* world.gd._on_designation_added 'chop'/'mine' cases now find the entity
  at the painted tile and flip the flag. _on_designation_cleared inverts.

* Boot seed auto-designates SAMPLE_TREES / SAMPLE_ROCKS / SAMPLE_BIG_ROCKS
  so the cabin demo still produces wood + stone end-to-end without
  requiring the player to paint first.

Also from the same audit (researcher mapped all 11 WorkProviders):

* DoctorProvider + EatProvider now pre-check reachability with
  pathfinder.find_path before issuing a job, mirroring HaulingProvider's
  pattern. Previously they handed out doomed walks that JobRunner had to
  cancel, busy-spinning at 20 Hz.

Verified end-to-end via MCP runtime: undesignated tree/rock returns null
from provider; paint flips the flag and provider returns a chop/mine job;
un-paint clears the flag; BigRock footprint paint works on any of the 4
cells.

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

47 KiB
Raw Blame History

memory — rimlike

Durable memory for this project. Read at session start, update before session end. Date format: YYYY-MM-DD.

A 2D, tile-based cute-farming-RPG-meets-colony-sim — Rimworld DNA, Going Medieval × Stardew lodestars — shaped for mobile and handheld. Promoted from ~/claude/ideas/rimlike on 2026-05-10 after a single deep brainstorm session. Realistic MVP timeline: 36 months solo.

How to read this project

memory.md is the index of decisions and open questions. The deep specs live alongside in docs/:

File Contents
docs/design.md Game design — core loop, simplifications, skills, statuses, mood, weather, stockpiles, production, combat, death/burial, storyteller corpus
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 Touch UX — work-priority matrix, stockpile/container screens, mood/lighting/rooms cues, combat banners, storyteller event UI, screens still to design
docs/art.md Owned assets (ElvGames bundle primary, Ventilatore secondary), license, autotile gotcha, audit list, candidates kept for record
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). For "what do I build next?" check the Status row at the top of docs/implementation.md.

Decisions & rationale

Distilled from the brainstorm. Each lock has a "why" — change with deliberate intent.

Pillars

Decision Choice Why
View Top-down grid for gameplay (pathfinding, designation, floor) + 3/4-perspective rendering for vertical structures (walls, doors, furniture). Re-decided 2026-05-10 after exhausting the asset library: every wall pack we own is RPG-style perspective (Stardew / Going Medieval style), not Rimworld-style top-down. Pivoting the renderer (Y-sorted entity sprites for walls) makes the entire library usable as-is and replaces the "we need to author or commission" bottleneck. Gameplay grid + pathfinding stay identical; only the rendering of vertical structures shifts.
Wall layer rendering Walls are entity sprites (Sprite2D / Y-sorted Node2D), not TileMap cells. Wall TileMap layer (Layer 2) becomes data-only — used for pathfinding-impassable + room-detection BFS, but doesn't render. Same source as the view-style pivot above. Consequence: doors, crates, furniture all live as entities with Y-sort; floor and designation-paint still tile-based. Architecture.md TileMap-layer section needs an annotation.
Primary platforms iOS + Android touch, then Steam Deck / ROG Ally gamepad. Desktop falls out for free. Mobile is the hard constraint; Deck inherits.
Ambition itch.io + TestFlight release. Real artifact, small audience. Drives engine choice; no app-store polish-tax.
Engine Godot 4 (GDScript) 2D-first, free, exports everywhere we need, fast iteration.
Tile size / style 16×16 pixel art, cute-farming-RPG primary (ElvGames bundle), Ventilatore as medieval accent ElvGames "Ultimate Farming RPG" Humble bundle owned (~2.8 GB, 70+ packs). Tone: Stardew × Going Medieval × Rimworld.
Setting Medieval fantasy with cute palette Owned-art alignment + clearer scope (no electricity / hydroponics / energy weapons) + underexplored on mobile.
Run shape Open-ended sandbox, autosave, persistent world Player picks up where they left off.
Session length 515 min target Drives every UI and pacing choice.
Default speed Fast (5×), with auto-pause on event 1 in-game day ≈ 5 min real time. Solves the "watch a pawn walk for 60s" problem; 1× exists for combat / fine work.
Goal scaffolding Light storyteller prompts Soft, dismissible nudges give each short session shape without forcing scenarios.
Combat Realtime with auto-pause on threat Rimworld-feel; touch-friendly.
Health Single HP per pawn + status effects (Bleeding/Sick/Tired/Hungry/Wet/Cold/Downed/...) ~80% of the drama for ~5% of Rimworld's health-system code.
Scale 36 pawns, 80×80 MVP map (architecture sized to ~120² ceiling) Roughly Stardew-farm size; readable when zoomed in, doesn't fit a phone screen — forces the world-view camera (pinch / pan / jump-to-alert) rather than strategic-overview-on-phone.
Priority levels 5 (Critical / High / Normal / When idle / Off) Matches Rimworld + Going Medieval contract.
Failure state Ghost colony — no game over; storyteller drops wanderer in 35 days Mobile-friendly; preserves player investment.
Engine version Godot 4.6.2 stable (Win64 binary at D:\godot\Godot_v4.6.2-stable_win64.exe) Locked for reproducibility; pinned in project.godot features.
Renderer GL Compatibility (mobile + desktop), not Forward+ Max device reach; Forward+ would lock out older phones.
Repo location Physical: /mnt/d/godot/rimlike/ (D: drive, fast for Windows-side editor). Symlink: ~/claude/projects/rimlike → physical. Mirrors tavernkeep's pattern. Both WSL and Windows access without crossing the WSL net bridge.
Player walls Wood + stone via Pixel Crawler Walls.png (entity sprites, Y-sorted; no autotile in Phase 5). Single-sprite-per-material is the Phase 5 ship; per-direction variants are a polish item. After the rendering pivot to 3/4 perspective, the Pixel Crawler Walls.png pack becomes directly usable. It has 4 wood materials + a sandstone variant with clear corner/edge pieces. Phase 5 ships with one sprite per material (uniform-looking walls); Phase 17 can add per-direction variants if playtest reveals the visuals feel flat. Stardew-cabin warmth restored without authoring or commission.

Architecture (tech)

  • Sim tick 20 Hz, render 60 Hz, decoupled. Pawn positions lerp between sim ticks. (docs/architecture.md Time / tick model)
  • Pawn AI: 5-layer pipeline (Decision → WorkProvider → Job + JobRunner → Status interrupts → Player overrides). Slimmer than Rimworld's ThinkTree. ~8001500 LOC GDScript for full MVP.
  • TileMap layers: 0 Terrain · 1 Floor · 2 Wall · 3 Designation · 4 Roof · 5 Fog. Furniture / Pawn / Item / EffectFX as scene-instanced entities (not TileMap).
  • Pathfinding: AStarGrid2D (built-in), updated on wall/door/furniture changes.
  • No background simulation — app backgrounded = sim paused. Avoids "lost colony to a raid while at work."
  • Save format: between sim ticks only; JobRunner mid-toil state round-trips from day one.

Game design

  • 5 skills (Manual Labor / Crafting / Cooking / Medicine / Combat), 010 each, level by use, multiplicative speed/quality bonus. Skills modify duration and quality, never permission.
  • 9 work categories (Construction / Mining / Hauling / Cleaning / Crafting / Cooking / Plant / Doctor / Combat). 5-level priority matrix per pawn.
  • Storage: floor zones AND independent crate furniture (4 stacks each), unified by StorageDestination interface. 16 filter chips (Wd/St/Ir/Cu/Ag/Au/Cl/Veg/Mt/Gr/Ck/Md/Tl/Wp/Ar/Co), 5 priorities with Rimworld flow semantics. One stack per tile, one type per tile.
  • Production: 2-step where medieval-sense (Iron→Ingot→Weapon, Grain→Flour→Bread); 1-step otherwise. 5 workbenches (Carpenter, Smelter, Smithy, Cooking hearth, Millstone), ~22 recipes. Full Rimworld bill semantics (one-shot count / forever / until-N + ingredient-quality filter + skill threshold).
  • Quality system (Shoddy/Normal/Excellent/Masterwork/Legendary) on every crafted item; multiplicative stat bonus. Quality from crafter skill + RNG only (inputs are just resources).
  • Mood: ~13 thoughts (data-driven registry, mix persistent + event-driven). Soft breaks at sustained mood < 25 for 30 in-game min — Sulking or Wandering, recover at mood ≥ 35.
  • Lighting (real shader at night), auto-detected rooms (named by furniture, scored for beauty + dirtiness), dirtiness + Cleaning (8th work category), beauty score with Quality multiplier.
  • Roofing: indoor = Layer-4 Roof flag, sim-data only (no rendering, just an indoor tint on floors). Auto-roof when walls enclose ≤8 cells (BFS); No-Roof designation for courtyards. Plants don't grow indoors.
  • Weather: 4 types (Clear / Rain / Storm / Cold snap), daily roll, season-weighted. Wet status accumulates outside in rain, decays indoors. 4 seasons × 12 days = 48-day year.
  • Combat: 3 weapons (sword/axe/bow), 3 armor slots (helm/cuirass/boots). Walls + trees provide cover. Two-roll resolution (hit, then damage with armor reduction). Downed-then-rescue death model; doctors auto-prioritize. Combat=Off "defends if cornered, won't volunteer." Friendly fire ON.
  • Death / corpses: Both burial AND cremation. Graveyard = special stockpile (Corpses-only); pawns dig graves, place permanent grave markers (tap → deceased pawn-detail). Cremation pyre = furniture with single recipe (1 corpse + 5 wood). Corpses decay 050 fresh / 50100 rotting (no butcher) / 100 rotted.
  • Storyteller: 25 prompts written in docs/design.md. Daily 6am roll, weighted pool, per-category cooldowns, tension model alternates quiet/threat per Tynan Sylvester pacing. Ambient banner for low-stakes, modal auto-pause for choice events.

Touch UX

  • Bottom-sheet menus instead of right-side panels. Long-press = inspect/context. Tap world = select. Speed/pause buttons fixed top.
  • Work-priority matrix: 9 columns × N pawns, sticky pawn-name column, horizontal scroll on phone. Tap-to-cycle priority, long-press for 5-chip picker, swipe column for bulk-set. Per-pawn and per-job views layered on top.
  • Stockpile/container UI: 4×4 chip grid for the 16 filter categories; same UI for floor zones and crates.
  • Storyteller events: ambient banners for nudges/seasonal/lore; modal auto-pause for wanderer/threat/disease/milestone. Events log + "while you were away" digest at resume.
  • Indoor tint marks "this is inside" without needing roof rendering — matches Stardew/Rimworld convention.
  • World-view camera: pinch-zoom + drag-pan + double-tap-to-center; selected pawn does not force-follow. Storyteller alerts/banners include a Go there tap that pans the camera to the event tile. No minimap in MVP — revisit if playtest shows people getting lost on the 80² map.

Art strategy

  • ElvGames "Ultimate Farming RPG" Humble bundle is the primary art (/mnt/d/godot/assets/humble set new/, ~2.8 GB, 70+ packs, all 16×16, ElvGames license: commercial OK with credit).
  • Ventilatore Fantasy Tileset Complete Bundle stays as medieval accent for biome variety / decorative props / animated water.
  • Mana Seed series considered but dropped from buy plan (the bundle covers what we'd planned).
  • Authoring still required: designation overlays (~2 hrs custom), possibly autotile bits on bundle wall sheets, possibly wolf sprite, possibly grave marker.

Known bugs / triage backlog

Reported from playtest. Triaged but not yet fixed. Plan: knock out as a bug-triage patch out-of-phase before Phase 18 (Audio) — same shape as the 2026-05-12 PC-controls patch.

  • [HIGH] Torches don't build when placed. Reported 2026-05-15, fixed 2026-05-15. Root cause: Torch/Bed/Crate/Workbench/CremationPyre didn't call World.register_build_site(self) in _ready (only Wall/Floor/Door/GraveSlot did). ConstructionProvider iterates World.build_queue so the unregistered entities were never offered as jobs. The seeded cabin pre-built everything via _spawn_complete_* helpers, masking the gap until a player painted a fresh furniture designation. Fix: added register_build_site / unregister_build_site to all five entity types.
  • [HIGH] Two of three pawns sit idle, one does all work. Reported 2026-05-15, fixed 2026-05-15. Root cause: pawns get stranded on tiles that became impassable mid-walk. Sequence: pawn-A walks a path computed pre-wall; pawn-B builds a wall on a tile in pawn-A's path; pawn-A keeps stepping along the now-stale path and lands on the wall tile; pathfinder requires a walkable START, so all subsequent find_path calls from pawn-A return empty → pawn-A is idle forever. The Phase 6 wall-trap-bug fix only protected the BUILDING pawn (adjacent-stand); bystanders + walk-through cases weren't covered. Two-part fix: (a) Wall._complete dislodges any pawn standing on the tile via new Pathfinder.find_nearest_walkable BFS helper; (b) Pawn._advance_walk re-checks next_tile walkability before snapping tile, aborts walk + cancels job + lets Decision reroute. Defense in depth.
  • [MED] Pawns render behind floor tiles. Reported 2026-05-15, fixed 2026-05-15. Root cause: Floor entity anchored origin at tile-center (tile.y*16+8), same Y as Pawn — Y-sort tiebreak fell to scene-tree order, Floor (spawned later) drew over Pawn. Fix: moved Floor origin to top-of-tile (tile.y*16) so Floor.y < Pawn.y under Y-sort; _draw offsets compensate (rect spans y=0..TILE_SIZE_PX instead of -half..+half).

Older bugs noted in passing but never fixed:

  • [LOW] Bed-claim failure for 2/3 pawns when beds are free (logged 2026-05-11). Bram bed claim failed at /root/Main/World/Bed — sleeping on floor even when beds free. Doesn't gate progress; needs sleep-system audit.
  • [LOW] Save mid-INTERACT/mid-BUILD restarts toil from 0 on load (Phase 16 known acceptable gap). Walk toil round-trips; multi-step interact does not. Tolerable per Phase 20 tuning note.

Open questions / TODOs

Audit / unblock-the-prototype action items

Total ~75 min. 3 of 5 closed on 2026-05-10; see session log + docs/art.md for findings. Two open.

  • Aesthetic harmony test — needs your eye. ElvGames Forest tile vs Ventilatore tile, side-by-side. Decides whether Ventilatore stays as accent or gets shelved. ~15 min.
  • ElvGames autotile audit — done. FG_Fortress.png IS autotile-solvable (tan stone, ~2030 modular pieces); FG_Houses.png is NOT (pre-built decorative house compositions, not modular wall variants). Iconic Homestead $19.99 fallback not needed. New decision required — see Open questions below.
  • Wolf sprite source — done. No wolf in the bundle anywhere. Need a custom commission, a CC0 sprite, or a Ventilatore find. New decision required — see Open questions below.
  • Grave marker source — done. Retro Graveyard 16x16 Tileset [Kingdom Explorer] confirmed in Tier 3, full graveyard suite. Direct use, no custom work.
  • License compilation — maintain credits string for every pack used (ElvGames + Ventilatore + Kingdom Explorer + any others). Display in game's credits screen. Confirm specific terms per pack before any commercial release.

Design topics still open

Resolved: wall material strategy. Lock = custom-author wood + stone walls (option b). Player builds wood-cabin walls from day one (corner/T/cap variants authored on top of FG_Houses.png wood-and-blue-roof material, ~½ day work) then upgrades to stone fortress walls later (FG_Fortress.png autotile-solvable as-is, ~few hours). Phase 5 slips ~3 days but the Stardew-cabin-warmth aesthetic survives, which was the original anchor. See docs/art.md Wall-material decision.

  • Wolf sprite acquisition (NEW from 2026-05-10 audit): bundle has nothing canine-predator; Ventilatore checked 2026-05-10, also nothing (Ventilatore is character + terrain + decoration; no animal/creature sprites at all besides player + slimes). Remaining options: (a) commission a 16×16 wolf (idle + 24-frame walk × 4 directions; ~$3060 paid commission); (b) source a CC0 wolf from OpenGameArt; (c) reskin a bundle animal placeholder for MVP (e.g. recolor a dog from Animal Sprites Pixelart) and replace later. Phase 10 blocker — can defer until then; placeholder from option (c) unblocks the combat/AI work meanwhile.
  • Auto-roof big-room UX: the ≤8-cell BFS cap silently fails on rooms larger than 8×8. Decide whether to (a) keep the cap and surface "this area is too large to roof — split with an interior wall" hint when the player encloses one, (b) bump the cap to ~16 with the same hint at the new threshold, or (c) detect any enclosed area regardless of size. Affects EnclosureDetector + a new room-feedback UI.
  • Onboarding / first 60 seconds: mobile-specific. Don't copy Rimworld's tutorial.
  • Touch UI for non-priority screens: world view, build drawer, alerts, day-summary, pawn detail. See docs/ui.md "Screens still to design."
  • Background time / "while you were away" mechanic — locked to no background simulation in MVP; revisit if it feels bad in playtest.
  • Audio direction — who/where for SFX + ambient track? Bundle has 11 music + 8 SFX packs covering most needs.
  • Steam Deck input parity — gamepad-driven cursor, or full menu navigation by D-pad? Probably both.
  • Localization stance — English-only for MVP, but architect strings for i18n (already locked in CLAUDE.md).
  • Pawn name/backstory generation — hand-curated list vs simple generator.
  • Naming the game — "rimlike" is a working title.
  • Monetization stance — free? PWYW? Premium?
  • Tech / research progression — medieval tech tree shape.
  • Map / world generation — fixed seed for slice; procgen later.

Tunable in prototype (not real "open Qs", just numbers to playtest)

  • Sleep mood gradient values (+5/+0/2/5/8)
  • Wet status thresholds (25 / 60) and accumulation rates
  • Season weather weights (Spring/Summer/Autumn/Winter distributions)
  • Hit-chance bonuses (skill ×5%, range ×5%, cover 40/20%)
  • Bleed-out timer (6 in-game hours)
  • Various mood thought magnitudes and decay times

Vertical slice (MVP target)

Same scope as locked in ~/claude/ideas/rimlike/plan.md. Realistic timeline 36 months solo for an MVP this rich.

  • 1 biome (temperate forest, ElvGames Forest Tileset 4 Seasons; Ventilatore foliage accents).
  • 1 map, 80×80 tiles, fixed seed for now.
  • 3 starting pawns ("settlers" / "villagers"), each with name + portrait + one-sentence backstory.
  • Verbs: chop wood, mine stone & ore, build walls/floors/furniture/crates, plant/harvest crops (34 types), cook meals (recipes), haul, repair, clean.
  • Needs: hunger, sleep, mood (~13 distinct thoughts, soft breaks at sustained mood < 25).
  • Status effects: Hungry, Tired, Bleeding, Sick, Downed, Wet (Damp/Soaked), Cold.
  • Storage: floor zones AND containers, 16 filter chips, 5 priorities.
  • Quality system on all crafted items.
  • Lighting — torches + hearths emit light; visual darkness at night.
  • Rooms — auto-detected, named by contents, beauty + dirtiness scored.
  • Cleaning as 8th work category.
  • Day/night cycle, ~5 min per day at default speed. Seasons (Spring/Summer/Autumn/Winter, 12 days each).
  • Weather: Clear / Rain / Storm / Cold snap.
  • One disaster type: wolves at night (bandit raids deferred).
  • One storyteller: random quiet/threat alternation, 25 prompt corpus.
  • Save/load, autosave on suspend, single slot.
  • Touch UI end-to-end (no desktop-only gestures).
  • Sound: minimal — UI clicks, ambient day/night loop, alert sting.

Session log

2026-05-10

  • Promoted from ~/claude/ideas/rimlike/ (single multi-hour brainstorm session).
  • Scaffolded projects/rimlike/ from _templates/project/. Customized CLAUDE.md. Distilled plan.md into this memory.md. Moved companion files (design / architecture / ui / art) into docs/. git init, first commit "Initial scaffold". Created Forgejo repo rimlike (private), set HTTPS remote, pushed main. Archived idea folder to ~/claude/archive/ideas/rimlike/.
  • Wired Godot MCP Pro: .mcp.json, .claude/settings.local.json allowlist, three project-local subagents (quick-edit, researcher, gdscript-refactor). Added the MCP-Pro and tiered-delegation sections to CLAUDE.md. Editor plugin / addons/godot_mcp/ re-copy still pending Godot project scaffold.
  • Reviewed docs/ against memory.md and CLAUDE.md. Decisions made:
    • Map size bumped from 40² → 80² for the MVP slice; architecture sized to ~120² ceiling. Pawn count stays at 3 start / 6 cap (frontier feel was rejected in favor of "split-the-difference" sizing — Stardew-farm scale, not Going-Medieval scale).
    • World-view camera = pinch-zoom + drag-pan + double-tap-to-center; storyteller alerts include a Go there tap. No minimap in MVP. No follow-cam (avoids fighting the player when issuing build orders across the map).
    • Storyteller cooldown semantics: per-event AND per-category, both gates must pass (resolves the design.md vs architecture.md disagreement).
    • MAX_STACKS_PER_THOUGHT = 5 (was named-but-unset).
    • Hauling-loop fallback: items that fail to find any valid destination after 3 retry passes drop on the floor and surface as a passive "No stockpile accepts X" alert.
  • Cleaned up doc rot in docs/design.md and docs/architecture.md — both had stale "8 work categories" intermediate sections still next to the canonical "9" lists. Removed the (8) snapshots.
  • 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.
  • Project location moved from /home/megaproxy/claude/projects/rimlike/ to /mnt/d/godot/rimlike/ (D: drive). Symlink at the original WSL path preserves the home-CLAUDE.md layout convention. Set git config core.filemode false to silence DrvFs's everything-is-0777 false-positive. Mirrors tavernkeep's pattern; both WSL and Windows access without crossing the WSL net bridge.
  • Phase 0 scaffold landed. project.godot + 7 autoloads + smoke-test scene + addons re-copy + folder layout. Used GL Compatibility renderer (not Forward+) for max mobile reach. Folder layout matches tavernkeep (autoload/ at root, scripts co-located in scenes/) — not the scripts/autoloads/ mirror layout originally sketched in implementation.md. Headless verification: godot --headless --path . --quit exits 0 with the smoke-test message. Editor-side green-dot check pending — needs you to open the editor once.
  • Asset audit ran via researcher subagent (Haiku). 3 of 5 items closed. Findings:
    • FG_Fortress.png autotile-solvable (tan stone). FG_Houses.png NOT autotile-solvable (pre-built decorative compositions). Iconic Homestead fallback not needed. Opens a new wall-material decision (see Open questions).
    • No wolf sprite anywhere in the bundle. Opens a wolf-acquisition decision (see Open questions).
    • Retro Graveyard 16x16 Tileset [Kingdom Explorer] confirmed in Tier 3 — full graveyard suite, ready for direct use in Phase 14.

2026-05-11

  • Phases 111 all shipped between 2026-05-10 and 2026-05-11 (the in-context session log lagged behind the commits). See docs/implementation.md Status table for canonical phase-by-phase state; below is just the headline.

  • Phase 9 (Status + Medicine) + Phase 10 (Combat + Wolves) shipped as the "drama pair" via 3-agent fan-out (Agent A: HP/Status on pawn, Agent B: DoctorProvider + medical bed + Rescue/Treat toils, Agent C: Wolf entity + WolfSpawner). Opus integrated into scenes/world/world.tscn + world.gd (middle bed at (47,24) marked is_medical=true).

  • MCP runtime verified both phases. Phase 9: injected 75 dmg + Bleeding(2) into Bram → went Downed (hp 25) → Edda+Cora both volunteered doctor → 'Rescue Bram → bed at (47, 24)' → treated → Bram healed to 94.2 hp, statuses cleared, returned to work. Phase 10: [wolf] RAID: 1 wolf(ves) spawned at [(53, 2)] fired at day 3 22:00 (darkness ≥ 0.8); 4 wolves alive across raid cycles by day 4 01:51. Screenshot confirms medical-bed red-cross marker and wolf silhouettes at night.

  • Phase 10 deliberately partial — wolf-side combat (two-roll, bleed on hit) shipped, but pawn-side weapons/armor/cover/friendly-fire deferred. Acceptance demo's full chain (wolf → bites → pawn bleeds → doctor saves) awaits player weapons. WolfSpawner pack size 12 vs design target 14 — tune up post Phase 20 numbers pass.

  • Bleed-out timer shipped at demo value BLEED_OUT_TICKS = 1200 (~ minutes) instead of design value 432000 (6 in-game hours). Documented in status_catalog.gd; flip on first time-balance pass. Recorded so it doesn't ship to a release at the demo value.

  • Bed-claim bug noticed in passing during ULTRA-speed run: Bram bed claim failed at /root/Main/World/Bed — sleeping on floor for two of three pawns even when beds free. Doesn't gate Phase 12; logged for separate triage.

  • Phase 12 (Seasons + Weather) shipped same day. Three-agent fan-out (Agent A = clock seasons + season top-bar + terrain palette; Agent B = Weather autoload + procedural rain overlay + storm flash; Agent C = Wet/Cold statuses + mood thoughts + shelter check). Opus prepped contracts up front (event_bus signals, Clock season constants, Weather autoload stub) so all three could run fully parallel.

  • Pre-fan-out contract pattern was the key. By writing the public API surface to disk before dispatching agents, each agent's slice compiled standalone and integrated on first try. Worth repeating for any future "multi-system phase" — pay the 5-minute scaffolding cost, save the round-trip merge fixup.

  • One quick-edit fixup needed: Variant inference errors on var old_sev := s.severity (untyped Array loop var). Same trap as the Phase 7 crop fix. Pattern: always explicit-type any := declaration assigned from a non-typed-Array element.

  • MCP runtime verified all paths. Top-bar shows "Spring 1/12", rain droplets render across screen, storm white-flash caught mid-animation, wet status flipped 0→Damp(26)→Soaked(65) with mood thought sync, cold status fired on cold_snap with -4 mood. _is_sheltered() proxy (has floor) works for v1; Phase 13 Room BFS replaces it.

  • Next: Phase 13 (Rooms, roofing, beauty, dirtiness, cleaning) is the natural follow-up — it pays the _is_sheltered() debt and unlocks beauty/dirty mood thoughts.

  • Phase 13 (Rooms + Beauty + Dirtiness + Cleaning) shipped same day. Three-agent fan-out reusing the Phase 12 contracts-first pattern (Room class, World.rooms/room_at_tile/is_indoor, 4 EventBus signals pre-written by Opus before dispatch).

  • DECISION: Big-room UX = bump cap to 16, banner above. Auto-roof activates for rooms ≤16 interior tiles; rooms above that emit room_too_large with no roof. Cabin (24 tiles) intentionally exceeds cap so the warning path is exercised at boot. Test shed (3×3 = 9 tiles) exercises the roof path.

  • Agent C wiring loss + recovery. Agent C reported wiring BeautySystem / DirtinessSystem / CleaningProvider / IndoorTintOverlay into world.gd but the instantiation code never landed — only the autoload field declarations and the entity-side register_furniture hooks survived. Opus added the missing 4 instantiations + work-provider registration + pre-built furniture seed in a follow-up edit. Recovery time ~5 min via runtime probe. Pattern: trust but verify agent reports against actual file state, especially for "I wired this into the scene/autoload" claims. Don't repeat by asking for "show me the diff" alongside the report.

  • Demo seed extended. Added _prestamp_test_shed_for_room_detector + _spawn_complete_wall / _spawn_complete_floor helpers — instantiates entities in completed state for a 5×5 walled shed at (34, 23). Demonstrates the auto-roof path side-by-side with the cabin's over-cap path.

  • Sheltering proxy debt paid. Pawn._is_sheltered() now reads World.is_indoor(tile) first, falling back to the floor-has-cell proxy for graceful degradation while RoomDetector populates.

  • Phase 10 wolves' raid cooldown is set to 4800 ticks (1 in-game day). Combined with darkness_factor ≥ 0.8 trigger gate, wolves continue to spawn nightly. No tuning required this phase.

  • Next: Phase 14 (Death + corpses + burial) — closes the death loop. Pairs naturally with Phase 13's DirtinessSystem.bump() API for combat-blood spikes.

  • Phase 14 (Death + corpses + burial) shipped same day. Three-agent fan-out (A: death+corpse spawn, B: graveyard+grave_slot+marker+haul, C: cremation pyre+ash+4 mood thoughts). Opus pre-wrote Corpse class with setup()/save round-trip + 5 EventBus signals + World.corpses/grave_markers registries before dispatch. Pattern proven for the third time — this is the way.

  • Bleed-out timeout shipped at design value (BLEED_OUT_TICKS = 432000 = 6 in-game hours at 20 Hz). Previous memory entry's claim of "demo value 1200" was based on a misread; the constant has been at the design value since Phase 9 status_catalog.gd landed.

  • Throughput tuning surfaced as a real concern. At ULTRA speed (12×), corpses decay (DECAY_PER_TICK=0.05) hit the 100-rotted threshold before HaulingProvider's priority-3 corpse-haul scheduling could chain pawn→pickup→graveyard. Pipeline is correct; numbers need a Phase 20 pass. Workaround for testing: pause + manual job assignment, or boost corpse-haul to priority 4+.

  • recipe.gd extended with ingredient2_type/count for the cremation recipe (1 corpse + 5 wood). CraftingProvider's pickup step still only enforces ingredient1 — documented gap. Cremation pyre works as a corpse-only recipe today.

  • HaulingProvider corpse path uses Node metadata (set_meta on the carrying pawn) to track the carried corpse. Agent B did this to keep Corpse class (Agent A's territory) untouched. If a proper Pawn.carrying_corpse field lands later, replace the metadata.

  • MCP runtime verified: DEMO_PHASE14_AUTOKILL toggle force-kills first pawn at tick 50 — Bram DIED → corpse spawned → Cora's saw_corpse (-3) thought fired. Grave dig + designation paint chain verified to completion. Bleed-out + Wet status overlap firing correctly during ULTRA runs. Screenshot shows fresh corpse silhouette at cabin doorway.

  • Next: Phase 15 (Storyteller) — the world prods the player. 25-event registry, daily 6 AM roll, per-event + per-category cooldowns (both gates locked), banner/modal UI, ghost-state recovery.

  • Phase 15 (Storyteller) shipped same day. Three-agent fan-out (A: EventCatalog with all 25 events authored from design.md, B: Storyteller autoload daily roll + cooldowns + tension + ghost state, C: BannerUI + ModalUI + go-there pan). Opus pre-wrote EventDef class + 5 EventBus signals + Storyteller autoload stub before dispatch. Contracts-first pattern proven for the 4th time.

  • Code-as-data choice for events. EventCatalog is GDScript factories rather than .tres resources. Trade-off: faster iteration in MVP (no Inspector dance, no resource UID drift), but .tres is on the table for Phase 17 if hot-reload becomes a workflow need.

  • MCP runtime verified across two boots (different daily rolls per boot — RNG fresh per session):

    • Boot 1: lone_wolf THREAT → modal "A starving wolf circles your livestock." with Prepare/Dismiss buttons + sim auto-paused. Resolve → tension bumped 27→42, sim resumed.
    • Boot 2: an_old_map LORE → top-center banner, non-blocking, 6-sec auto-dismiss.
  • Quick-edit fixup mid-flight: modal didn't auto-hide when Storyteller.resolve_current was called externally (only on internal button click). Added a storyteller_event_resolved subscriber to the modal — one method. Phase 17 polish will sweep similar UX gaps.

  • Wolf-spawn integration deferred to Phase 17 — Agent A noted EventBus.request_wolf_spawn(count) signal not yet declared; threat events that spawn wolves currently log-stub. Pattern recorded: when a Phase-N agent surfaces a missing cross-Phase signal, declare it on EventBus in the next contracts-prep pass rather than spreading the fix across agents.

  • All categories used in the 25-event corpus: nudge×4, seasonal×4, wanderer×4, threat×4, disease×3, resource×3, lore×2, milestone×1. Total cooldowns lock the per-day pool to roughly 3-6 eligible events on a typical day.

  • Next: Phase 16 (Save/load full coverage) — pays the partial-save debt accumulated since Phase 3. All entity types (pawn, item, furniture, container, corpse, wolf, plant, grave_marker), TileMap layers via get_used_cells_by_id, Storyteller state round-trip, Bill mid-fetch states. Phase 16 is the integration phase — fewer new files, more save-seam plumbing.

  • Phase 16 (Save/load full coverage) shipped same day. Three-agent fan-out (A: class_id tagging + missing to_dict/from_dict on 6 entities + tilemap helpers + beauty/dirt map serialization; B: SaveSystem v2 rewrite with per-class factory registry + clear-and-respawn apply_save + slot API; C: Autosave autoload + Save/Load TopBar buttons + LoadMenu + ResumeToast). Opus pre-wrote World.clear_all + 4 EventBus signals before dispatch. Pattern proven for the 5th time.

  • User explicitly wanted autosave + manual save/load UI — both shipped: Save (💾) + Load buttons in TopBar; Load opens slot picker; Autosave fires periodically (every 6000 ticks = ~5 in-game min) and on app pause / focus loss.

  • clear-and-respawn pattern works. World.clear_all() wipes all entity registries + queue_frees the Nodes; SaveSystem.apply_save then iterates payload.entities and dispatches to per-class factories. Verified: 113 entities saved at tick 1137, sim advanced to tick 4600 at ULTRA, load restored tick=1137 + all 3 pawns + all furniture in correct positions with 0 errors. Round-trip clean.

  • Wolf target re-resolution — wolf.from_dict stores target_pawn as a name string; Agent A's note says Agent B's apply_save should re-resolve names against World.pawns after all pawns are restored. Verify on next save-load cycle.

  • Save version bumped to 2. v1→v2 mismatch shows a warning dialog in LoadMenu; player can continue or cancel. Future bumps follow the same pattern.

  • Known acceptable gaps: Pawn JobRunner mid-INTERACT/mid-BUILD restarts from toil 0 on reload (walk toil round-trips; multi-step interact does not). Workbench bill mid-craft fetch state isn't fully serialized. Both are tolerable — pawns just redo a few seconds of work. Document as Phase 20 tuning.

  • Three new autoloads now: Autosave (Phase 16) + Storyteller (Phase 15) + Weather (Phase 12). All registered in project.godot in dependency order (Sim/Clock first, then Weather/Storyteller/Autosave).

  • Next: Phase 17 (Touch UX completion). The biggest deferred-polish bucket — work-priority matrix UI, bills UI, alerts log, pawn detail panel, build drawer, settings menu, all the touch-first interaction layer that's been stubbed. Several Phase 14/15 effects (wanderer recruit, resource buffs, wolf-spawn signal) wire in here too.

  • Phase 17 (Touch UX completion, MVP-cut) shipped same day. Three-agent fan-out: A = PawnDetailPanel + SettingsMenu, B = BuildDrawer (with 12 new Designation tools), C = WorkPriorityMatrix + AlertsLog + Decision Layer 4 per-pawn priority refactor + EventBus.request_wolf_spawn wiring. Opus pre-wrote 6 EventBus signals + Pawn.work_priorities Dictionary stub before dispatch. Pattern proven for the 6th time.

  • TopBar now has 10 buttons: ‖ / 1× / 5× / 12× / Save / Load / Settings / Build / Work / Log[N]. + a floating ⊕ FAB at bottom-right (BuildDrawer quick-open). Crowded but functional; mobile-polish pass can group under a hamburger.

  • Decision Layer 4 refactor. Pawn.work_priorities (Dict cat→int 0..4, 0=OFF, default 3=NORMAL) is now respected. Needs categories (rest/eat/sleep) BYPASS the filter so a pawn can't accidentally starve from misconfiguration. Doctor IS in the matrix (players can opt a pawn out of doctor duty). Audit log now prefixes work decisions with (pri=N).

  • Mouse drag-paint works as-is. User specifically asked about this. Existing Selection + Designation tools read _unhandled_input events for mouse motion + button-held state, so drag-painting walls/floors/designations works in the editor without further work.

  • Pattern proven 6th time: "pre-write contracts to disk before fan-out". This session has been a single 1-day sprint shipping 6 phases (12 through 17) end-to-end via this pattern. Cost discipline: every phase = 3 Sonnet agents in parallel + Opus pre-write contracts + Opus integration + Opus MCP runtime verify.

  • MCP runtime verified all 4 new UI surfaces: Bram's detail panel shows Crafting=8 / Cooking=2 / Manual=0 matching seed; BuildDrawer Designate tab shows 4 tools with procedural icons; WorkPriorityMatrix shows 3 pawns × 8 categories grid with default "3" cells; AlertsLog shows 4 entries with mixed severity icons + "Spring Awakens" from the boot storyteller roll.

  • Deferred to Phase 17.5 polish pass: Per-pawn/per-job view layers, stockpile 4×4 chip grid, Bill UI, "no stockpile accepts X" / "bill blocked" emit wiring, DaySummaryCard visual.

  • Next: Phase 18 (Audio). Music + SFX + ambient + volume sliders + mute-on-suspend. Smaller scope than 17 — 1 week target. ElvGames + Ventilatore bundles include music/SFX packs we can source from.

2026-05-12

  • PC controls patch shipped (out-of-phase, for desktop testing + Steam Deck prep). New input actions: WASD/arrow pan, =/- zoom, C/Home center, Tab/Shift+Tab pawn cycle, B/L/P/, panel toggles, Escape priority stack (cancel tool → close topmost panel → deselect pawn), right-click cancel/deselect (RTS convention). F is the new speed_cycle binding (handler still TODO). Touch paths untouched. Commit 0b2e0fc.

  • Pattern note: pawn cycling Shift+Tab. First attempt used Input.is_key_pressed(KEY_SHIFT) to detect modifier on pawn_next action — this works with real keyboard but fails for MCP synthetic input (the singleton keystate isn't updated by injected events). Fix: read event.shift_pressed on the InputEventKey directly. More reliable AND works in tests. Use event.<modifier>_pressed, not Input.is_key_pressed(KEY_*), when reading modifiers tied to a specific key event.

  • Latent pre-Phase-17 bug surfaced and fixed in same commit. WorkPriorityMatrix, AlertsLog, StorytellerModal, LoadMenu, SettingsMenu all had MOUSE_FILTER_STOP Backdrop/Dim Controls that stayed input-active when the panel was "closed". Their open/close only toggled _root.visible / _panel.visible — never CanvasLayer.visible (self). World mouse events (right-click deselect, left-click pawn-select) silently eaten. Each _set_visible/open/close now toggles self.visible so input dispatch shuts off. Why it went undetected since Phase 17: Tab-select and direct script invocation bypass _unhandled_input; the runtime verify in Phase 17 used those paths. First proper mouse-world test (this session) exposed it.

  • Pattern recorded: for any CanvasLayer-based UI panel with full-screen backdrop, always toggle self.visible (CanvasLayer) in addition to inner Control visibility, OR use mouse_filter=PASS on the backdrop. Apply when adding future modals.

  • Delegation report: PC controls drafted by gdscript-refactor (Sonnet, 2 dispatches — spec implementation + polish pass). Backdrop-bug discovery + fix done on Opus during MCP runtime verification (already in context). Headless + runtime verify all green.

  • Visual sprite upgrade pass (play → fix → play loop). Three procedural draws replaced with ElvGames atlas sprites this session:

    • Walls — stone-fill was at FG_Fortress (1,1), which is a tan stone floor tile (no brick texture, no cap). Swapped to (13,4) — middle column of a 3-tile-wide capped autotile, used as a non-autotile single sprite. Reads as a proper brick wall with a depth cap. Commit before context summary.
    • Items on ground — five most-spawned types (stone, iron_ore, gold, wood, plank) now render from FG_Abandoned_Mines coords with a quality border + stack-count badge composited on top in _draw(). Other types still use the original hue-hashed square fallback. Commit 7274ada.
    • Doors — first attempt used FG_Fortress 32×32 closed-gate at (4,19); user rejected as "a door for a entrance to a castle" (commit ac21443). Pivoted to FG_Village (3, 24), a 1-tile-wide olive-wood cabin door with U-handle extracted from the red-roofed cottage template. Commit 745ab29. FG_Village.png copied into art/tiles/.
  • Tileset survey notes (for future visual passes). FG_Fortress = ALL doors are 2-tile-wide castle gates. FG_Houses = component-style 2-wide doors (cottage but still big). FG_Village = full-house templates with 1-tile-wide cabin doors baked into the bottom row (the one we used) — good source for residential furniture, signs, windows. FG_Interior = wardrobes/dressers/wallpaper, no standalone door entities. FG_Marketplace = no doors at all.

  • MCP execute_game_script quirk: scripts with 3+ statements fail Parse error. Workaround: pack with ; or use for x in y: a; b; c (compound for-body line). Affected this session's visual probes.

  • Pattern recorded: when copying a new texture into art/tiles/, run /mnt/d/godot/Godot_v4.6.2-stable_win64.exe --editor --headless --quit to force generation of the .import file before any scene can preload() it. Skipping this step yields a silent null preload at runtime.

  • Delegation report this session: No delegation — handled on Opus for sprite-atlas surveys, GDScript refactors, MCP runtime verification. Pure visual / MCP-tool work; subagents would have re-read the same files repeatedly.

2026-05-15

  • Bug-triage patch shipped out-of-phase, before Phase 18 (Audio) starts. Same pattern as the 2026-05-12 PC-controls patch. Three playtest-reported bugs investigated, root-caused, fixed, and MCP-runtime-verified end-to-end. See Known bugs / triage backlog above for per-bug detail.

  • Pattern recorded — "pre-built seed masks downstream wiring gaps". Five entity types (Torch / Bed / Crate / Workbench / CremationPyre) had been missing World.register_build_site(self) since Phase 17 landed. Nobody noticed because the cabin demo seed calls _spawn_complete_* helpers (insta-builds via direct on_build_tick loop), so no player ever painted a fresh furniture designation. Lesson: when adding a new entity type to a build-queue iterating system, always playtest the FRESH-PAINT path, not just the pre-built seed.

  • Pattern recorded — "pathfinder mutation can strand walking pawns". When set_cell_walkable(false) fires, pawns already mid-walk on a path through that cell will keep stepping along the stale path and land on the now-impassable tile. AStarGrid2D requires walkable START, so the pawn idles forever. Defense-in-depth fix: Wall._complete dislodges-on-tile + Pawn._advance_walk re-checks walkability before stepping. Generalises to any future system that mutates pathfinder walkability (e.g. doors, big_rock, future fortifications).

  • Pattern recorded — "Y-sort equal-Y ambiguity". Two entities at same Y-sort root with same position.y fall back to scene-tree order, which is fragile. Always set distinct Y-positions for distinct visual layers (ground vs. above-ground). Ground-tier entities use top-of-tile anchor; above-ground entities use bottom-of-tile anchor (Wall/Bed/Torch/Workbench pattern). Pawn at mid-tile sits cleanly between.

  • Delegation report: researcher (Haiku, 1 dispatch) mapped three bug surfaces (~600 word digest with file:line citations). All fixes + MCP runtime verification handled on Opus — fix sites were already in context from the researcher report, so re-dispatching to Sonnet would have been pure overhead.

  • Job system audit + designation-gate fix shipped same day in the same bug-triage patch session. Player report: "I set some trees to be cut but no one is doing it". Root cause via researcher (Haiku, 1 dispatch, ~900 word digest mapping all 11 WorkProviders): ChopProvider and MineProvider iterated World.trees / World.rocks unconditionally — is_choppable() / is_mineable() only check progress, not designation. The &"chop" and &"mine" cases in world.gd._on_designation_added stashed a null sentinel and never touched the entity, so paint was purely cosmetic. Pawns were auto-chopping the nearest unfelled tree regardless of what the player painted.

  • Fix: added chop_designated: bool to Tree, mine_designated: bool to Rock + BigRock (BigRock flag covers entire 2×2 footprint via footprint_tiles() membership check), gated both providers, wired designation paint/cancel to flip the flag, auto-designated SAMPLE_TREES / SAMPLE_ROCKS / SAMPLE_BIG_ROCKS at boot so the demo still runs end-to-end. Rimworld parity restored — pawns no longer auto-chop / auto-mine.

  • Also from same audit: added reachability pre-checks (mirroring HaulingProvider) to DoctorProvider and EatProvider — they were issuing jobs to unreachable targets, then relying on JobRunner walk-cancel to clean up. The pre-check avoids the busy-spin between Decision and JobRunner.

  • Pattern recorded — "iteration-source bugs hide behind boot-seed shortcuts". The Phase 4 seed SAMPLE_TREES / SAMPLE_ROCKS was always being chopped/mined because providers auto-picked. Player only noticed when they painted designations and the behavior didn't change. Boot seeds that mirror "default OK" state can mask gate logic; when adding any new gate (designation, skill, capability), playtest the FRESH state, not just the seeded state.

  • Other audit findings (deferred, not fixed this session): CraftingProvider has an ingredient re-scan race (ingredient may disappear between lines 73 and 91); PlantProvider only handles harvest (sow stubbed for Phase 17); RestProvider is a Phase 3 smoke-test leftover that could be deprecated. All low priority.

External references

  • Forgejo repo: https://git.rdx4.com/megaproxy/rimlike (private)
  • Owned art bundle (primary): ElvGames "Ultimate Farming RPG" Humble bundle, local at /mnt/d/godot/assets/humble set new/. License: ElvGames terms (https://elv-games.itch.io/terms). Commercial OK with credit; no NFT/crypto/resale.
  • Owned art bundle (secondary): Ventilatore Fantasy Tileset Complete Bundle — https://itch.io/s/117124/the-fantasy-tileset-complete-bundle
  • Mana Seed catalog (fallback if bundle gaps surface): https://seliel-the-shaper.itch.io/
  • Iconic Homestead (autotile-ready wall fallback, $19.99): https://seliel-the-shaper.itch.io/iconic-homestead
  • Lodestars: Rimworld (Tynan Sylvester / Ludeon Studios), Going Medieval (Foxy Voxel), Stardew Valley (ConcernedApe).
  • Original brainstorm history: archived to ~/claude/archive/ideas/rimlike/ after promotion. The session log there captures every decision's rationale.
  • Brainstorming-mode preference: see ~/.claude/projects/-home-megaproxy-claude-ideas/memory/brainstorm-ask-dont-decide.md (not directly applicable to projects but captures interaction style).