scooby — Work Index

Master ordered ledger of work packets (WPs) and execution checklists (ECs). Each WP is one unit of work with a goal, dependencies, and exit criteria. ECs are step-by-step checklists for the WPs most likely to sprawl.

Last updated: 2026-06

Status vocabulary (closed set): ✅ Done · 🚧 In Progress · 📝 Drafted (WP file authored, not yet started) · 📦 Queued (deps met, WP file not yet authored) · ⏸ Blocked (dep unmet) · 🔮 Placeholder (forward-looking, intentionally not authored)


Current state

Current phase: Phase 0 → Phase 1 — Pre-Work then Format Research Primary blocker: WP-002 (TGIFILE.ART payload decode). Phase 2 cannot start until at least one TGIFILE.ART entry is extracted to a recognizable image. Next unblocked: Phase 0 pre-work. WP-007 ✅ landed 2026-06-02; WP-003 ✅ landed 2026-06-02; WP-008 ✅ landed 2026-06-03 (object.ini interpreter behavior characterized; engine is name-driven, MODE_A). Remaining order: WP-009 → WP-010 → WP-001 → WP-002. The WP-003 baseline (pre-payload region characterized as the engine name table; no palette present; off-by-4 header-offset correction landed) is now available to WP-001 (palette-hunt scope drops from EC-001; the OBJ→asset-entry 1:1 mapping cuts asset-resolution scope) and to WP-002 (first-decode strategy: palette is NOT in the pre-payload region — it is either per-asset leading bytes or per-record metadata; investigate both). The WP-008 baseline (engine name-driven, 215 OBJ_* sections discriminated by ID=, deterministic naming rule confirmed) gives WP-002’s probe_art.py a direct labeling path (entry_<index>_<wp003_name>.png) and gives WP-009 a canonical room-ID list to use for screenshot naming.

Phase 1 findings landed (2026-06)


Phase 0 — Pre-Work (run before WP-001)

These WPs require no Ghidra, no format decoding, and no binary analysis. They build the ground-truth references that make Phase 1 debugging tractable, and pin the ScummVM API target before implementation decisions are made. None block each other; recommended execution order is left-to-right in the table.

WP Title Status Deps EC Notes
WP-007 Scooby.exe strings dump + import table ✅ Done (2026-06-02) — — ~30 min actual (matched WP body’s 20–40 min estimate, vs. the original 15–30 min Phase 0 placeholder). Findings landed in scooby-exe §Binary identity / §String literals / §Import table; cross-title runtime-dependencies table now carries import-verdict cells (no remaining TBD/predicted). Primes EC-001 Steps 3–4.
WP-003 Pre-payload region scan (palette hunt) ✅ Done (2026-06-02) WP-007 ✅ (recommended) — ~2 hrs actual (matched 1–2 hr estimate). Findings landed in tgifile-art.md §Pre-payload region. Region is the engine name table (811 clean records: 42 ROOM + 453 OBJ + 316 ANIM). Header offsets corrected by −4 (asset_count at 0x0118). Negative palette finding — palette discovery moves to WP-002. Drops palette-hunt scope from EC-001.
WP-008 object.ini + Scooby.eng asset catalog ✅ Done (2026-06-03) — EC-004 ~3 hrs actual (vs. half-day estimate). Findings landed in scooby-exe.md §object.ini interpreter behavior. Engine is name-driven (MODE_A); 215 OBJ_* sections discriminated by ID=; 77.27 % cross-check vs WP-003 name table. Unblocks WP-009 naming + WP-002 first-decode labeling.
WP-009 Reference screenshot library (Showdown) 📦 Queued WP-008 ✅ — 1–2 hrs; required by EC-002 pre-flight. Canonical room-ID list now available from the WP-008 catalog (tools/samples/asset-catalog.json → rooms map; 37 IDs in ROOM_P{NN}_<Descriptive> form). Use these IDs verbatim as screenshot filenames per the WP-008 sanitization rule.
WP-010 ScummVM fork + empty engines/scooby/ scaffold 📦 Queued — EC-005 Half-day; pins commit hash; defines debug channel names before Ghidra annotations

Phase 1 — Format Research

