Files
healer-man/dungeon-pipeline/README.md
T
2026-09-09 11:21:33 -04:00

289 lines
15 KiB
Markdown

# 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 `<slug>.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
Boss specials are compiled as independent mechanic records. AzerothCore
SmartAI timers and health events are imported automatically; C++ encounter
spells are imported from the pinned script checkout. Add or override a boss in
`dungeon-pipeline/boss-mechanics.json` when an encounter needs hand-authored
targeting, summon behavior, timing, or telegraph geometry. Use `mode: "replace"`
to make that list authoritative or `mode: "append"` to layer entries ahead of
the imported mechanics, then run `npm run dungeon:catalog`. The generated
`combat.mechanicIds` list is the stable loadout boundary intended for later
encounter randomization.
The same catalog also stores Runewaker kits under
`rw-<dungeon>-<entity-id>` keys. Run `npm run runewaker:bosses:refresh` to
rebuild those records from preserved RuneWaker spell/Lua evidence, regenerate
the population packages, and run `npm run runewaker:audit:gameplay`. A record
whose preserved source has no recoverable combat ability is explicitly marked
`source.kind: "healer-man-source-gap"` rather than being claimed as authentic.
Stock AzerothCore population is used for the standard dungeons. The three
Ascension-specific instances—Tinkertech Showdown, Frozen Reach, and Forgotten
Mine—keep their recovered client identities, spell/summon evidence where
available, and explicit source-backed or HealerMan-authored runtime adaptations.
Their remaining procedural population is never labeled authoritative.
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/<slug>/`. 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 -- <slug> --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 have authoritative WoW population packages.
Tinkertech Showdown, Frozen Reach, and Forgotten Mine now have playable,
provenance-labeled runtime adaptations backed by
`ascension/ASCENSION_CUSTOM_DUNGEON_RECOVERY.json`. They remain outside the
authoritative package count because the recovered client evidence does not
include complete Ascension creature templates, display mappings, spawn/object
coordinates, or server-side cadence.
1. `npm run dungeon:discover -- <slug>` 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 -- <slug>` 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 -- <slug>` 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 -- <slug>` instances and prunes a shipping visual
while preserving the lossless GLB and `.blend`.
6. `npm run dungeon:creatures -- <slug>` 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 -- <slug>` bakes an offline Recast navigation GLB
to `dungeon-pipeline/work/<slug>/staging` using pinned dependencies.
8. `npm run dungeon:build -- <slug>` hashes the reviewed runtime fixture and
its environment/creature dependencies into a pack manifest.
9. `npm run dungeon:validate -- <slug>` 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 -- <slug>` 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,
runs the actual runtime-registry coverage test, and audits instance-level
functionality. It writes deterministic JSON and Markdown reports to
WOW_DUNGEON_CONTENT_REPORT.json, WOW_DUNGEON_CONTENT_REPORT.md,
WOW_DUNGEON_FUNCTIONALITY_REPORT.json, and
WOW_DUNGEON_FUNCTIONALITY_REPORT.md. Catalog compilation also writes
WOW_GAMEOBJECT_ASSET_MANIFEST.json, which deduplicates the source-backed object
spawns by client model path, preserves per-dungeon/display usage, assigns the
planned shipping GLB URL, and lists unresolved display models and bounds.
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
# Re-run combat, animation, and instance-functionality audits against current output.
npm run dungeon:wow:all -- --audit-only
The functionality report is the production-fidelity gate. It separately checks
typed world-object contracts, source instance scripts, encounter orchestration,
required interactions, traversal evidence, resets, checkpoints, and completion
playtests. A green asset or combat audit does not imply that doors, escorts,
waves, vehicles, keys, chests, or scripted instance progression are implemented.
The report fails closed and lists concrete edit targets for every remaining
dungeon gap.
The 2026-09-08 implementation sweep completed an instance-level source review
for all 54 campaign dungeons. Fifty-one now have runtime-wired reviewed
orchestration in addition to fleet boss/checkpoint/completion declarations; the
three stock instance scripts that are genuinely empty are pinned and recorded
as source-exact no-ops. This means there is no remaining unreviewed instance
script, not that every source feature is already exact or live-traversal validated. Per-dungeon adaptations,
missing primitives, native-object export work, and live traversal evidence stay
open in `WOW_DUNGEON_FUNCTIONALITY_REPORT.md`.
Source-backed object records stay hidden, non-blocking, and non-interactive
until their manifest asset has been exported and the corresponding instance
script transition has been reviewed. This lets the typed data ship through the
runtime contract without leaking placeholder geometry or turning an incomplete
door/transport port into a dungeon soft lock.
Kresh, the Deviate Faerie Dragon, Grubbis, Spirestone Battle Lord, Spirestone
Butcher, and Crystal Fang are intentionally recorded as source-faithful
melee-only bosses. Kresh entry 3653 and the Deviate Faerie Dragon entry 5912
have no spell or SmartAI row in the pinned AzerothCore snapshot; the latter is
also despawned by the Wailing Caverns initialization event. Grubbis entry 7361
has only aggro dialogue and death-completion rows, with no combat spell cast.
The three Blackrock Spire entries are 15% rare spawns whose database rows
contain no active combat cast; Crystal Fang's exact on-death Spire Spiderling
summon is implemented by the reviewed instance adapter. One shared exception
table supplies the runtime test and composed-content audit; stale, duplicate,
or newly introduced basic-only boss keys fail the batch.