# Dungeon pipeline This directory turns the original Wailing Caverns one-off into a reviewed, versioned process. Wailing Caverns is the global-WMO golden fixture and Deadmines is the first ADT/hybrid recipe. ## Inputs - `WOW_CLIENT_ROOT` points at a local 3.3.5a client. If omitted, the recipes use the workspace-relative `../wow335a` client. - `EPOCH_CLIENT_ROOT` points at the installed Project Epoch client. For the Ascension Launcher install used by this project: `C:\Program Files\Ascension Launcher\resources\epoch_live`. - `WOW_SERVER_DATA` points at a read-only normalized JSON snapshot or a directory containing `.json`. Credentials are never read or written. - Server JSON has a `tables` object containing `creature`, `creature_template`, `creature_template_model`, `creature_addon`, `creature_formations`, `waypoint_data`, `gameobject`, `gameobject_template`, `instance_encounters`, and `areatrigger_teleport`. ### Reproducible AzerothCore snapshot The bulk importer can create one normalized, map-scoped source file per reviewed dungeon recipe from a pinned AzerothCore world database commit. It reads SQL as data and never starts, connects to, or mutates a database: ```powershell npm run dungeon:source:azerothcore -- --fetch $env:WOW_SERVER_DATA = "dungeon-pipeline/work/server-data" ``` The fetch is pinned by commit in `scripts/dungeon-pipeline/import-azerothcore-world.mjs`. Its lock report records the repository, commit, file hashes, parsed schemas, and per-dungeon counts. The installed Ascension `DungeonEncounterExtra.dbc` catalog remains the boss identity/order source so custom realm encounters are not silently replaced by stock server data. The generated SQL cache and normalized snapshots stay under `dungeon-pipeline/work/`. ## Full-campaign build The campaign compiler turns every reviewed recipe into a runtime-ready dungeon catalog. A clean rebuild is: ```powershell $env:EPOCH_CLIENT_ROOT = "C:\Program Files\Ascension Launcher\resources\epoch_live" npm run dungeon:epoch:sync npm run dungeon:epoch:catalog npm run dungeon:source:azerothcore -- --fetch npm run dungeon:epoch:scripts -- --fetch npm run dungeon:discover:all npm run dungeon:epoch:creatures npm run dungeon:epoch:build npm run dungeon:catalog npm run manastorm:maps:validate ``` `dungeon:catalog` compiles the 54 reviewed five-player instances declared in `dungeon-pipeline/dungeon-campaign.json`. The explicit manifest is required because Ascension's `Map.dbc` also marks instanced outdoor-zone copies and arenas as party instances. Raids, arenas, and outdoor zones are intentionally excluded from the dungeon browser. The 18 Project Epoch additions require all five-player instance signals: an instance `Map.dbc` row, LFG records, normal and heroic `MapDifficulty.dbc` rows, ordered `DungeonEncounter.dbc` records, and a real WDT/map directory. `dungeon:epoch:catalog` verifies those signals directly from the installed MPQs. The compiler aligns pinned AzerothCore populations to the exported environments, combines template spells with exact boss-script references, and attaches native animated client models by display ID. It writes: - `src/game/generated/dungeonCampaignCatalog.json`, the readable source artifact - `src/game/generated/dungeonCampaignCatalog.compressed.ts`, the bundled catalog - `src/game/generated/dungeonAvailability.json`, the generated availability list Stock AzerothCore population is used for the standard dungeons. The three Ascension-specific instances—Tinkertech Showdown, Frozen Reach, and Forgotten Mine—keep their client encounter identities and use an explicit procedural trash-population fallback. Non-Epoch recipes keep explicit procedural actor bodies until reviewed display exports are available. Epoch actors use packaged client GLBs with their complete native animation libraries; only event-only controllers without a creature display fall back. ## Project Epoch five-player import `dungeon-pipeline/epoch-five-player-instances.json` is the auditable source manifest for the 18 imported instances. It includes the Caverns of Time five-player instances and the selected Wrath five-player maps from Utgarde Keep through Halls of Reflection. - `dungeon:epoch:sync` regenerates the 18 dungeon and Manastorm recipes and updates the explicit campaign. - `dungeon:epoch:catalog` reads the Epoch MPQ/DBC view and verifies maps, difficulties, LFG records, encounters, displays, animations, and spells. - `dungeon:source:azerothcore` writes map-scoped spawns, templates, formations, patrols, game objects, encounter credit entries, and spell lists. - `dungeon:epoch:scripts -- --fetch` maintains a sparse checkout of the exact pinned AzerothCore C++ encounter scripts, including Caverns of Time, and compiles them into a deterministic ability catalog. - `dungeon:epoch:creatures` exports and packages every referenced display as an animation-preserving browser GLB. - `dungeon:epoch:build` resumes the environment, collision, navigation, semantic-anchor, optimization, and stage-package build for all 18 maps. ## One-dungeon release flow The gradual Manastorm-to-five-player migration is tracked in `FIVE_PLAYER_IMPORT_TODO.md`. Import only the selected dungeon: ```powershell npm run dungeon:five-player:import -- shadowfang-keep --refresh npm run dungeon:catalog npm test ``` The importer packages the reviewed instance environment and only the included combat population under `public/assets/game/dungeons//`. The campaign compiler prefers that package for the converted slug and temporarily retains the existing Manastorm package for every unchecked dungeon. To execute the same single-dungeon command separately for every remaining checklist entry and keep a resumable audit log: ```powershell npm run dungeon:five-player:import:remaining ``` The runner invokes `npm run dungeon:five-player:import -- --refresh` for each entry. It writes `FIVE_PLAYER_IMPORT_RUN_REPORT.json` and `FIVE_PLAYER_IMPORT_RUN_REPORT.md` after every dungeon. A rerun resumes past green entries unless `--force` is supplied. Failed entries stay unchecked until their documented blocker is resolved and the individual command succeeds. After compiling the catalog, run the native-pack audit: ```powershell npm run dungeon:catalog npm run dungeon:five-player:verify ``` The audit verifies the complete 54-dungeon catalog, authoritative/fallback classification, every native environment and creature URL, file sizes, checksums, animation presence, and compiled entry-to-model bindings. The 2026-07-26 batch packaged 50 native imports; together with the Wailing Caverns golden fixture, 51/54 dungeons are authoritative. Tinkertech Showdown, Frozen Reach, and Forgotten Mine remain documented fallbacks because available local sources contain their maps and encounter identities but no authoritative Ascension creature templates, display mappings, or spawn rows. 1. `npm run dungeon:discover -- ` writes deterministic client/server snapshots, a provenance lock, review-required overrides, and—when server data is present—a runtime/creature draft. The command reads DBCs through the merged MPQ view; it does not require files to be staged by an MPQ editor. 2. Review the entrance, objective order, optional encounters, inferred formations, unsupported objects/transports, and off-mesh links. 3. `npm run dungeon:extract -- ` exports a global WMO or every WDT-present ADT tile, placement metadata, referenced WMO/M2 models, raw liquids, and textures through the patched portable wow.export bridge. 4. `npm run dungeon:convert -- ` assembles the exported scene in Blender and emits lossless visual GLB, collision chunks (each at most 100,000 triangles), editable `.blend`, bounds, material roles, and a review report. 5. `npm run dungeon:optimize -- ` instances and prunes a shipping visual while preserving the lossless GLB and `.blend`. 6. `npm run dungeon:creatures -- ` exports every resolved display in one pass. Direct M2 actors retain their source skeleton; composite records carry baked textures, geosets, equipment attachments, and the complete source sequence library. Unresolved composites are blockers. 7. `npm run dungeon:navmesh -- ` bakes an offline Recast navigation GLB to `dungeon-pipeline/work//staging` using pinned dependencies. 8. `npm run dungeon:build -- ` hashes the reviewed runtime fixture and its environment/creature dependencies into a pack manifest. 9. `npm run dungeon:validate -- ` checks GLBs, collision budgets, population references, creature skins/tracks/semantic clips, difficulty masks, objective connectivity, and reviewed off-mesh links. 10. Capture the required desktop, Thor, and Android visual/performance evidence. 11. `npm run dungeon:enable -- ` updates the generated availability file only when the latest validation report is green. ## Current fixtures - Wailing Caverns is enabled and validates green with a Recast navigation GLB, one authored steep-transition link, 16 shared creature definitions, and the original gameplay coordinates/behavior. Its deterministic pack and green validation baselines live in `fixtures/wailing-caverns` for clean-rebuild comparison. - Deadmines proves the ADT/hybrid source path: 36 WDT-present tiles and 47 referenced model assets extract with no missing dependencies; Blender emits a 36-chunk collision set, reconstructs legacy `MCLQ` liquid geometry across 27 ADT meshes, and emits an optimized visual. Its imported population is aligned to the exporter coordinate basis and is included in the campaign catalog. All generated work/cache/staging output is resumable and ignored. Reviewed recipes and fixtures are committed. The one-dungeon validation flow treats missing source dependencies as blockers in JSON reports. The campaign compiler labels its procedural actor/population fallbacks explicitly rather than presenting them as source-faithful exports. ## All-WoW-dungeons batch Use the project-native batch instead of prompting Codex dungeon by dungeon: npm run dungeon:wow:all The default pass recompiles the 54-dungeon campaign, verifies all packaged environment and creature assets, audits every mob and boss attack/mechanic, opens every unique native creature GLB to verify idle, movement, attack, wound, and death clips, proves the procedural animation path for model-less actors, and runs the actual runtime-registry coverage test. It writes deterministic JSON and Markdown reports to WOW_DUNGEON_CONTENT_REPORT.json and WOW_DUNGEON_CONTENT_REPORT.md. Useful batch options: # Re-import cached server/script data and resume every native dungeon package. npm run dungeon:wow:all -- --refresh # Refresh the pinned upstream checkout before importing. npm run dungeon:wow:all -- --fetch # Re-run green packages, then build the app after validation. npm run dungeon:wow:all -- --refresh --force --build # Only re-run combat, mechanic, and animation coverage against current output. npm run dungeon:wow:all -- --audit-only Kresh is intentionally recorded as a source-faithful melee-only boss: entry 3653 has no spell or SmartAI row in the pinned AzerothCore snapshot. Trial of the Champion is likewise documented as a boss-arena population rather than a trash route. These exceptions are asserted by exact dungeon/entity IDs; any new basic-only boss or mob-less dungeon fails the batch.