WP Title Status Deps EC Notes
WP-001 Ghidra session: Scooby.exe imports + TGIFILE.ART decode trace 🚧 In Progress WP-003 ✅, WP-007 ✅ (recommended) EC-001 EC-001 Step 1 (PE Rich Header) ✅ done — toolchain identified across 4 titles. WP-007 baseline ✅ — Step 3 (Imports table review) is now a cross-check against scooby-exe §Import table, not a re-extraction. WP-003 baseline ✅ — palette-hunt scope drops from the TGIFILE.ART decode trace; the OBJ→asset-entry 1:1 mapping cuts asset-resolution scope. WP-008 baseline ✅ — four new explicit Ghidra targets surfaced (per WP-001 §Background): the object.ini consumer (switch on ID= value + name-hash lookup, xref-anchored on Failed to load room.), the scrappyid=Global.Scrappy.* script-table resolver, the inventory-anim resolver (OBJ_INV_* toolbaranim=/usecursor= names live outside TGIFILE.ART), and the scripted-room render branch (21 rooms with no TGIFILE.ART entry render via per-room code like Horseshoe_Corral_Room.cpp). Steps 2, 4, 5 (Ghidra load, file-I/O labeling, TGIFILE.ART decode trace) still pending.
WP-002 TGIFILE.ART payload decoder + first image extraction 📝 Drafted WP-001 (preferred, not strict) EC-002 Phase 1 exit criterion #1. WP-003 baseline ✅ — first-decode strategy: palette is NOT in the pre-payload region; investigate per-asset leading bytes and per-record metadata (offsets 48–67 of name-table records) as palette sources. The mixed tail region of the pre-payload (0xE6CC–0x10017E) also contains F0-opcode packed data and may co-locate per-asset palettes or pre-decoded frame data. WP-008 baseline ✅ — engine is name-driven; probe_art.py can label decoded entries directly as entry_<index>_<wp003_name>.png (sanitization rule per WP-008 §Notes; a no-op on every observed name). The 65 unmatched references from the WP-008 cross-check are not expected to resolve to decoded entries — verifying that none of them do is part of EC-002’s probe coverage.
WP-003 Inspect the 1 MB region between asset entries and first payload (palette hunt) ✅ Done (2026-06-02) — — Also listed in Phase 0. Pre-payload region is the engine name table — see tgifile-art.md §Pre-payload region. Header offsets corrected by −4 bytes. No palette in this region (palette discovery → WP-002).
WP-004 Audio archive index + codec identification 📝 Drafted — — Phase 1 exit criterion #3. WP-008 baseline ✅ — Scooby.eng is NOT in-game dialogue (10 boot/init system-error messages only). Dialogue text store is a new unknown — most likely Voice.dat, embedded in Scooby.exe, or a not-yet-identified file. pickupsfx=<none> is the only audio key in 215 object.ini OBJ sections, weakening “voice clips referenced by name from object.ini” — audio cues are likely triggered by the scrappyid script system (WP-001 lead). See WP-004 §Notes.
WP-005 Engine-family check across Case File ISOs 🚧 In Progress — EC-003 Case File #1 done — one engine lineage across three generations confirmed; code-level TerraGlyph→IBS inheritance confirmed. Case File #2 verification still owed.
WP-006 Phantom archive format verification (Gen 1 vs Gen 2) 📝 Drafted — — One-minute Format-Hex check; locks in Phantom’s generation classification

Phase 1 exit gate: see Project Vision → “Phase 1 — Format Research” exit criteria. Summary: one TGIFILE.ART entry rendered to PNG/BMP, structure documented in docs/formats/, audio codec named, engine-family question answered.


Phase 2 — ScummVM Engine Scaffold (placeholder)

Authored after Phase 1 exit. Tracked here to maintain phase ordering only.

Provisional scope Anchored to
Fork scummvm/scummvm; pin commit hash in 02-SCUMMVM-INTEGRATION.md Moved to WP-010 (Phase 0)
Create engines/scooby/ skeleton with module.mk, configure.engine; debug channel stubs Moved to WP-010 (Phase 0)
MetaEngineDetection + MetaEngine subclasses; engine class with empty run() 02-SCUMMVM-INTEGRATION.md §1, §2
ADGameDescription table populated from Phase 1 findings, carrying a per-entry generation flag (Gen 1/2/3) per the engine lineage finding §3
POTFILES (after translatable strings exist) §10

Phase 3 — Resource Loading (placeholder)

Provisional scope
TGIFILE.ART parser as Common::Archive subclass (Gen 1)
MMFW container parser as Common::Archive subclass (Gen 2 / Gen 3)
Audio loader through Audio::Mixer
Scooby.eng parser (Gen 1 / Gen 2)
object.ini parser into engine structs (Gen 1 / Gen 2)
XML config parser (Gen 3) — likely wraps ScummVM’s bundled libxml or a small in-engine parser

Phase 4 — Game Logic (placeholder)

Provisional scope
Room/scene management and transitions
Cursor system and object interaction
Inventory
Bink video playback via ScummVM’s decoder
Puzzle state machine — data-driven first, Ghidra-assisted where data falls short

Phase 5 — Polish & Contribution (placeholder)

Provisional scope
Test in-scope titles per Phase 5 scope rule in vision
Save/load if engine supports it
ScummVM wiki page
PR to scummvm/scummvm targeting ADGF_TESTING
All twelve acceptance gates from 02-SCUMMVM-INTEGRATION.md pass

Reference Screenshots — Showdown in Ghost Town (WP-009)

One screenshot per distinct room, captured from a YouTube longplay. Required tier serves WP-002’s decoder (EC-002 pre-flight); stretch tier serves WP-001 Ghidra / Phase 3 reimplementation. Full gallery lives at docs/assets/screenshots/showdown-screens/ — tracked in git, served by GitHub Pages.

This section carries only 1–2 representative thumbnails as a teaser linking to the gallery; the full 16+ image set does NOT live inline here (it would bloat WORK_INDEX). Embed syntax for adding a teaser row:

| ![Room name](../assets/screenshots/showdown-screens/ROOM_P21_Boot_Hill1.png) | Boot Hill 1 | `ROOM_P21_Boot_Hill1` |
Screenshot Room ID
(WP-009 not yet run — see gallery scaffold)    

References


Promote Phase 2-5 entries to authored WPs as Phase 1 closes — not before. Premature WP authoring is its own form of churn.