| M1 HUD on-screen | ✅ Class badge / HP+STA bars with quartile ticks + low-pulse / clock with TOD + paused-tag / coin-iconned gold / Score+title with progress bar + past+next ticks / mini-map fog-of-war / TOD + magical-interior band tint | done 2026-06-06 |
| M2 Right-click verb coin | ✅ Radial on hotspot AND empty-world (synthetic RoomLookHotspot). Hover highlight + tooltip. | done 2026-06-06 |
| M3 Sheriff visible + talkable | ✅ LMB-on-NPC = Talk. First-Sheriff-talk awards +5 gold + +5 score + 'Met the Sheriff' achievement. | done 2026-06-06 |
| M4 Map geographic to original | ✅ 30+ SCI hotspot tables, SPIELBURG_GRID fallback, scripted exit + GoBack. | done 2026-06-06 |
| M5 Random encounters trigger | ✅ TOD-scaled chance, 8 enemy types with banner colors + Lv.N scaling, ±50cm jitter, force-spawn caves, early grace. | done 2026-06-06 |
| M6 Stats training | ✅ Guild/MagicShop/Stable/Inn room-entry training. MagicShop magic-only, Stable thief-only, with class banners. | done 2026-06-06 |
| M7 First quest live | ✅ Sheriff/Guild/Healer auto-accept + tutorial breadcrumb. FreeBarunsSon at 3 brigand kills. | done 2026-06-06 |
| M8 Save/Load menu (data + hotkeys) | ✅ Slots 1+2+3 via F5/F6 save / F7/F9 load + qfg_SaveSlot/qfg_LoadSlot execs (T928xg multi-slot coverage). Autosave silver toast every transition. Multi-slot 27_save_slot2/3 + 27_load_slot2/3 PIE assertions green. | done 2026-06-06 |
| M8 Save/Load menu (status panel) | ✅ FCanvas DrawSaveMenuPanel (T925l, QFGGameHUDActor.cpp line 8272+) with class-colored open pulse + post-save green flash + post-load crimson flash. NOT UMG by design (T917o FCanvas philosophy bypasses UMG entirely). | done 2026-06-06 |
| M8b Interactive slot picker | ✅ W42 T928aaf+aag: HighlightedSaveSlot nav (Up/Down wrap 0..2) + Tab save/load mode toggle (green/crimson highlight frame) + Enter confirm through existing slot paths. Save-menu-gated keybindings + qfg_Picker exec driver; 31-series PIE assertions; 76-assert regression green. FCanvas per T917o philosophy. | done 2026-06-10 |
| M9 Combat HUD overlay | ✅ Panels+wheel: T928xm corner parchment scrolls (Hero HP/SP/MP + Enemy HP, enemy-nearby gated, canonical S1) + T928abe action wheel (6 stances on a ring, selection highlight, qfg_CombatAction driver) with deterministic parry-branch coverage via qfg_EnemyAttackN weak volley (36-series green, run 30 attempt-1). T928abg completes R1.c: combat-gated arrows (Up=Attack Down=Dodge Left=Parry Right=Cast, 1500cm gate mirrors the overlay) through the menu-priority multiplex (main menu > char-create > picker > combat); also wired the Wanted-Hero menu's Up/Down/Enter (T928aax gap). | done 2026-06-11 |
| M10 Main menu + character creation flow | ✅ Core W42 T928aao..aas: qfg_CharCreate exec state machine (start/class/next/back/alloc/dealloc/name/confirm/cancel) + FCanvas ClassPick (n202) + 50-point Allocate (n203) panels + confirm pipeline (CreateFromClass + Stats/Skills alloc + active-hero swap + inventory regrant + TownGate). Milestone gate green 2026-06-11: 33-series full Magic-User creation flips MagicShop ScrollShelf ClassGate (6 spawned, 0 gated off). T928aax adds the Wanted-Hero main menu (S2): qfg_MainMenu + FCanvas poster panel, Start New Hero -> class pick, Restore -> M8b picker load-mode end-to-end (34-series green). T928abc closes the design doc: read-only character sheet (n204/S5) with stats/skills/vitals from live ActiveHero, asserted post-restore (35-series green, run 29 attempt-1 clean). Deferred (recorded): title-map auto-show (needs title map in PIE path), typed-name input (rides M12). | done 2026-06-11 |
| M11 System / settings menu | ✅ W42 T928abi: qfg_SystemMenu + FCanvas S3 panel — Save/Restore/Restart/Quit rows + DETAIL/VOLUME/SPEED slider bars (clamped, exec left/right). Save/Restore route into the M8b picker (its promised home). ESC toggle via OnEscapeKey fall-through (packaged builds; PIE eats ESC per T928jz, exec is the gate driver). Keyboard multiplex: main menu > system menu > char-create > picker > combat. 37-series green (run 32 attempt-1). Deferred (recorded): slider persistence to save file; Restart/Quit packaged wiring. | done 2026-06-11 |
| M12 Verb typing + accelerators | ✅ W42 T928abk..abp: qfg_Verb parser (R1.b vocabulary + synonyms onto EQFGVerb, narrated errors, 38-series), qfg_TypeIn T-key command strip (buffer/backspace/submit-to-parser, 39-series), 12 R1.a CTRL accelerators (combat-aware, real clock-pause on CTRL-P), SHIFT-CLICK Look via the L-key path. Three interaction surfaces (coin / chords / typing) feed one asserted dispatch core. Deferred (recorded): per-keystroke capture into the FCanvas strip (input preprocessor, packaged build), typed-name entry reuse for M10, +/-/= speed keys, SPACEBAR/F3 repeat. | done 2026-06-11 |
| M13 Castle / Baron region (data+canon) | ✅ W42 T928yg+aai..aal: 5 castle rooms live with transitions + 23 hotspots; FreeBarunsSon canonically revised (bear-restore -> BarnardRestored -> Baron audience completes with prophecy; brigand kills feed ClearBrigandFortress); court on schedule (Baron 4 TODs grief register / Barnard / WeaponMaster / StableMaster). 78-assert green incl. 32-series chain. Remaining polish: CastleAnteroom n141 split from CastleDoor if canon demands; scene-art pass rides the global background track. | data+canon done 2026-06-10 |
| M14 Mage's Maze minigame | ✅ W42 T928abq..abw: UQFGMazeGameSubsystem (deterministic by construction: fixed 12x8 board, BFS E/S/W/N tie-break, 2:1 tick ratio, rotation-list boulder respawns) + all four R1.d spells with MP/cooldown economy + eat rule + FCanvas board (creatures, MP/spell bars, outcome banner) + ErasmusHouse WizardGame hotspot (ClassGate=Mage, Maze_Start dispatcher) + first-win QuestFlag_WonWizardGame +5 score. 40/41/42-series green (runs 38-43): blocked-board proof, scripted Open+Fetch WIN, ClassGate both ways, board-starts-maze. LESSON: ClassGate vocab is Fighter/Mage/Thief — distinct from ClassID's MagicUser. Deferred (recorded): same-size mutual attraction, random layouts, spell-knowledge gating, real mana spend, art. | done 2026-06-11 |
| M15 Dag-Nab-It minigame | ✅ W42 T928aby..acb: ThievesGuild room (SCI rm332, 101st room, TownSquare alley entry + 4 SCI hotspots) + UQFGDagNabItSubsystem (turn-based, zero RNG: ring score = pure function of dev from the 70/50 sweet spot; 9 throws; Throwing practice per dagger; champion >=150 -> first-time QuestFlag_DagNabItChampion +5) + FCanvas board (deviation-true ring geometry, hit dot, tally, champion banner) + DagBoard Use -> DagNabIt_Start dispatcher. 43/44/45-series green (runs 44-46), exact-tally asserts incl. the hand-computed 150-on-the-nose champion run. Deferred (recorded): opponent thieves/wagers, perfect-450 achievement, canon tavern+password entry, board art. | done 2026-06-11 |
| M16 Survival loop (hunger core) | ✅ W42 T928zq..aac: HungerLevel (saved) + 3-meal TOD cadence + meal economy (inn meal -3s +5HP/+25SP, room -5s + flag + door unlock, sleep full restore, Erana fruit, qfg_Eat ration from UQFGInventoryComponent) + starvation penalties (regen block + -5 SP/missed meal, never lethal). 74-assert PIE green with end-to-end 'ate a ration' proof. T928ach adds carry capacity (canon: from Strength; instance-count cap at the unified facade's AddItem, kits exempt, 47-series green; per-item weights deferred). T928acj closes the siblings: currency split (Stats.Silver 0..9 normalized, facade AddSilver/SpendSilver sole mutators, SpendGold at 10:1; FIXED a 10x canon overcharge -- the inn logged silver but deducted gold; 48-series green incl. live inn meal). M16 COMPLETE. | done 2026-06-11 |
| M17 Scripted room hotspots | ✅ First release W42 (T928xq..yy): DT_RoomHotspots (130 rows / 30 rooms, canon-cited per LP audit) + UQFGRoomHotspotManager world subsystem (spawn/despawn on room change, lazy uasset load + allowlist reimport) + LookText on every hotspot + RewardScript dispatcher (RoomEnter_* transitions / Shop_Open* price lists / Talk_* NPC dialogue / survival stubs) + ClassGate+QuestGate spawn enforcement. PIE-gated: 28-series assertions (table load / spawn count / exec count / gating), 70 total. First PIE run green 2026-06-10 attempt 2; found+fixed CSV comma row-drop (LESSONS_LEARNED). | done 2026-06-10 |
| M18 Economy + puzzle layer (read-only sweep) | ✅ W42 T928aec..aee: one question — "which tables only run their read path?" — converted seven dead systems to play. Commerce (qfg_Buy/BuyHaggled/Sell vs Zara: stock + capacity-before-payment + SpendSilver + haggle floor via DT_MerchantHaggle steps), loot (HandleDeath rolls DT_LootTables, deterministic 100%-drop Brigand/Rations proof row), crafting (qfg_Craft: DT_Recipes Intelligence-gated, ingredient consume, fail-first branch), puzzles (qfg_SolvePuzzle: DT_PuzzleSolutions room/item/class/skill gates; success sets QuestFlag_Solved_<ID> +2 score — puzzles are now flag PRODUCERS for the unified gate evaluator; Gold offerings route as 10-silver wealth gates). Six real bugs found+fixed en route (born-over-capacity kit gold, double-gold kill grant, free rented room, inn 10x overcharge, coins-as-cargo, RequiresFlag unenforced). 67-72 assert series, runs 78-86, merged green. Deferred (recorded): stock decrement, crafting station gates, per-item weights. | done 2026-06-11 |
| M19 Gate-producer arc (tripwire + debt burn) | ✅ W42 T928aej..aet: validate_csvs gained a cross-table tripwire — every gate flag must have a producer (C++ literal / SetFlag_ row / pseudo-flag / Solved_ puzzle). First run found 15 producer-less gates = unreachable canon content; a shrink-only known_debt ratchet grandfathered them, then 13 burned in 12 PIE runs (87-98, every merge attempt-1 green except one honest red that hardened the harness). Shipped en route: 3 GENERIC producer families (Killed_<EnemyId> on HandleDeath; HasItem_/HasItems_ live-inventory pseudo-flags; SecondVisit_<Room> via persisted visit counters) + real spellcasting (CastSpell stub retired: skill/mana gates, Detect Magic reveal, scroll-teaches-spell) + player content: Kobold key chain + trapped chest, Bruno's key, Healer steal-ban, the COMPLETE dispel-potion chain (Dryad seed/acorn/recipe → Flying Falls → cauldron brew via HasItems_, self-retiring hotspot), skull-gate gem trade + hut rhyme, Henry hospitality + Trigger learn-path, stable job, trapped-fox Elsa lore. Infra: per-run PIE screenshots untracked (20MB packs broke pushes chronically). Remaining debt: Yorick pair ONLY (awaits Shaun's n093-097 fortress ruling). Recorded source ticks: Brauggi's gem, Spirea seed, fairy dust, Erana flowers, meep fur, BabaYagaHut interior. | done 2026-06-12 |
| M20 Canon content arc (quest chains earned) | ✅ W42 T928aev..afb: every remaining driver-grant in the quest space converted to earned play. Brauggi's bargain (5 apple sacks from Hilde's cart -> Jotunheim gem; sacks solve the 50-apples-vs-carry-cap collision canonically), night fairies (IsNight pseudo-flag's first content proof; dance gifts the dust), Erana's Peace (flower flask + stone teaches Calm via REAL Open cast) + meeps (green fur + Detect Magic scroll), the spore-spitting spirea (hostile-flora ambush, deterministic seed drop -- dispel chain 100% diegetic), Amelia's bounties on existing commerce rails (mushrooms 1g / flowers 5s, zero C++), Baba Yaga's errand (strict IsMidnight mandrake pull, delivery buys your life; mirror finale deferred on fortress ruling), and combat barks WIRED (DT_CombatBarks had zero combat consumers; Aggro/HitTaken-once/Defeat now speak, KoboldWizard voiced). Runs 99-105, attempt-1 green except one flake-confirmed retry (102). The Mage spellbook reaches canon shape: DetectMagic/Trigger/Open/Calm all teachable in-world. EVERYTHING remaining converges on the n093-097 fortress ruling (Yorick/Elsa, ClearBrigandFortress, mirror finale, Bonehead, Brutus). | done 2026-06-12 |
| M21 Deferral closure (economy systems complete) | ✅ W42 T928afd..afh: every recorded M16/M18 deferral closed. Shop stock decrement (session ledger seeded from StockQty, consume AFTER carry-gate BEFORE payment; 0-stock rows = sell-only), crafting station gates (recipe Station must be a room FIXTURE — table row by RoomID+HotspotID, spawn gates deliberately ignored: the quest-gated dispel cauldron is still a pot for ordinary alchemy), restock-hours (shelves reseed on the game clock past the authored hours), per-item weights (FQFGItemsRow.Weight default 1 = old instance-count semantics preserved; LeadIngot weight-5 proof row; live RowStruct change rode the T928aaa md5-stamp pipeline cleanly). Plus combat barks wired (Aggro/HitTaken-once/Defeat; DT_CombatBarks' first combat consumer; KoboldWizard voiced) and the wizard's canon blink-on-hit (deterministic offset rotation) + qfg_HurtEnemy survivable-damage driver. Runs 105-112. Three reds (106 carry-vs-stock test ordering, 108 two-table-worlds lookup, the afb/aff double-paste pair incl. one gate-chain violation owned in LESSONS) — all root-fixed same-tick. Queue archaeology: the standing /loop queue items 1-2 verified ALREADY COMPLETE via the T928aaa project-level pipeline. Balance pass (real weights) = recorded CMO tick. | done 2026-06-12 |
| M22 Polish lane (while the fortress ruling waits) | ✅ W42 T928afj..afn: the n093-097 DECISION BRIEF (docs/DECISION_n093_097.md — the endgame's single blocker reduced to a 60-second read; recommendation Option B = align doc to data, zero runtime changes; AWAITS SHAUN). C-Suite review (disk 33GB/monitor, dev==main tree-identical, lessons-protocol tool created). Burden readout chain: shared weight getters on the facade -> qfg_Inventory burden line -> FCanvas HUD gauge by the coin (tan/amber/red at 80%/cap; display and cap share ONE implementation). Force Bolt: the wizard's blink answers with instant-hit retaliation (-10), completing his canon kit (blink + bolt + barks + key + once-ambush; Reversal deferred on spell-combat). Runs 113-115 attempt-1 green. | done 2026-06-12 |
| M23 Combat voice + consumption closure | ✅ W42 T928afp..afr: safe-subset weight balance (Sword 4 / Chainshirt 6 / LeatherArmor 4 — mage-era cap blocks untouched by construction). qfg_Drink closes the LAST read-only consumption gap (potions were bought/crafted/looted/sold, never drinkable: HealthPotion +30 HP, ManaPotion +25 MP, refusal branches). Swing barks (AttackStart/Hit/Miss) consumed — moved to UQFGCombatComponent::AttemptAttack after run 119 proved PerformAttack is only ONE caller (the volley driver goes component-direct; the run-108 two-paths trap again). DT_CombatBarks now FULLY consumed: every trigger fires. The three-run Bruno chase (118-120) banked the harness-ecosystem lesson: live leftovers are actors (the wandering wizard explains runs 110/115's double markers), AI timing never beats the hero's auto-engage (force behaviors with drivers). T928aft+afu complete the voice cast: the Hero's Block bark on the player's parry + the LowHP threshold bark (the wizard's 'my bear' Barnard tie-in) — EVERY DT_CombatBarks trigger now fires from real combat code, both sides of every exchange (Hero Critical/LowHealth rows recorded deferrals: no crit system, needs hero-damage driver). Assert series reached 100. Runs 116-122. | done 2026-06-12 |
| M24 THE FORTRESS CAMPAIGN — QFG1 main quest COMPLETE | ✅ W42 T928afw..agc (runs 123-128, every merge attempt-1 green): the staged execution plan (FORTRESS_EXECUTION_PLAN.md) plus the critical-reread discovery that most of it was RULING-STABLE (handlers key on RewardScript strings, not room identity). Shipped: Brutus (1-HP glass cannon, 20-25 thrown dagger, the brothers' joke), the Yorick chain (jester reveal + deterministic 4-pull Escher maze -> tiny door; DEBT RATCHET ZERO — every gate in the game has a producer), Elsa's unmasking (the Leader IS the Baron's daughter; the single-brew dispel restores her, +25), the homecoming (Baron's hall, +25, ClearBrigandFortress canon completion beside the kill-counter route), the second brew (Dryad's post-Elsa acorn + fairies' item-guard — every ingredient source renewable), and THE MIRROR (+50, BabaYagaDefeated). All four QFG1 main quests now complete in earned, gated, asserted play. Outstanding: Bonehead's rhyme (ruling-entangled flavor), the §1 doc alignment (Shaun's DECISION_n093_097 — now purely documentation), endgame ceremony/QFG2 hand-off, art track. | done 2026-06-12 |
| M25 THE ENDING — ceremony + the carpet east | ✅ W42 T928age..agf (runs 129-130, attempt-1 green): THE CEREMONY (the hall full, Barnard at the right hand, Elsa at the left; 'By deed and by valor -- HERO OF SPIELBURG'; +100, the game's largest award) and THE CARPET (Abdulla Doo at the inn gated on the crowning; Talk = the invitation, Use = the departure; QuestFlag_DepartedForShapeir planted for QFG2's bootstrap -- the same-hero-across-five-games promise made load-bearing; the 16-second gold banner: TO BE CONTINUED IN QUEST FOR GLORY II: TRIAL BY FIRE). QFG1 plays title-screen to TO-BE-CONTINUED, every frame earned. The tick also re-learned the line-boundary-insert lesson (substring find split a CSV row; the awk gate caught it instantly). Remaining tracks: Bonehead + section-1 doc row (Shaun's DECISION_n093_097), packaged-build items, art, QFG2. | done 2026-06-12 |
| M26 SCRIPT COVERAGE COMPLETE — every authored interaction plays | ✅ W42 T928agh..ags (runs 131-141): the RewardScript-handler tripwire (validate_csvs.py cross-checks every DT_RoomHotspots RewardScript against the dispatch chain; exact/StartsWith/EndsWith/Lore_/Flavor_ all count) found 22 authored-but-dead interactions; eleven ticks burned them to ZERO and the ratchet now HARD-FAILS on any future dead script. Shipped along the way: the quest board (live quest-state readout), the stealth pair (Hide_Bushes + the thief-tail Wall_Climb), the ropes crossing, Toro 3-method, sword training, the handwriting-tell signs, throwing rocks, the Trigger-ladder to the hermit, the class three-methods (inner door Open/picks/bash; the nest's ring climb/Fetch/rock-throw — the block-115 joke rocks became the block-116 solution), Wolfgang's battlement exposition, the antwerp self-impale (canon: no score), and the ogre's full verb spread (live Calm pacify + real 30-HP Fight spawn + idempotent dead-guards). Run 140's 3/3-red was the own-guard collision (the dead-guard correctly beat the cast after the chest-prep driver kill) — root-fixed by moving the live pacify pre-kill, NET COVERAGE UP (both guards now asserted too). Assert series at 117; 0 issues across 102 data files. | done 2026-06-12 |
| M27 THE PACKAGED BUILD — Shaun can double-click it | ⚠️ REGRESSED → see M28 / docs/PLAYABLE_AUDIT.md (Shaun playtest 2026-06-13: menus stack, hero faces wrong way, transitions skip the walk-to-hotspot, attack jumps screens then freezes — none catchable by the log-green harness that closed this milestone). Original close: ✅ W42 T928agu..ahe2 (runs 139-149, cooks 1-10): the project's FIRST packaged Windows build, driven end-to-end by Shaun's two playtest reports. EIGHT root causes, none visible to the editor-target compile gate or the log-based PIE harness: (1) GetActorLabel/SetActorLabel editor-only APIs at 8 sites; (2) FATAL GC-verification crash ~60s in (runtime WASD modifiers outered to the disregard-pool IMC asset -> transient RuntimeMappingContext); (3) less than half the game cooked (runtime path-loading invisible to the cooker's reference walk -> DirectoriesToAlwaysCook, 448->956 packages); (4) hero+NPCs were meshless debug placeholders -> UQFGSpriteQuadComponent (chroma-keyed cel-on-quad, M_QFGSprite editor-python builder, sRGB->linear key, half-texel insets) + hero SPR_0 wired; (5) camera aimed 4.5m above the hero (boom offsets; BP_QFGHero serialized stale overrides -> Configure25DCamera owns ALL boom geometry); (6) T782 stage Brigand kept the combat wheel + Enemy panel on screen in EVERY room forever (rooms share one stage) -- AND its scenes_index generator resurrected it after the first purge; (7) THREE hardcoded copies of camera geometry desynced on the first reframe -> GetHeroCameraGeometry single source; (8) THE FLOOR WAS THE VOID: anonymous unlit 40x40m slab occluded the painting below the floor line -> geometric hide, collision kept, the hero walks ON the painting. New infra: -QFGTestBridge (file-bridge in cooked non-shipping builds), bridge-driven screenshot verification (the PIE harness asserts logs, not pixels -- per-run PIE shots had silently been editor-splash-only), Packaged/ gitignored after a 118MB pak nearly travelled. Smoke-19: zero black rows; hero sprite keyed clean in the meadow. | done 2026-06-12 |
| M28 PLAYABILITY PARITY — reference-vs-actual regression burn-down | 🔴 IN PROGRESS W42-T929 (opened on Shaun's "the game is broken" playtest): the recursive reference-vs-actual work-breakdown lives in docs/PLAYABLE_AUDIT.md — every game phase (title/char-create/exploration/hotspots/transitions/dialogue/combat/inventory/save-load/system/journal/HUD/minigames/sprites/UI-layering/survival/audio) decomposed into trackable leaves with status + candidate root-cause anchors. FOUR confirmed regressions seeded as the priority queue: REG-1 menus stack (PA-14: no single-active-modal arbiter in the FCanvas HUD draw), REG-2 hero faces wrong way (PA-13.2: inverted axis/mirror in QFGSpriteQuadComponent Dir mapping), REG-3 transition skips the approach-walk (PA-4: hotspot Use fires GoToRoom with no MoveTo phase), REG-4 attack jumps screens then freezes (PA-6.1: attack mis-dispatches as a room change then combat state stalls). HARD GATE for M28: no leaf flips ✅ on a log-green PIE run — ✅ requires a -QFGTestBridge screenshot read by eye (the M27 lesson made into a rule). CAPTURE PASS 1 done (tools/capture_phases.ps1, 20 PIE phases ScreenShot00000-19): confirmed REG-1 stacking (Journal stays drawn under Picker+System menu; per-panel toggles work, so the fix is ONE modal arbiter) + found REG-5 — a phantom "Kobold Lv 2" enemy persists in EVERY town room keeping the Enemy panel + combat action strip on screen (the T782 shared-stage-enemy bug REGRESSED). PIE caveat: hero renders as the UE checker placeholder (M_QFGSprite not applying in editor) so sprite visuals incl. REG-2 facing need a fresh cook, not PIE. Walk+transition-on-edge WORKS, so REG-3 is the click-to-walk trigger specifically. Revised order: REG-5 → REG-1 → REG-4 → REG-3 → REG-2. CYCLE 1 (T929c): REG-1 modal-arbiter FIX LANDED — priority gate in DrawHUD picks one top modal and suppresses the rest (compile PASS, PIE harness flake-confirmed green). Reframing from the verify capture: parchments are opaque so modal-over-modal is subtle; the DOMINANT clutter is REG-5 (combat strip + enemy panel in every town room), now top priority — root-caused to leftover encounter enemies on the shared stage origin needing cleanup-on-room-change, entangled with the harness's qfg_AttemptAttackN block. CYCLE 2 (T929d): REG-5 FIX LANDED — boot test enemy spawns hidden + OnRoomEntered hides leftover enemies + HUD combat gate skips hidden enemies (harness-safe: AttemptAttackN finds by IsDead not IsHidden). Verified BOTH gates: harness green (468/468, combat markers fired despite hidden enemies) + eyeballed (town rooms clean — Enemy panel + combat strip gone). REG-6 (NEW): hero renders the full sprite sheet squashed into the quad in PIE (M_QFGSprite UV sub-rect not applying) — PIE-only, needs a fresh cook to judge alongside REG-2 facing. Remaining: REG-4 combat, REG-3 click-to-walk, REG-2 facing + REG-6 cel-crop (cook needed). CYCLE 3 (T929s): MENU "IDENTICAL" REWORK LANDED — the three core menu/char-creation screens now draw the ORIGINAL extracted game art full-screen instead of FCanvas panels floating over the live town: main menu = BG_100 ("Wanted: Hero for the Village of Spielburg" tree+poster+path, PA-0.2), class select = BG_905 (stone niche wall + class labels + selection frame, PA-1.1), stat allocation = BG_904 (parchment char sheet with labels baked in + +N values in the boxes, PA-1.2). Unblocked by Shaun's authorization to ship original art (private repo) + his canonical UI-art map (100/904/905 = those screens; 912/945/950/990/992/995 = .v56 atlases for later). Also fixed qfg_CharCreate start to close the main menu on any entry path (capture caught the Wanted poster drawing over the class pick). Compile PASS x3, capture-verified by eye (ScreenShot 00105 main / 00106 class / 00107 alloc — backdrops identical), PIE harness green (bsa5gennh attempt-1, all asserts). PA-1.1/PA-1.2 backdrops flip ✅ in PLAYABLE_AUDIT (statue sprites + value-box alignment = recorded polish). CYCLE 4 (T929t): MAIN-MENU LAYOUT now matches 5-ch0104 — the dark corner strip replaced by 3 wood-sign buttons right-center (Introduction/Start New Hero/Continue Quest, original order, red selection outline) via a draw-only display→index map (controller dispatch + 34-series harness ring asserts untouched; harness green). Diagnosed the remaining "identical" gaps vs the LP originals: the carved-sign/statue/portrait/icon SPRITES live in the .v56 VIEW atlases (100.v56 = the real wood signs) — building clean per-cel transparent textures is the next enabler (SCI1.1 view-cel parser unsolved + .v56.bmp composites messy; recon in REFERENCE_LPARCHIVE_QFG1.md). Allocation "+N" is a deliberate 50-pt-pool mechanic (no class base stats), not a display bug. Remaining M28: REG-4 combat, REG-3 click-to-walk, REG-2 facing + REG-6 cel-crop (cook needed), and the .v56 sprite pipeline (exact carved signs + class statues + dialogue portraits + HUD icons). CYCLE 5 (T929v): CLASS STATUES LANDED + .v56 CEL PIPELINE PROVEN — the 3 original class figures (802.v56 cels) now stand on the BG_905 niche pedestals, matching 8-ch0107 (cap 00206). PA-1.1 statues ✅. Solved the .v56→FCanvas recipe (key magenta+black, alpha-dilate, UI-group TC_EDITOR_ICON import, aspect-correct DrawTile — full recipe in REFERENCE_LPARCHIVE_QFG1.md); this unblocks all remaining sprites (100.v56 signs, 506 labels, 1014-1334 portraits, icons). Debugged a black-bar artifact = a pure-black border row the magenta-only key kept. Remaining: statue size/pos fine-tune; then real carved signs + portraits. CYCLE 6 (T929w): REG-6 HERO-SQUASH ACTUALLY FIXED (Shaun caught it still broken — the 06-13 "PIE-only" call was wrong, and my menu-only capture-reading missed the 01-05 hero frames). Root cause: UTexture2D::GetSizeX() returns a bogus 32 in PIE for every sprite sheet -> InitSprite computed cel UV scale as CelW/32 not CelW/193 -> whole sheet squashed on the quad (material/UV were fine all along). Fix: use Sheet->GetImportedSize() (stable source dims). Fixes hero + ALL enemy/NPC sprites. Verified by eye vs source cel (cap 00315). Re-imported SPR_0 to true 193x397. PROCESS RULE ADOPTED: read the idle-hero frame every capture pass, not just the screen under edit. CYCLE 7 (T929x): PACKAGED BUILD DELIVERED — full UAT BuildCookRun (cook+stage+IoStore) regenerated QFGRemaster-Windows.ucas + exe, synced into Packaged/. Verified in the DOUBLE-CLICK build: hero = clean single cel (cap pkg 00040) AND the 3 class statues stand on the niches (cap pkg 00042). Both Shaun-reported issues now fixed in the playable build, plus the char-creation backdrops + main-menu layout. LESSON: packaged build is IoStore — new assets (statues) only enter via a full re-stage, not loose-file copies. Next batch (fresh session + ONE re-package): carved main-menu signs (100.v56, fiddly extraction), dialogue portraits (1014-1334), statue position fine-tune, and the deferred REG-2 facing / REG-3 walk-to / REG-4 attack click-test. CYCLE 8 (T929y): BOOT FLOW FIXED + a hard reckoning. Shaun played the build: no intro/menu/char-select on boot, hero stationary (no walk-to-hotspot), map wrong, HUD unchanged, NO NPCs, NO dialogue, no original assets seen. ROOT INSIGHT (the M27/M28 lesson at full scale): the M1-M26 milestones were verified by LOG-ASSERTIONS in the harness + exec/GoToRoom drivers, never by BOOTING AND PLAYING — so the integrated played game is missing the front-of-game flow and most systems don't manifest naturally. Measure-against is now the VGA longplay (reference/walkthrough/fxbfd8eB89Y, video_inspector) + live play, NOT logs. FIRST FIX: the boot sequence -- StartPlay auto-created a default Fighter and dropped into a room, skipping menus. Now (normal play only; -QFGTestBridge skips it for the harness) the HUD boots SIERRA (BG_1) -> title (BG_902) -> Wanted-Hero main menu (BG_100) -> Start New Hero -> class pick (statues) -> char creation -> first room. Verified by eye (cap 00375 Sierra, 00377 menu) via qfg_BootShow. NEXT (live, needs Shaun): walk each room -> fix map, spawn NPCs, wire dialogue, fix walk-to-hotspot (REG-3), strip HUD to the minimal original -- each measured against the longplay. CYCLE 9 (T929z): CHAR-SELECT STATUES TRULY IDENTICAL -- proved (clean-crop of pre-decoded 802.v56.bmp) the 3 STATIONARY stone statues exist in NO .v56 (only the rendered screen 8-ch0107; ruled out 800/802/803/905/904/902/903/907/910 -- docs/SCI_V56_FORMAT.md); the build had overlaid the WRONG 802.v56 ANIMATION poses (arms-crossed/pointing/caped-lunge), mis-sized. FIX: class-select now draws the ORIGINAL rendered char-select full-screen (BG_CharSelect = 8-ch0107 with the hover banner+cursor cleaned), so the 3 stone statues stand in their niches exactly as the original; the 802 overlay + top title + dev-hint retired; selected class on a wood banner under its niche. Full IoStore re-stage + eye-verified vs reference (ScreenShot00002 statues/niches/pedestals == 8-ch0107). PA-1.1 statues TRULY identical. CYCLE 10 (T929z): SCI VIEW EXPORTER BUILT -- animation pipeline unblocked. tools/sci_view_export.py decodes ANY .v56 view into per-loop/cel transparent PNGs + manifest (w/h/dispX/dispY + mirror map) + an inspector contact sheet. Validated on the hero (0.v56: 8 directional loops, walk-cycle frames, mirrors auto-resolved, EMBEDDED palette = correct red-cape colours) and the 802 UI atlas (all cels fill exactly w*h). THE bug that garbled cels all session: the view header sits at base 26 (a 26-byte prefix) and the cel RLE/literal stream offsets are RELATIVE TO BASE, not absolute -- a 26-byte skew a simple cel survived but complex ones desynced into streaks; the loop table is now WALKED, not brute-forced. Retired the buggy extract_v56_cels.py; format fully documented in docs/SCI_V56_FORMAT.md. This is HOW every animation gets made (hero/NPCs/monsters/FX/portraits/char-hover). NEXT: batch-export all views -> packer + DT_SpriteAnim + runtime play-by-name; redo char-select hover with 802 loop 0 + .snd cues. CYCLE 11 (T929z): DATA-DRIVEN SPRITE ANIMATOR (cooked + verified). QFGSpriteQuadComponent's hand-measured hardcoded HeroEast/South/North arrays RETIRED -> the animator now reads QFGAnim:: loop/cel data generated from the .v56 (tools/sci_view_pack.py packs a blue-key sheet + manifest; tools/gen_sprite_anim_header.py -> QFGSpriteAnimGen.h). Direction->SCI loop (E=0 W=1 S=2 N=3) + mirror resolution + cel-cycle at the view's fps -- identical behaviour, but DATA-sourced, so it scales to all 126 actors with zero hand-measurement. Hero SPR_0 re-imported from the packed sheet; compile PASS, full IoStore re-stage, eye-verified in the PACKAGED build (ScreenShot00000: hero a clean single cel, correct red-cape colours, facing camera at the town gate). NEXT: batch-pack the other 125 actors + regen header + wire NPCs/enemies; then char-select hover-to-life + .snd cues. CYCLE 12 (T929z): ENEMIES ANIMATE (data-driven, cooked + verified). All 9 enemy views (Brigand 465, Goblin 445, Saurus 460, Troll 425, Cheetaur 440, Bear 420, Mantray 435, Ogre 450, Kobold 455) packed into clean blue-key sheets + added to QFGSpriteAnimGen.h; QFGEnemy now forces the blue key (was per-view composite keys that no longer matched) + sets the anim flag. The animator gained a loop fallback so single-loop side-view creatures (Saurus/Cheetaur) fall back to loop 0 (west-mirrored) instead of breaking. Compile PASS, IoStore re-stage, eye-verified in the PACKAGED build (ScreenShot00012: a clean keyed winged enemy in combat, no blue box; SPR_465 confirmed the humanoid Brigand sheet). NEXT: NPCs (Sheriff/Zara/Erasmus/etc.) the same way; then the char-select hover-to-life + .snd cues. CYCLE 13 (T929): 3 PLAYTEST BUGS FIXED (Shaun: "walking doesn't work / main menu wrong / char-select no buttons"). (1) WALKING: click-to-walk called SimpleMoveToLocation, which needs a NavMesh the painted rooms don't carry -> silent no-op -> no velocity -> the velocity-driven animator stayed idle/south ("teleports, no anim, stares at you"). Replaced with continuous AddMovementInput steering toward the clicked point each Tick (the proven qfg_AutoWalk path) -> real velocity -> walk anim + facing for free; exit triggers now walk-to-edge THEN transition (no teleport into the next room). (2) MAIN MENU: the 3 carved wood signs are now the REAL 100.v56 cels (loop2 plank + loop4 gold lettering, baked to MM_Sign0/1/2 + MM_BorderSel/Idle) at the VGA-measured positions (x139 w154 h31, row tops {24,77,130} in native 320x200), replacing flat rects + DrawSCIText; click hit-test realigned. (3) CHAR-CREATE: decoded 802.v56 = the char-create UI atlas (loop0 = 3 stone class figures, loop3 = start btn, loop4 = cancel btn, loop7 = Points Available); the stat screen (phase 2) now overlays the selected class's stone figure in the niche + start/cancel buttons + Points Available on BG_904 (matches 9-ch0108); phase-2 click maps start->confirm, cancel->back-to-class-select. All compile-gated + IoStore re-staged + eye-verified in the PACKAGED build (main menu == ref f_00001; alloc screen == 9-ch0108; hero walks an animating back-view pose, not idle; hero traverses rooms under AddMovementInput). Capture caveat: an 8s AutoWalk crosses room edges, so mid-walk facing was caught via a tight 0.45s-preshot capture (tools/capture_walk_tight.ps1). KNOWN GAP (NOT faked, per the identical directive): the phase-1 statue HOVER animation (fighter draws+swings sword in the longplay) -- its multi-frame source is in NO decoded view (800=death anim, 802=this UI atlas, 803=combat HUD); statues remain the correct static stone idle until the animation source is located. CYCLE 14 (T929): STATUE HOVER ANIMATION + HERO FACING FIXED (Shaun's pointers: "526/527/528.v56 are the char-select animation screens", "0.v56.bmp is all the walking animations"). (1) Decoded 526=Fighter(7: arms-crossed->draw+swing sword) / 527=MagicUser(6: cast) / 528=Thief(6: stand->crouch-throw) -- already in sandstone tone, frame0=the standing rest the longplay shows, magenta=greenscreen. Built feet-aligned keyed strips (CC_AnimF/M/T), switched class-select from baked BG_CharSelect (its thief was frozen mid-crouch) to BG_905 (empty niche wall) + 3 composited statues at niche anchors F(44,119)/M(127,118)/T(218,118); hovered niche animates (qfg_CharCreate hover <n> drives it for the mouse-less bridge). Eye-verified in the packaged build: fighter draws sword, thief crouches (00002/00006 differ from rest). (2) Rendered all of 0.v56 = 8-direction walk: L0=W L1=E(m0) L2=S L3=N L4=SW L5=SE(m4) L6=NW L7=NE(m6). The animator used only 4 cardinals AND mapped East->L0(=West art) = REG-2 "faces wrong way"; replaced with full 8-way compass-angle->loop mapping. Eye-verified (capture_walkhome): East=>faces RIGHT, West=>faces LEFT, North=>back, South/idle=>front. REG-2 ✅. Both compile-gated + IoStore re-staged + read by eye. CYCLES 15-18 (T929): char-creation IDENTICAL + bounded depth scaling (hero stops vanishing) + carved banner cels/statue-on-pedestal/buttons + real .v56 sprites for Zara/Shameen/Erasmus (3 capsules killed). CYCLE 19 (T929, 2026-07-09): SCREEN-SPACE (SCI-faithful) WALKING FINISHED + HARNESS RECOVERED. The hero now moves in the fronto-parallel control plane (screen Y=horizontal, Z=vertical) like the original SCI engine, deprojecting clicks linearly onto that plane; per-room walkable-dirt rectangle (QFG_FloorFracForRoom) so he walks the painted floor in EVERY room (default lower-band + TownGate/TownSquare tuned), qfg_SetFloorFrac pins a manual rect for live tuning. CRITICAL PROCESS FINDING: the pie_test_run.ps1 gate had been SILENTLY RED since CYCLE 16 (d9c980f0 made char-create VGA-identical — confirm refused until all 50 pts spent — while the harness still allocated only 2; ~14 cycles shipped eye-verified only, the exact CLAUDE.md-warned rot). Root-caused 28 misses, restored GREEN attempt-1/3: harness now spends the full 50-pt pool in all 3 char-create flows (unblocked ~26 cascaded mage/thief asserts), walk asserts retargeted to the new QFG-Face SciLoop marker (East=1/West=0, screen-space AutoWalk drives Y only), and new qfg_EnemyAttackBy(EnemyId,N,ForceWeak) forces a NAMED enemy to swing (the leftover KoboldWizard had stolen Bruno's nearest-enemy volley → his AttackStart bark never fired). Compile PASS, PIE GREEN 0-fails, merged dev→main (ca0cc6f3) + pushed. CYCLE 20 (T929, 2026-07-09): REG-3 + REG-4 CLOSED and HARD-GATED. Both were fixed-in-code but stayed open because nothing tested the real mouse-click dispatch (the harness's 20_hotspot_click_route was a SOFT-MISS — the exact input-layer blind spot that let M27/M28 ship broken). REG-4 (attack jumps screens then freezes): the enemy-in-reach exit-suppression gate is now observable + gated (qfg_SpawnEnemy gained an optional FwdDist to place an enemy within the 150uu reach; an edge-click asserts suppression + a real swing, never a transition). REG-3 (click-to-walk): was gated behind GetHitResultUnderCursor (real OS cursor) so the bridge could never reach it — added a bClickOverride walk branch; two markers now gate it ("click-to-walk initiated" dispatch + "click-walk moving (vel=)" real velocity). 122/122a/123/123a green, merged dev→main (60e2a5d1) + pushed. Remaining M28: dialogue portraits (1300-band recon done). CYCLES 30-46 (T929, 2026-07-16): WORLD POPULATED + PORTRAIT COVERAGE COMPLETE (SCI-definitive). Ground truth switched from eyeball-matching to the decompiled SCI room scripts (QFG1_ASSETS/*.scr.txt — each actor's view $HEX/loop $HEX is the game's own NPC→sprite mapping; scan_all_npcs.py parses all of them). Shipped: 16 SCI-confirmed NPC BODIES (Shameen 302, Wolfgang 312, Amelia 57, Otto 606, Shema 303, Baron 141, BabaYaga 20, Beggar 333, Boris 332, Bruno 65, Crusher 331, Fenrus 199, StableMaster 42, Barnard 423, Dryad 76, Henry 83, BrigandLeader 97) via QFGNPCBase NPCSheets, and 18 SCI-definitive dialogue PORTRAITS (Shameen 1301 [Katta, not human — a caught eyeball error], Shema 1302, Sheriff 1300, Zara 1314, Barnard 1317, Dryad 1076, Erasmus 1034, Wolfgang 1311 [corr. from 1035], Kaspar 1322, Henry 1086, AbdullaDoo 1303, Fenrus 1031, Baron 1141, BabaYaga 1021, Yorick 1096, Meep 1060, Bruno 1074/Brutus 1073 [corr.], Amelia 1055, Beggar 1334, Elsa 1097, Brauggi 1059, Bartender 1331, Hilde 1320). BIGGEST BLOCKER SOLVED: newly-imported portraits rendered content-independent garbage until root-caused to import_sprites.py's TC_EDITOR_ICON+NoMips+never_stream overrides (180KB uncompressed vs the originals' ~25KB default-compressed) — tools/import_portraits_default.py imports from .v56.bmp with DEFAULT settings, and all 18 render clean. Also: tavern+thieves-guild backgrounds fixed (added DT_BackgroundIndex rows for BG_331/332), and the combined interaction model landed (mouse-to-top drop-down icon bar via TryTopBarClickAt AND the verb coin — both live). Every add SCI-cited + default-import-proven + compile-gated. | M28: all tracked regressions closed; 16 SCI NPC bodies + 18 SCI portraits landed — world populated |