G: large_text scales global theme font (14→20 at 1.4×) via new
GameState.get_font_scale + EventBus.settings_changed. reduce_motion
gates ResumeToast fade (HintOverlay already gated).
I: InspectTooltip long-press wired (500ms hold, 12px drift cancel,
tap-to-clear pin). Stale Phase 19 TODO replaced with accurate doc.
H: Pawn.arrived_at_destination now also emitted on
EventBus.pawn_arrived_at_destination; DirtinessSystem subscribes and
bumps indoor traffic dirt (BUMP_INDOOR_TRAFFIC = 0.2). Outdoor-tracked
bump needs Pawn.prev_tile — flagged for Phase 20.
P: CraftingProvider caches ingredient item ref on Job.ingredient_item;
JobRunner._tick_pickup validates is_instance_valid + not being_carried
before the tile scan, cancels cleanly if another pawn grabbed it.
J: rest_provider.gd deleted. Removed @onready + register call from
world.gd, ext_resource + node from world.tscn. Provider count comment
updated to 9.
M: DIRTY_THRESHOLD extracted — cleaning_provider and job_runner now
reference DirtinessSystem.DIRT_DIRTY_THRESHOLD.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Trees: 4 growth stages (Sapling→Young→Growing→Mature), only Mature
yields wood. WildGrowth ticker fires every in-game hour; rejection-
samples grass tiles and plants a sapling with ~30% probability (capped
at MAP_TREE_LIMIT=60). New `paint_plant_tree` designation lets the
player manually plant — ghost sapling registered as a build_site that
ConstructionProvider fulfils. Stage round-trips through save/load.
Initial seed mixes 4 saplings + 6 mature so growth is visible day 1.
Quarry: new BigRockNode entity (2×2 permanent stone outcrop, never
depletes). 3 nodes seeded far from cabin. New QuarryWorkbench
(extends Workbench, auto-FOREVER `quarry_stone` bill, recipe drops
1 stone per 300 work-ticks). New `paint_quarry` designation only
accepts BigRockNode tiles. CraftingProvider now supports recipes
with `ingredient_count == 0` — skips ingredient-fetch and goes
straight to walk+craft toils. Recipe gains `ingredient_count` field
(defaults 0). Save/load layering: big_rock_node spawns at priority 0
(same as rock/tree), quarry_workbench at priority 2 (after the node).
UI: Plant tree + Build quarry buttons added to Build drawer.
build_drawer_thumb gains `plant_tree` (sapling sprout in dirt) and
`paint_quarry` (stone block + chisel + cut-stone pile) shapes.
inspect_tooltip recognises BigRockNode + shows tree growth stage on
hover.
Delegation: gdscript-refactor (Sonnet ×2) for trees full impl +
quarry skeleton; quick-edit (Haiku) for CraftingProvider no-ingredient
plumbing + TopBar polish; integration handled on Opus.
Player report: hovering trees works after the canopy fix, but crops show
nothing and beds still report "Wood floor" sometimes.
* Crops are added to the lookup, showing kind + growth stage + percent
("Wheat | sown · 98%", "Wheat | ready to harvest", "tilled — not sown").
* Bed sprite is 16×32 (two tiles tall, anchor at the foot). Hovering on
the headboard (one tile above the anchor) used to miss. Added a sprite-
canopy pass for beds mirroring the existing 4-tile tree canopy logic.
* Full layer audit and reordering. Final priority top-down:
1. Pawn / Wolf / Corpse / Grave marker — entities the player cares
about first.
2. Crop — small sprite, exact tile only.
3. Tree — trunk tile + 4-tile canopy.
4. Big rock (2×2 footprint) / Rock — exact tile / footprint.
5. Furniture at exact tile (wall / door / bed / crate / workbench /
torch).
6. Furniture sprite-canopy (currently only bed; future tall furniture
slots in here).
7. Item on the ground (loose stack).
8. Stockpile / zone region overlay.
9. Floor — only when nothing physical is on the tile.
Confirmed at runtime: bed foot → Bed; bed headboard → Bed (via canopy);
two-tiles-above-bed → empty; crop at growing stage shows percent; bare
floor still says Wood floor; furniture on wood floor wins over floor.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two playtest gaps reported:
* Hovering on a tree showed nothing — trees anchor to the trunk tile but
the canopy sprite rises ~4 tiles upward. Now any hover within the
vertical band [trunk.y - 4, trunk.y] resolves to the tree.
* Hovering inside the cabin always said "Wood floor" — both floor and
furniture register in World.build_queue, and the floor was found
first. Now we two-pass the queue: remember any floor we hit, but keep
scanning for furniture (bed / crate / workbench / torch / etc.) and
return that if found. Items on the ground also win over the bare
floor. Floor only shows when nothing else occupies the tile.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds an InspectTooltip CanvasLayer that follows the mouse, samples the
tile under the cursor each frame, and renders a small dark panel with a
short description of whatever's there.
Per-entity describers cover the playable surface:
* Pawn: name + HP + mood + current job
* Tree / rock / big rock: progress %, "marked" tag if designated
* Wall: material + ghost/% if unbuilt
* Floor / door / torch: ghost vs complete state
* Bed: occupant or "available", medical tag
* Crate: full contents broken down by item type and count
* Workbench: label + active bills count
* Item on ground: type + stack size
* Corpse: deceased name + fresh/rotting/rotted state
* Wolf: HP + state
* Grave marker: deceased name
* Stockpile / graveyard zone: name + priority + accepted types
Layer 50 so the tooltip sits above the world but below modals (which
sit at 100+). process_mode = ALWAYS so hovering still works during
storyteller modals. Position auto-flips to the other side of the cursor
when it would overflow the viewport.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>