Compare commits

...
19 Commits
Author SHA1 Message Date
phenom 7f6001723a Release Healer Man 0.1.22 2026-09-09 11:21:33 -04:00
phenom f6f2375145 Release Healer Man 0.1.21 2026-09-08 10:40:26 -04:00
phenom 699fc858c9 Release Healer Man 0.1.20 2026-09-06 14:38:59 -04:00
phenom d9bebb4e81 Release Healer Man 0.1.19 2026-09-06 11:06:03 -04:00
phenom eaddad4134 Release Healer Man 0.1.18 2026-09-05 22:15:48 -04:00
phenom fc8a7a722a Release Healer Man 0.1.17 2026-09-05 21:27:30 -04:00
phenom b57d2b2839 Release Healer Man 0.1.16 2026-09-05 20:42:38 -04:00
phenom f49e54f35f Release Healer Man 0.1.15 2026-09-05 15:33:06 -04:00
phenom 7b41b102fa Release Healer Man 0.1.14 2026-09-05 11:40:50 -04:00
phenom 67d7a8ebe7 Release Healer Man 0.1.13 2026-09-01 16:31:26 -04:00
phenom 65e24f644e Release Healer Man 0.1.12 2026-09-01 14:35:56 -04:00
phenom 13970d03c8 Release Healer Man 0.1.11 2026-08-31 14:12:51 -04:00
phenom 5f1a14d8de Release Healer Man 0.1.10 2026-08-31 12:05:34 -04:00
phenom d060296ade Release Healer Man 0.1.9 2026-08-30 14:16:56 -04:00
phenom c245a199b6 Release Healer Man 0.1.8 2026-08-27 13:29:58 -04:00
phenom eca6b5db9b Release Healer Man 0.1.7 2026-08-22 15:53:43 -04:00
phenom b12fb84859 Release Healer Man 0.1.6 2026-08-20 14:05:50 -04:00
phenom 55cfd43d66 Release Healer Man 0.1.5 2026-08-18 16:22:19 -04:00
phenom f4c9cf356c Release Healer Man 0.1.4 2026-08-18 12:06:04 -04:00
1263 changed files with 1245773 additions and 8367 deletions

No files matched your search

+10
View File
@@ -0,0 +1,10 @@
root = true
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
[*.{bat,cmd}]
end_of_line = crlf
+3
View File
@@ -0,0 +1,3 @@
* text=auto eol=lf
*.bat text eol=crlf
*.cmd text eol=crlf
+1
View File
@@ -20,5 +20,6 @@ releases/
/content/ /content/
dist-android/ dist-android/
.android-public/ .android-public/
.web-public/
__pycache__/ __pycache__/
*.pyc *.pyc
+6
View File
@@ -0,0 +1,6 @@
{
"files.eol": "\n",
"files.insertFinalNewline": true,
"files.trimFinalNewlines": true,
"files.trimTrailingWhitespace": true
}
+7 -1
View File
@@ -2,6 +2,13 @@
These rules apply to every change under this project root. These rules apply to every change under this project root.
## Text-file hygiene
- Every text file must end with exactly one newline, with no extra blank line
at EOF and no trailing whitespace.
- Before handing off changes, run `npm run release:check`. This check includes
untracked files; `git diff --check` alone does not.
## Workspace and reference boundaries ## Workspace and reference boundaries
- The active project root is `D:\Projects\HealerMan`. All implementation, - The active project root is `D:\Projects\HealerMan`. All implementation,
@@ -44,4 +51,3 @@ These rules apply to every change under this project root.
- `document.pointerLockElement` remains `null`; - `document.pointerLockElement` remains `null`;
- releasing right mouse stops camera motion; - releasing right mouse stops camera motion;
- no browser mouse-capture prompt appears. - no browser mouse-capture prompt appears.
+52
View File
@@ -0,0 +1,52 @@
# Balance benchmarks
The balance benchmark suite provides repeatable evidence for tuning World of Warcraft, CoA, and Runes of Magic classes. It runs fixed builds through versioned damage, tanking, healing, movement, stacking, and resource-endurance scenarios. The goal is to reveal balance changes and outliers, not to name a universally best class.
## Default cohort
The default comparison cohort is level 60, matching CoA's authored cap while keeping the three content sources in one cohort. It uses the `coefficient-empty` preset: no equipment, so the first cohort isolates base kits, scaling coefficients, talents, and resources. Gear-normalized cohorts should be added separately rather than mixed with this one.
Every comparison must use the same gear preset, scenario version, baseline policy ID, duration scale, and seed set. A changed level, gear preset, scenario, policy, or app version creates a new cohort and should not be compared directly with an older one.
Run the suite with:
```sh
npm run balance:benchmark
```
Use `npm run balance:smoke` for a short end-to-end check. The full command accepts comma-separated `--class`, `--role`, `--scenario`, and `--seeds` filters, plus `--level`, `--duration-scale`, and `--output`. For example:
```sh
npm run balance:benchmark -- --class priest,rom-priest --role healer --seeds 1,2,3
```
The command is the intended stable entry point for the benchmark runner. Its output directory contains:
- `matrix.json`: raw run reports, build and scenario definitions, seed metadata, validation results, ability details, resources, and event counts.
- `matrix.csv`: one row per scenario, build, and metric, with observed/null counts plus median, p10, and p90 values.
- `summary.md`: a concise role-separated comparison for review and pull-request evidence.
Keep the JSON artifact when investigating a result. The CSV and Markdown are derived views and can be regenerated from it.
## Reading results
The reported center is the median across validated seeded runs. The p10–p90 interval shows run-to-run spread; a wide interval calls for more seeds or investigation before tuning. Invalid runs are counted but excluded from distributions. An early death or other scenario stop can be a valid outcome and should not be discarded merely because the full duration was not reached.
Interpret each role as a vector of outcomes, not a single ranking:
- Damage builds emphasize DPS and priority-target damage, with deaths and mechanics failures alongside throughput.
- Tanks emphasize damage taken per second, mitigation, avoidance, threat control, minimum health, survival, and their damage contribution.
- Healers emphasize healing per second, consumed absorbs, overheal, party health, deaths, and time to resource failure.
- Movement and stack scenarios add movement interrupts and stack compliance to the relevant role vector.
No composite score is produced. Compare a build only with other builds in the same scenario version and cohort, and inspect the underlying metrics before making a balance change. A null time to resource failure means the resource was not exhausted during that run; it is not zero. Similarly, a null time to first death means no death occurred.
## Limitations
- The baseline policy is a deterministic, maintainable reference policy, not an optimal player rotation. Skilled play may outperform it, and policy changes can move results without a class-data change.
- The initial `coefficient-empty` cohort does not model production gear breakpoints or itemization. Add explicit equal-budget gear presets for that work.
- Runes of Magic coverage is primary-class-only initially. Secondary-class and dual-class interactions require their own explicitly versioned cohort when supported.
- Results cover mechanics represented by the simulator and scenarios; they do not replace live encounter playtesting, usability review, or PvP testing.
- Small seed sets can miss rare random outcomes. Treat p10 and p90 as descriptive bounds for the sampled runs, not guarantees.
- Total metrics depend on scenario duration. Compare rates or fixed-duration totals only within the same scenario definition.
- Gear-stat budgets must be equivalent, but equivalent budgets do not guarantee identical interactions with every class kit.
+66 -33
View File
@@ -1,10 +1,12 @@
# Local-first content updates and Android releases # Local-first content updates for browser and Android
Healer Man separates the installed game client from large game content. The Healer Man separates the installed game client from large game content. Both
Android APK contains the React/Three.js runtime, native Android bridge, menus, the production browser build and Android APK contain a compact required set:
local profile and save support, UI assets, and the Wailing Caverns starter the React/Three.js runtime, menus, local profile and save support, UI assets,
pack. Other GLBs, textures, audio, character packs, dungeons, and Manastorm starter equipment, Wailing Caverns starter content, and the basic Human
stages are published by TrueNAS as optional content. character model with its default male and female appearances. Android also
contains its native bridge. Other GLBs, textures, audio, character/skin packs,
dungeons, and Manastorm stages are published by TrueNAS as optional content.
Single-player is local-first. Starting the game, loading a character, entering Single-player is local-first. Starting the game, loading a character, entering
installed content, simulating combat, and saving progress never require the installed content, simulating combat, and saving progress never require the
@@ -27,16 +29,12 @@ UI behavior, shaders or loaders, native Android code, permissions, or the
content-manifest schema. A manifest can set `minimumAppVersion` so an older APK content-manifest schema. A manifest can set `minimumAppVersion` so an older APK
will not activate incompatible content. will not activate incompatible content.
The browser build remains a full build served by TrueNAS. It receives client Production builds deliberately stage only required content. `npm run build`
code when the app checkout is pulled, rebuilt, and restarted. The Android build prepares `.web-public` and emits the compact browser `dist`; Android prepares
is deliberately separate and compact so the APK does not inherit the complete `.android-public` and emits `dist-android`. The development server continues to
multi-gigabyte browser asset catalog. use the source `public` tree so asset-pipeline work remains convenient. The
complete source catalog and published immutable objects stay on TrueNAS, not in
Measured on August 14, 2026, the production browser `dist` is 3.88 GiB across every player's initial browser or Android installation.
18,895 files; GLBs account for 3.75 GiB. The compact Android `dist-android` is
148.0 MiB across 5,561 files, including 47.8 MiB of starter GLBs. The final
signed APK will be smaller because Android packages compress eligible files;
record its exact size after the first release build.
## Content manifest ## Content manifest
@@ -56,8 +54,9 @@ The runtime continues to request stable paths such as:
``` ```
The content resolver maps that path to a verified file in Android app-private The content resolver maps that path to a verified file in Android app-private
storage. Filenames are therefore not used as version numbers and runtime code storage or, in production browsers, to the app-managed content cache through a
does not need to know the hash. same-origin service worker. Filenames are therefore not used as version numbers
and runtime code does not need to know the hash.
## Safe publication and activation ## Safe publication and activation
@@ -68,17 +67,34 @@ Publication order is intentionally atomic:
3. Write the versioned manifest. 3. Write the versioned manifest.
4. Replace `manifest.json` only after all referenced objects exist. 4. Replace `manifest.json` only after all referenced objects exist.
On a device, the client fetches the small manifest and compares it with its The client fetches the small manifest and compares it with its bundled and
installed manifest. Only missing or hash-mismatched objects are downloaded. installed file identities. Only missing or hash-mismatched objects are
Android streams each object to a `.part` file, supports HTTP range resume, downloaded. Browsers download into a temporary Cache Storage staging area,
verifies its size and SHA-256, then renames it into the object cache. The active verify every object's byte count and SHA-256, and promote the pack to the active
logical-path map changes only after the complete pack verifies. An interrupted cache only after the complete pack succeeds. Android streams each object to a
or corrupt update leaves the previous pack playable. `.part` file, supports HTTP range resume, verifies its size and SHA-256, then
renames it into the object cache. An interrupted or corrupt update leaves the
previous pack playable on either platform.
The starter pack is bundled into the APK. Downloaded packs live under Android's The Downloads screen uses the same lifecycle in browser and Android. A missing
app-private files directory, outside the packaged web bundle, and survive an pack offers **Download**, an installed pack with changed files offers
APK update. Players may remove optional packs through the content manager; save **Update**, and an installed optional pack offers **Remove**. Required packs are
data is stored separately and is never removed with content. marked as included and cannot be removed. Browser packs live in the app-managed
cache; Android packs live in app-private storage and survive APK updates. Save
data and roster identities are stored separately and are never removed with
content.
Character packs are presentation-only. When a selected race's pack is absent,
removed, disabled, or fails to load, the shared character renderer uses the
matching-gender basic Human model and default appearance. The saved race, class,
equipment, progression, and appearance choices remain intact and become visible
again after the pack is installed.
Generated spell effects and synthesized combat cues are the default. The
`core:combat-media` pack containing packaged original spell visuals and sounds
is never part of required bootstrap content. Original mode becomes available
only after an explicit download and falls back to generated effects if the pack
is later removed.
## Offline behavior ## Offline behavior
@@ -87,6 +103,8 @@ data is stored separately and is never removed with content.
- The last verified content map is read synchronously from local storage. - The last verified content map is read synchronously from local storage.
- A failed update check is silent outside the content manager. - A failed update check is silent outside the content manager.
- A failed or interrupted download never replaces active content. - A failed or interrupted download never replaces active content.
- Missing optional character packs fall back to the basic Human model.
- Generated spell effects remain available without original spell media.
- Local saves are authoritative during play and cloud synchronization retries - Local saves are authoritative during play and cloud synchronization retries
when connectivity returns. when connectivity returns.
- Content that has never been downloaded is clearly marked as unavailable - Content that has never been downloaded is clearly marked as unavailable
@@ -104,9 +122,10 @@ Keeping the runtime in the APK is what makes offline startup reliable.
/mnt/usbssds/apps/healer-man/backups Database backups /mnt/usbssds/apps/healer-man/backups Database backups
``` ```
The Node server exposes the content volume at `/content`. Manifests use The Node server exposes the compact production browser client at `/` and the
`no-cache`; immutable hashed objects use long-lived cache headers and support complete downloadable-content volume at `/content`. Manifests use `no-cache`;
byte ranges for resumed downloads. immutable hashed objects use long-lived cache headers and support byte ranges
for resumed downloads.
After pulling source on TrueNAS, publish content before restarting the app: After pulling source on TrueNAS, publish content before restarting the app:
@@ -121,15 +140,29 @@ discover a manifest whose files have not been published.
## Pack policy ## Pack policy
Packs are player-facing groups while files remain individually addressable. Packs are player-facing groups while files remain individually addressable.
This permits a fast initial pack install and small later patches. Current pack This permits a compact initial install and small later patches. Required pack
IDs are derived predictably: IDs include:
```text ```text
core:runtime
core:ui
core:equipment
core:character-basic
dungeon:wailing-caverns dungeon:wailing-caverns
```
`core:character-basic` owns the two basic Human rigs, the character manifest,
and only the default texture selections needed by the fallback. The remaining
human customizations and every non-Human character model/skin are optional.
Downloadable pack IDs include:
```text
dungeon:forsaken-abbey dungeon:forsaken-abbey
characters:wow335a-v1 characters:wow335a-v1
characters:ascension-v1 characters:ascension-v1
characters:runewaker-v1 characters:runewaker-v1
core:combat-media
manastorm:<stage-id> manastorm:<stage-id>
shared:creatures shared:creatures
``` ```
+32 -19
View File
@@ -24,8 +24,9 @@ container, rebuilding `dist`, or pulling source must not replace the database.
TrueNAS Gitea stores the source repository and APK release attachments; it is TrueNAS Gitea stores the source repository and APK release attachments; it is
not the game database. not the game database.
Large runtime assets are published separately under `/app/content`. Android Large runtime assets are published separately under `/app/content`. Production
clients download verified content objects from `/content` and retain them in browser and Android clients download verified content objects from `/content`;
browsers retain them in an app-managed cache and Android retains them in
app-private storage for offline play. See `CONTENT_UPDATES.md` for the manifest, app-private storage for offline play. See `CONTENT_UPDATES.md` for the manifest,
atomic activation, compatibility, and rollback contract. atomic activation, compatibility, and rollback contract.
@@ -55,9 +56,10 @@ Container/host port:
``` ```
The Gitea bare repository is not runnable. Clone it with Git; never copy it The Gitea bare repository is not runnable. Clone it with Git; never copy it
with `cp`. The checkout contains several gigabytes of required GLB assets, so with `cp`. The checkout contains several gigabytes of content-source GLB assets,
the initial clone and first build will take substantially longer than later so the initial clone and first content publication will take substantially
fast-forward updates. longer than later fast-forward updates. Production browser and Android bundles
stage only their compact required-content subset.
Do not turn the GLBs into Git LFS pointers without also changing this deployment Do not turn the GLBs into Git LFS pointers without also changing this deployment
procedure. Gitea keeps LFS objects outside the bare repository, so a bare-path procedure. Gitea keeps LFS objects outside the bare repository, so a bare-path
@@ -80,7 +82,8 @@ git branch --show-current
If the repository slug differs, change both the remote URL here and every If the repository slug differs, change both the remote URL here and every
`healer-man.git` bare-repository path below. Do not commit `.env` files, `healer-man.git` bare-repository path below. Do not commit `.env` files,
keystores, API tokens, `content`, `dist`, `dist-android`, or `.android-public`. keystores, API tokens, `content`, `dist`, `dist-android`, `.web-public`, or
`.android-public`.
On TrueNAS, confirm the bare repository path. If the first command fails, use On TrueNAS, confirm the bare repository path. If the first command fails, use
the search command: the search command:
@@ -154,8 +157,9 @@ account/cloud-save data; `/app/content` owns downloadable manifests and
immutable content objects. Never mount a volume at `/app/data`, because that immutable content objects. Never mount a volume at `/app/data`, because that
would hide the checkout's required `/app/data/loot/schema.sql`. The would hide the checkout's required `/app/data/loot/schema.sql`. The
startup command installs locked dependencies, initializes the schema, publishes startup command installs locked dependencies, initializes the schema, publishes
new or changed content objects, builds the full browser bundle, and starts the new or changed content objects, builds the compact required-content browser
combined static/API/content server. Existing content objects are reused. bundle, and starts the combined static/API/content server. Existing content
objects are reused.
After startup, test on the LAN: After startup, test on the LAN:
@@ -185,6 +189,7 @@ on the development PC. Stop if any test or build fails:
```powershell ```powershell
Set-Location F:\Projects\HealerMan Set-Location F:\Projects\HealerMan
npm run release:check
$VersionName = '0.1.3' $VersionName = '0.1.3'
$VersionCode = 1003 $VersionCode = 1003
@@ -202,12 +207,13 @@ $ReleaseVersion = [ordered]@{
npm run content:test npm run content:test
npm run server:test npm run server:test
npm test npm test
npm run content:publish
npm run build npm run build
npm test -- --run src/avatar npm test -- --run src/avatar
npx vitest run src/game/inputManager.test.ts src/game/inputMath.test.ts npx vitest run src/game/inputManager.test.ts src/game/inputMath.test.ts
npm run release:check
git status --short git status --short
git diff --check
git add -A git add -A
git status --short git status --short
git diff --cached --stat git diff --cached --stat
@@ -217,10 +223,15 @@ git push origin main
git rev-parse HEAD git rev-parse HEAD
``` ```
`content:publish` is a fail-closed pre-build release check. It must report all
54 WoW campaign dungeon packs and refuses to replace the manifest when a pack,
dependency, or catalog-referenced asset is missing. Its local `content/` output
is ignored and must not be staged.
Before `git commit`, read the staged file list printed by `git status --short`. Before `git commit`, read the staged file list printed by `git status --short`.
Do not commit a `.env` file, password, API token, keystore, APK, database, Do not commit a `.env` file, password, API token, keystore, APK, database,
`content/`, `dist/`, `dist-android/`, or `.android-public/` output. The final `content/`, `dist/`, `dist-android/`, `.web-public/`, or `.android-public/`
command prints the exact deployed commit ID. output. The final command prints the exact deployed commit ID.
Next, open the TrueNAS Apps UI and **stop** `healer-man`. Open a TrueNAS shell Next, open the TrueNAS Apps UI and **stop** `healer-man`. Open a TrueNAS shell
and run these exact commands: and run these exact commands:
@@ -246,11 +257,12 @@ sudo git -C /mnt/usbssds/apps/healer-man/app rev-parse HEAD
The TrueNAS commit ID must match the one printed on the development PC. Start The TrueNAS commit ID must match the one printed on the development PC. Start
`healer-man` in the TrueNAS Apps UI afterward. Container startup `healer-man` in the TrueNAS Apps UI afterward. Container startup
publishes immutable content objects and replaces `manifest.json` only after all publishes immutable content objects and replaces `manifest.json` only after all
objects exist, then rebuilds the browser client and starts the server. Android objects exist, then rebuilds the browser client and starts the server. Browser
devices discover the small new manifest and download only missing or changed and Android clients discover the small new manifest and download only missing
files. Asset-only updates do not require a new APK. A failed fast-forward pull or changed files for packs the player installed. Asset-only updates do not
deliberately leaves the running checkout unchanged; resolve diverged history on require a new APK. A failed fast-forward pull deliberately leaves the running
the development machine rather than forcing the TrueNAS checkout. checkout unchanged; resolve diverged history on the development machine rather
than forcing the TrueNAS checkout.
After the logs say the server is listening on port `4173`, run on TrueNAS: After the logs say the server is listening on port `4173`, run on TrueNAS:
@@ -285,9 +297,10 @@ copies; it does not replace dataset-level protection.
## APK releases and Obtainium ## APK releases and Obtainium
Keep APK binaries out of the Git branch. The Android build uses `dist-android`, Keep APK binaries out of the Git branch. The Android build uses `dist-android`,
which contains the game runtime, UI, equipment, and Wailing Caverns starter which contains the game runtime, UI, starter equipment, basic Human character,
content rather than the full multi-gigabyte browser catalog. Downloaded packs and Wailing Caverns starter content. Optional character/skin packs, original
survive APK updates. spell media, dungeons, and other large content remain outside the APK.
Downloaded packs survive APK updates.
Install JDK 21 and Android SDK Platform 36 on the development PC and set Install JDK 21 and Android SDK Platform 36 on the development PC and set
`JAVA_HOME` plus `ANDROID_SDK_ROOT`. The build wrapper also recognizes the `JAVA_HOME` plus `ANDROID_SDK_ROOT`. The build wrapper also recognizes the
+110
View File
@@ -0,0 +1,110 @@
# Encounter authoring and fidelity
Healer Man keeps boss abilities, dungeon orchestration, presentation, and source
evidence separate. Boss abilities are modular `EnemyAttackDefinition` records;
dungeon-wide doors, waves, checkpoints, and transitions are modular
`DungeonEncounterDefinition` records. Neither runtime stores Three.js or React
objects, so the same definitions can later be selected or randomized without
rewriting a boss component.
## Adding or editing a boss mechanic
1. Add or edit the attack in the boss entity's `combat.attacks` list. Imported
RuneWaker lists are generated under `src/game/generated`; authored WoW
exceptions live with their dungeon content.
2. Give the mechanic a stable `id`, timing, condition, target, effect, and source
record. Health mechanics use `self-health-percent`; timed mechanics use
`initialCooldownMs` and `repeatCooldownMs`.
3. Author a `telegraph` when the source supplies geometry. Harmful area attacks
without explicit geometry receive a conservative circle/cone/line inference,
but inferred geometry is not described as source-exact.
4. Add a guide override only when the generated explanation needs encounter
context that cannot be derived from the mechanic. The Boss Guide otherwise
reads the runtime definition directly, including its trigger, timer, effect,
telegraph, counterplay, fidelity, and test procedure.
5. Run the focused mechanic, telegraph-geometry, campaign, timeline, and guide
tests, then perform the browser playtest described in `PLAYTEST_NOTES.md`.
Telegraph geometry is shared by presentation and hit resolution. A circle,
frontal cone, or line shown on the floor is therefore the area the resolver
tests when the cast completes. `warningMs` is also enforced as a minimum cast
time, so a telegraph cannot appear after its damage resolves.
## Adding a dungeon encounter rule
Attach a `DungeonEncounterDefinition` to `DungeonDefinition.encounters`. Rules
combine a trigger, optional guards, and reusable actions. Available primitives
cover tick/elapsed time, signals, interactions, entity engagement/death/health,
all-members-dead checks, phases, flags, counters, timers, spawn groups, dynamic
world-object state, objective completion, checkpoints, party teleports, loot,
and signal chaining.
Definitions and snapshots are JSON-safe and stable-ID based. Actions are
idempotent by default. Loot actions must use `persistence: "run"`; this prevents
a wipe or checkpoint reload from duplicating a reward. Declare encounter-owned
mob waves in `DungeonDefinition.encounterSpawnGroups`. Declare doors, switches,
chests, keys, bridges, NPC prompts, and quest objects in
`DungeonDefinition.serverGameObjects`; their collision, sight blocking, visual,
prompt, and allowed interaction states follow the current encounter snapshot.
Online groups use party-leader authority. A follower interaction is sent as a
request, then revalidated by the leader against the follower's synchronized
position, range, line of sight, object state, and object ID before any rule is
dispatched. The leader publishes serializable encounter snapshots to followers.
## Save behavior
Character profiles store a versioned safe dungeon checkpoint. The checkpoint
projection retains only actions marked `checkpoint` or `run`; active timers,
temporary waves, and a half-finished pull are reset. Entering the same dungeon
hydrates that safe projection and its spawn after definitions are registered.
Loading a different dungeon starts at its normal entrance.
## Source fidelity and remaining review
The deterministic ledgers are:
- `scripts/runewaker-pipeline/RUNEWAKER_ENCOUNTER_IMPLEMENTATION_REPORT.md`
- `scripts/runewaker-pipeline/RUNEWAKER_GAMEPLAY_CONTENT_REPORT.md`
- `scripts/runewaker-pipeline/RUNEWAKER_ENVIRONMENT_ASSEMBLY_REPORT.md`
- `scripts/runewaker-pipeline/RUNEWAKER_NAVIGATION_GAP_REPORT.md`
Current encounter evidence covers 30 RuneWaker packages, 4,113 deferred source
rows, and 1,524 unique direct evidence records. Of those evidence records, 388
have exact executable spell mappings and 1,136 still need source review. Four
bosses have clearly labeled, playable Healer Man fallback kits because the
preserved data does not expose their original executable behavior. Eight
non-empty packages do not contain source-confirmed boss membership; two
authoritative variants are intentionally empty.
The upgraded WDB environment builder can assemble all referenced ROS resources
with full placement translation, quaternion, and nonuniform scale, source-hash
caching, shared meshes, collision chunking, and a separate dynamic-placement
manifest. The integration pass regenerated Raksha Temple and The Origin through
that full-WDB path; remaining shipping packages retain their last validated
build until they are individually regenerated. The current audit finds 107
filename-only dynamic candidates; they remain static and review-required
because filenames alone do not prove door/switch behavior.
Treasure Trove's 908-placement full-WDB staging export is reproducible and its
487,380-triangle visual/collision assembly, meshopt pass, and KTX2 compression
all succeed. Its 0.3-metre, 512-cell full-resolution Recast navigation bake did
not complete: the watershed run was stopped after nearly two CPU-hours when it
showed the smaller-tile retry signature, and the explicit monotone run was
stopped after more than four CPU-hours on its first pass. The fail-closed
pipeline therefore did not publish that staged package. The last validated
shipping package remains active. The recipe retains the monotone tiled policy
for a future offline bake or a reviewed spatial-partitioning optimization;
lowering navigation resolution was not silently substituted.
The route report contains 19 unreachable legs across eight dungeons, all from a
distance-from-entrance objective-order heuristic. Those legs are evidence that
objective order needs review, not proof that an off-mesh link should exist.
Links are added only when source geometry or a reviewed traversal justifies
them.
Run `npm run runewaker:audit:gameplay`, `npm run
runewaker:audit:environment-assembly`, and `npm run runewaker:audit:navigation`
after importing new source data. A report can be structurally green while its
content status remains `review-required`; this is intentional and prevents an
incomplete source inference from being presented as an original mechanic.
+546
View File
@@ -4,6 +4,134 @@ This file is the durable record of runtime behavior, regressions, and the
evidence required before calling a visual bug fixed. Update it whenever scene, evidence required before calling a visual bug fixed. Update it whenever scene,
camera, input, physics, mob-rendering, or asset-loading code changes. camera, input, physics, mob-rendering, or asset-loading code changes.
## 2026-08-18 GM Manastorm administration - COMPLETE
- Server-authorized `Phenom` access, revisioned SQLite configuration, safe
all-Needs-tested defaults, public/offline caching, optimistic conflicts, and
denial/revision logging were exercised through the production HTTP surface.
- The GM hub exposed all 406 deduplicated boss records, readiness and runnable
state, pool filters, six global switches, dungeon entry, placement editing,
and GM tests. A fresh revision correctly reported zero Ready bosses.
- Live Wailing Caverns authoring captured and nudged the shared group anchor,
displayed derived party, boss, portal, and exact linked-mob data, and saved a
three-mob / two-kill Chaotic Link stage. The desktop Save control was moved
above the Tactical control after the playtest found their hit targets
overlapping; a normal semantic click then published the next revision.
- Promoting an imported encounter directly to Ready initially exposed missing
stage materialization at the server boundary. The readiness transition now
persists its complete inherited stage. Cross-mode duplicates also merge
their mode memberships, so a boss imported for both leveling and end-game is
represented once and remains eligible in both modes.
- Live pool acceptance promoted Lady Anacondra and Burning Felguard, entered a
level-1 public Manastorm, then marked the active Lady Anacondra record Not
ready from a parallel GM client. The existing run retained Lady Anacondra and
its two-stack Chaotic Link snapshot; after reload, the next run selected only
Burning Felguard. This verified new-run publication and active-run
immutability together.
- Desktop and Thor-preview passes rendered the DOM editor over the dungeon,
retained camera/game separation while the panel was open, and exposed the GM
pause-menu entry. Console inspection found no errors and only the existing
third-party initialization deprecation warning.
- Verification passed: server **7/7**, full Vitest **121 files / 699 tests**,
TypeScript, production build, and the KTX2 audit of 11,839 compressed textures
with zero fallbacks. The build retained the existing informational
large-chunk advisory.
- Evidence: `playtest-artifacts/2026-08-18-gm-manastorm-admin/desktop-admin-hub.png`,
`desktop-world-editor-final.png`, and `thor-world-editor.png`.
## 2026-08-17 authentic combat VFX and audio - COMPLETE
- Player, party, and enemy combat actions now publish transient presentation
phases without changing combat resolution. The scene consumes those events
through bounded pooled effects (High: 64 systems / 8,192 particles; Low: 24
systems / 2,048 particles with no effect lights), while Off skips visual
spawning. Actor-group switches clear live systems and voices immediately.
- The generated source catalog covers 6,383 runtime spell/skill IDs: 5,144
resolve to preserved WoW/Ascension/RuneWaker descriptors and the remaining
1,239 are explicit school/delivery fallbacks. All 38 referenced source sound
paths resolve to 32 deduplicated packaged clips (6,365,096 bytes); the audit
reports no missing packaged assets.
- Owner settings migrated to local profile database v3 and remain independent
of character gameplay settings. Options exposed High/Low/Off, independent
Player/Party/Enemy visual switches, and independent audio mute/volume rows.
The existing master volume also controls combat and Manastorm cues.
- Live Wailing Caverns verification entered through the offline roster as a
Human Priest healer. The entrance fight visibly presented party melee/ranged
effects and enemy actions. A High-quality Smite capture showed the player
cast system alongside party effects; Low-quality Lesser Heal showed the
reduced healing system; Off-quality Shadow Word: Pain showed combat state,
aura/combat text, and damage continuing without spawned VFX. Defaults were
restored to High after the pass.
- At a 390 x 844 mobile viewport, the Options dialog measured 362 px wide with
345 px of scroll content and no document overflow. Player frame, party list,
minimap, and action bar all remained inside the viewport. A discovered narrow
Options text/control overflow was fixed by allowing grid labels to shrink and
moving combat-audio controls onto a full-width narrow-screen row.
- Verification passed: combat-effects parser/coverage audit **4/4**, focused
persistence/event/cue/UI suites **68/68**, full Vitest **118 files / 674
tests**, TypeScript, production build, and Android web build. Both builds
retained the existing informational large-chunk advisory; the browser console
had no errors and one existing third-party initialization deprecation warning.
- Evidence: `playtest-artifacts/2026-08-17-combat-presentation/desktop-high-combat.png`,
`desktop-player-smite.png`, `desktop-low-heal.png`, `desktop-off-combat.png`,
`desktop-options.png`, `mobile-combat-controls.png`, and
`mobile-high-combat.png`.
- Coverage limit: browser automation exercised Web Audio creation, group
routing, mute, volume, and authentic clip loading but cannot judge perceived
loudness or spatial balance; that final acoustic judgment still requires a
listening pass on physical desktop/mobile speakers.
## 2026-08-17 dungeon proximity aggro and range overlay - COMPLETE
- Idle dungeon enemies now check the living player and party positions during
the low-frequency combat tick. Crossing a mob's radius engages its complete
linked pack through the normal threat path, anchors each member at its pull
position, and seeds initial threat on the nearest actor who crossed the line.
- Normal enemies default to a 16-unit aggro radius and bosses to 20 units;
creature definitions can override either value. Proximity uses full 3D
distance so vertically overlapping dungeon floors do not pull one another,
while the existing planar combat leash continues to support uneven terrain.
- Options now includes `Mob aggro ranges`, defaulting to Off and persisting with
the rest of the account gameplay settings. When enabled, idle dungeon mobs
render restrained orange world-space boundaries above uneven terrain. Rings
disappear once their mob engages and are never rendered in Manastorm.
- Focused verification passed: `src/game/combatStore.test.ts` and
`src/game/mobAi.test.ts`, **2 files / 60 tests**. `npx tsc -b --pretty false`
passed, and `npx vite build` passed with 960 transformed modules.
- Live browser verification entered Wailing Caverns as a healer through the
offline roster. With the party left in Defend and no player attack issued,
the entrance pack automatically acquired and damaged Garrick. The Options
dialog showed the new setting Off by default; matched scene captures then
confirmed visible range rings when On and their removal when toggled Off.
- The browser console contained no errors and one existing third-party
initialization deprecation warning. The local Vite host separately recorded
the known optional `/content/manifest.json` proxy refusal because the content
server on port 4173 was not running; packaged dungeon play was unaffected.
## 2026-08-17 Kresh cliff-pull aggro regression - COMPLETE
- Reproduced the reported reset with a deterministic combat-store regression:
Kresh registers at one end of his long patrol, moves to a later patrol point,
takes damage while the player is falling well above him, and advances combat
after the player reaches the lower grotto.
- Roaming mobs now anchor their leash at their runtime position when a new pull
starts instead of retaining the position where their model first mounted.
Aggro leash eligibility uses planar dungeon distance, matching the existing
mob-AI rule, while attack reach still includes vertical separation. A real
horizontal leash break continues to evade and restore the encounter.
- Focused verification passed: `src/game/combatStore.test.ts` and
`src/game/mobAi.test.ts`, **2 files / 58 tests**. `npm run build` also passed,
including TypeScript, 956 transformed Vite modules, and the KTX2 audit of
11,839 compressed textures with zero fallbacks.
- Production-preview smoke testing entered Wailing Caverns through the offline
roster, rendered the full dungeon/HUD/party view, issued the Attack order,
and observed live enemy damage on the tank. This checkout lacks the optional
local playable-character and creature model packs, so the documented
procedural fallbacks and their asset warnings were visible during this pass.
- Coverage limit: the exact cliff jump was validated by the deterministic
combat-state regression rather than by manually traversing from the entrance
to Kresh during the browser smoke test.
## 2026-08-16 responsive jump and natural teammate movement - COMPLETE ## 2026-08-16 responsive jump and natural teammate movement - COMPLETE
- Added the grounded single-jump path for Space and controller L3, including a - Added the grounded single-jump path for Space and controller L3, including a
@@ -1293,3 +1421,421 @@ Vite's existing large-chunk advisory remains informational.
- Verification: 38 focused party/pathing/jump/animation tests passed, all 28 - Verification: 38 focused party/pathing/jump/animation tests passed, all 28
avatar tests passed, and `npm run build` completed successfully with 954 avatar tests passed, and `npm run build` completed successfully with 954
modules transformed. The existing large-chunk advisory remains informational. modules transformed. The existing large-chunk advisory remains informational.
# 2026-08-20 — shared online dungeon session with AI fill
- Ran two signed-in production clients against the local account server on
separate browser origins. **SharedLeader / Bulwarka** invited
**SharedMember / Mendara**; the accepted group roster showed both selected
characters and their Tank and Healer roles as ready.
- The leader launched Wailing Caverns with **Fill open slots with AI** enabled.
Both clients automatically entered the same activity, each rendered the
other player through the normal equipped `CharacterModel` path, and each
showed a live, targetable remote party frame. Three AI companions filled the
remaining slots, producing the expected five-member party on both clients.
- The reciprocal scene captures showed Bulwarka and Mendara at the same shared
dungeon position with matching environment, objective, AI roster, mob state,
and remote role labels. The leader client continued encounter simulation;
the member client received the synchronized mob and AI state without running
a second competing world simulation.
- From the member client, selected Bulwarka's online party frame and completed
a Lesser Heal cast. The member's mana/resource change propagated to the
leader client and both clients retained the same live remote health state.
Enemy combat and AI resource/health changes also continued to propagate while
the two clients remained connected.
- Evidence reviewed during the browser run: invitation/group roster DOM,
coordinated-launch DOM from both clients, reciprocal full-window dungeon
captures, and before/cast-complete remote-healing DOM snapshots. No missing
character-body or equipment fallback appeared in either dungeon capture.
- Verification: server/API tests passed all 11 cases, the complete Vitest suite
passed all 755 cases across 132 files (including the 28 avatar cases), and the
TypeScript production build completed successfully with 983 modules
transformed. The existing large-chunk advisory remains informational.
# 2026-08-28 — configurable render caps and idle-loop efficiency
- Opened the saved Human Priest roster after a fresh client reload. The full
body and starter staff rendered correctly in the single character-preview
canvas, which reported the persisted 30 FPS preview cap and manual frame loop.
- Entered Wailing Caverns as healer and exercised the gameplay setting live.
The performance probe settled at about 30.5 FPS for the 30 FPS option and 60
FPS for the 60 FPS option; combat and fixed-step physics continued normally.
- Pausing switched the dungeon canvas to demand rendering. Its performance
counters remained byte-for-byte unchanged over 1.4 seconds, confirming that
the local paused scene did not keep rendering in the background.
- Returned gameplay rendering to the default 60 FPS and left the character
preview at 30 FPS. Evidence reviewed during the browser run included the
roster-preview and live dungeon screenshots. The final fresh session emitted
no errors; the existing third-party initialization deprecation warning
remained non-blocking.
- Verification: the focused efficiency tests passed all 83 cases, all 28 avatar
tests passed, the complete Vitest suite passed all 809 cases across 148 files,
and the production build completed with 1,043 modules transformed. KTX2 and
environment-performance audits remained green; the existing large-chunk
advisory remains informational.
# 2026-08-30 — authored weapon grips and ready stances
- Reloaded the offline client and switched a Human female preview directly
between Hunter, Warrior, and Priest. The bow, sword/shield, and staff changed
immediately to their native HoldBow, Ready1H, and Ready2HL poses; no stale
class pose or backward procedural axis remained.
- Verified RuneWaker Human Warrior and Scout previews against their explicit
hand/shield locator frames. The one-hand, shield, and bow silhouettes used the
RuneWaker socket-axis adapter and remained proportionate to the character.
Also checked the Ascension Human Ranger fallback with its bow visible in a
supported ready pose.
- The saved Human Priest roster preview showed the complete body and staff with
both hands aligned to the shaft. In Wailing Caverns, the player and party
equipment remained attached through live combat animation without a second
local weapon swing or load-time placement jump.
- Evidence: `playtest-artifacts/2026-08-30-weapon-grip/weapon-grip-roster.png`,
`human-hunter-holdbow.png`, `human-warrior-ready1h.png`,
`human-priest-ready2hl.png`, `runewaker-warrior-sockets.png`,
`runewaker-scout-bow.png`, `ascension-ranger-bow.png`, and
`weapon-grip-dungeon.png`.
- Verification: all 41 avatar tests passed, the 37-test focused weapon/stance
suite passed, and the production build completed with 1,047 modules
transformed. Asset audits remained green with zero KTX2 fallbacks and zero
environment-performance regressions; the existing large-chunk advisory
remains informational.
# 2026-08-30 — bounded combat VFX bursts and silent audio default
- Created a fresh offline Human Priest and confirmed the in-game Options panel
opened with **Master volume** at 0%. Gameplay and preview frame-rate controls,
VFX quality, and per-actor VFX/audio controls remained available.
- Entered Wailing Caverns as healer, sent the party into combat, and captured a
live four-effect spell burst. High quality reported four active effect systems
and zero combat point lights; additive particles, impacts, melee arcs, the HUD,
and combat telegraphs remained visible.
- The captured burst reported 60 FPS, a 16.7 ms average frame, a 16.8 ms slowest
frame, 258 draw calls, and 353,526 triangles at 1.5 pixel ratio. A three-second
combat sample reached five concurrent effects, stayed between 54.1 and 60 FPS,
and returned to a 16.7 ms frame average.
- A cold Vite dynamic import failed once while first opening character creation;
reloading after compilation resolved it. The final dungeon run had no further
errors; the existing third-party initialization deprecation warning remained.
- Verification: the complete Vitest suite passed all 839 cases across 153 files,
the production build completed with 1,047 modules transformed, KTX2 and
environment-performance audits remained green, and the release-candidate
check passed. The existing large-chunk advisory remains informational.
# 2026-08-31 — Shadowfang Keep navigation freeze regression
- Reproduced the reported freeze with the saved Human Priest at the Shadowfang
Keep entrance. The visible scene fell to roughly 4–11 FPS with 91–225 ms
average frames and repeated 500+ ms slow frames, without a runtime exception.
- Traced the stall to synchronous construction of the provisional 545,171-
triangle party-navigation graph after the dungeon became visible. A direct
benchmark blocked the main thread for roughly 8 seconds and consumed about
800 MiB of heap; its subsequent entrance surface/path queries also failed.
- Added a navigation policy that keeps reviewed, budgeted graphs enabled while
unvalidated or over-50,000-triangle graphs use the existing local and
breadcrumb party-follow fallback. Shadowfang therefore avoids the unusable
graph, while Wailing Caverns retains its reviewed navigation.
- Re-entered Shadowfang from a clean reload and kept the live scene open beyond
the former graph-build window. Eight consecutive samples held 59–60 FPS at
about 16.7 ms per frame; the slowest final sampled frame was 25.8 ms. The party,
HUD, minimap, combat state, and full environment remained responsive and
visible in the reviewed screenshot. No new browser errors were emitted.
- Verification: all 20 focused navigation cases passed, the complete Vitest
suite passed all 844 cases across 154 files, the production build completed
with 1,048 modules transformed, KTX2 and environment-performance audits
remained green, and the release-candidate check passed. The existing
large-chunk advisory remains informational.
# 2026-08-31 — dungeon-fleet startup freeze audit
- Audited the complete registered fleet: 84 regular-dungeon navigation assets,
all 75 Manastorm package assets, and all 470 published Manastorm stages. Every
referenced navigation GLB exists and parses. Under the reviewed 50,000-
triangle policy, 31 regular and 41 Manastorm package graphs remain enabled;
the other 53 regular and 34 Manastorm packages use breadcrumb following.
- Added an actual-geometry triangle check before navigation allocations. This
prevents stale catalog metadata from bypassing the synchronous-build ceiling;
Wailing Caverns metadata was corrected from 32,077 to 45,732 triangles.
- Found nine zero-length imported patrol routes that could throw during scene
render: one in Scholomance, two in Botanica, two in Magister's Terrace, and
four in Escape from Durnholde. Catalog generation now preserves those actors
as static spawns, and runtime normalization provides the same defense for
future malformed imports. All remaining 752 regular patrols and every
effective Manastorm stage patrol have usable routes.
- Live entrance checks loaded Scholomance, Escape from Durnholde, and Forgotten
Mine without a scene error or startup freeze. Scholomance settled near 28.5
FPS at 946 draw calls; Durnholde near 29 FPS at 3,663 draw calls; Forgotten
Mine near 50 FPS at 1,502 draw calls after staged loading. These identify
remaining environment/population throughput work, but are separate from the
fixed startup-crash and synchronous-navigation failure modes.
- Verification: the complete Vitest suite passed all 850 cases across 155
files, the production build completed with 1,048 modules transformed, all
106 environment assets passed their performance audit with no regressions,
the KTX2 audit found no fallback textures, and the release-candidate check
passed. The existing large-chunk advisory remains informational.
# 2026-09-04 — optional content offload and basic Human fallback
- Built and served the production browser output from a clean localhost origin.
A fresh Undead female Priest preview rendered with the real bundled Human
female rig and default textures while retaining the Undead/Priest identity in
the roster. No optional character pack had been installed.
- Entered Wailing Caverns as healer from a separate clean browser origin. The
Undead player, Undead tank, and Goblin party member all rendered through the
matching basic Human fallbacks while their saved race, role, class, equipment,
and party labels remained intact. The dungeon stayed playable and emitted no
new error; only the existing third-party initialization deprecation warning
appeared.
- Exercised the browser Downloads lifecycle with a small local two-revision
content fixture. Missing character and original-media packs showed Download;
a verified install showed Remove; the changed revision showed Update and
Remove together; and applying Update returned the pack to offline-ready state.
- Reloaded after service-worker activation. The application and lazy JavaScript
chunks loaded normally, while the content worker continued to reserve managed
character, creature, equipment, game, and UI paths for bundled or verified
cached content. The initial broad `/assets/` interception found during this
playtest was corrected before the final run.
- In-dungeon Options showed Generated as the active default, kept Original
disabled until its optional spell-effects-and-sounds pack is downloaded, and
exposed a Download action for that pack.
- Evidence:
`playtest-artifacts/2026-09-04-optional-content/roster-undead-priest-basic-human-fallback.png`,
`dungeon-optional-models-basic-human-fallback.png`,
`browser-downloads-optional-packs.png`, and
`browser-downloads-update-and-remove.png`.
- Verification: all 43 avatar tests passed; the complete Vitest suite passed all
896 cases across 164 files; production browser and Android builds completed;
both binary inventories contained only the two Human rigs, starter equipment,
and Wailing Caverns content; and neither output contained optional character
packs, original combat media, or WAV files. KTX2 and environment-performance
audits remained green, and the release-candidate check passed. The existing
large-chunk advisory remains informational.
# 2026-09-05 — Power Word: Shield live character anchoring
- Installed the optional Original Spell Effects & Sounds pack through the
production Downloads screen, enabled it, and selected Original spell visuals.
- Entered Wailing Caverns as a Human Priest and cast Power Word: Shield on both
the party tank and the player while exercising party movement and combat. The
persistent original aura stayed at the rendered character root instead of
following the throttled gameplay-position snapshot, with no inherited camera
or character rotation.
- Reviewed live dungeon screenshots before and during the movement test. The
browser emitted no new errors; only the existing third-party initialization
deprecation warning remained.
- Verification: all 899 Vitest cases passed across 165 files, including three
new visual-anchor registry cases. The production build completed with 920
modules transformed, and asset audits remained green. The existing
large-chunk advisory remains informational.
# 2026-09-05 — modular RuneWaker boss mechanics
- Built a temporary local production content feed for Forsaken Abbey and the
first two Ystra Labyrinth boss rooms, then installed each pack through the
browser Downloads workflow with checksum verification.
- Loaded the source-backed Specter Guardian Creator encounter. Its mechanic
panel appeared below the minimap and buff/debuff strips with Guard Bomb,
Transport Magic, and Meteor Shower countdowns. A live Meteor Shower cast
showed its one-second cast warning over the boss.
- The first pass exposed that four countdown rows could crowd the boss's
pending 80%, 60%, 40%, and 20% phase triggers out of the panel. The timeline
now limits only countdown rows and always retains every pending health
threshold. The corrected production build displayed all eight rows without
covering the central playfield.
- Loaded Rune Guardian Leader in Ystra Labyrinth Boss Room 2. Its source-backed
Manastorms Duo Lv5 mechanic displayed a large purple circular floor warning
while the matching panel row counted down at 0.6 seconds. The area indicator,
cast timing, party damage, and effect/debuff presentation all advanced in the
live encounter.
- Browser logs contained no uncaught application errors. The existing
third-party initialization deprecation warning remained; WebGL context-lost
messages corresponded to intentional production rebuild reloads and opening
replacement test tabs.
- Verification: the full suite passed all 913 cases across 169 files, and the
corrected production build completed with 923 modules transformed. KTX2 and
environment-performance audits remained green, and the release-candidate
check passed.
# 2026-09-05 — specialization-aware heirlooms and endgame loot
- Activated the legacy level-10 Priest `Rolecheck`. The mandatory Class Hall
picker appeared before the main menu, offered Discipline, Holy, and Shadow,
and presented Cancel, Keep talents, and Reset talents after choosing Holy.
Keeping talents returned to the main menu with the specialization saved.
- Opened Wailing Caverns from Dungeon Finder. Role selection was restricted to
Healer, matching the saved Holy specialization; no Tank or DPS override was
available.
- Reviewed the roster preview and a live Wailing Caverns combat scene. The
player body, staff, and all four AI party bodies/equipment silhouettes were
visible and correctly anchored without obscuring the HUD or playfield.
- Opened Inventory & Equipment in the dungeon. The player had zero earned
items but every applicable slot resolved to a level-10 Priest healer
heirloom and reported average item level 10. Morvane, the Blood Death Knight
companion, showed a complete tank heirloom loadout with the intended
two-handed weapon layout and empty conflicting slots.
- Browser logs contained no uncaught application errors. Only the existing
third-party initialization deprecation warning appeared.
- Automated coverage validates every classic and CoA specialization, Feral
Bear/Cat separation, RoM-derived profiles, player and party scaling caps,
same-level catalog dominance at levels 1/40/79, real item-level-85 upgrade
availability for every gear archetype, two-hand replacement scoring,
fallback reappearance, percentage-preserving stat refreshes, specialization
persistence and talent reset behavior, and the item-level-255 save limit.
- Verification: the complete Vitest suite passed all 928 cases across 171
files, including all 43 avatar cases. All 15 server persistence/API tests
passed. The production build completed with 925 modules transformed, KTX2
and environment-performance audits remained green, and the release-candidate
check passed. The existing large-chunk advisory remains informational.
# 2026-09-07 — modular encounter completion and boss guide
- Entered Wailing Caverns through the live offline roster and verified the 3D
dungeon, party HUD, minimap, and buff/debuff strips remained readable. The
encounter timeline occupies the same top-right HUD column beneath those
elements, keeping timed casts and pending health thresholds out of the
central playfield.
- Opened the new Boss Guide from the in-dungeon pause menu. The three-column
field manual listed both WoW and RuneWaker dungeons, their bosses, source
provenance, triggers, timings, target/effect descriptions, warning geometry,
counterplay, and a concrete test procedure for every listed mechanic.
- Selected Archaedas in Uldaman and confirmed all four authored mechanics:
Awaken Earthen Custodian every 10 seconds, the two-second 18-metre Ground
Tremor warning circle, six Earthen Guardians at 70% health, and two Vault
Warders at 40% health. Bosses with no sourced special attack are explicitly
labelled with zero special mechanics instead of receiving invented behavior.
- The encounter authoring layer now drives serializable timers, health gates,
guards, actions, summon groups, chained signals, stateful world objects,
teleports, rewards, checkpoints, and online leader-authoritative interaction
validation. Harmful area mechanics use the same geometry for both the world
warning and hit resolution.
- Browser review found no visible layout or interaction regressions. The only
previously observed browser message remains Rapier's third-party
initialization deprecation warning.
- Source limitations and the exact remaining RuneWaker evidence, navigation,
formula, loot, animation, and asset-fidelity gaps are recorded in the linked
deterministic audit reports and authoring documentation rather than silently
approximated.
- Full-WDB environment packages for Raksha Temple and The Origin completed and
passed their GLB gates. Treasure Trove's 908-placement visual/collision stage
also completed, but its full-resolution 36-tile Recast bake did not terminate
after nearly two CPU-hours on the watershed path and more than four CPU-hours
on the monotone path. The fail-closed pipeline preserved the prior validated
shipping package; this remaining offline bake is documented in
`ENCOUNTER_AUTHORING.md` instead of lowering navigation resolution.
- Verification passed: the complete Vitest suite passed all 981 cases across
185 files; online authority passed all 4 server cases; RuneWaker gameplay,
encounter, environment, navigation, formula/loot, and animation audits passed;
and the production build completed with 955 modules transformed. The KTX2
audit covered 12,347 compressed textures with zero fallbacks, and the
environment-performance audit found no regressions. The existing large-chunk
advisory and Rapier initialization deprecation warning remain informational.
# 2026-09-08 — WoW dungeon production-functionality audit
- Audited all 54 WoW five-player catalog entries against live runtime contracts,
pinned AzerothCore population/object drafts, and instance-script source. The
composed-runtime content audit is green for 1,193 mobs, 273 bosses, 4,026
attacks, 2,572 specials, and 1,275 native models, but the stricter production-
fidelity gate remains blocked at 0/54.
- The audit found 3,943 source game-object spawns, including 2,321 actionable
doors, buttons, chests/resources, transports, traps, and related objects. Raw
database rows are no longer passed into the typed world-object renderer; all
54 live definitions now have zero malformed world-object records.
- The follow-up implementation sweep completed source review for all 54
instances. Fifty-one now have runtime-wired instance orchestration and the three
genuinely empty stock instance scripts are pinned as source-exact no-ops;
there are no unreviewed instance scripts left. Wailing Caverns remains the
only entry with a reviewed off-mesh link, and the three Ascension-specific
dungeons still lack authoritative server population data.
- Entered Wailing Caverns from the local browser roster as a Priest healer. The
3D environment, populated combat route, party, objective, minimap, and HUD all
loaded; the minimap strip showed one Power Word: Fortitude entry. No uncaught
client runtime errors appeared. Rapier's existing initialization deprecation
warning remained informational.
- The local content manager exposed all 54 WoW entries but only Wailing Caverns
was installed; the other 53 were marked download required. Those dungeons were
therefore checked by source/runtime-contract audit in this pass, not claimed
as completed visual traversal playtests.
- The follow-up world-object compiler converted all 3,943 source rows—including
all 2,321 actionable doors, chests/resources, switches, traps, and
transports—into stable typed definitions with transformed coordinates,
type-aware states, conservative dimensions, and source/template/spawn/type
provenance. Wailing Caverns receives its 57 generated records through the
authored-definition enrichment path as well.
- Client `GameObjectDisplayInfo` metadata resolves a visual display ID for
3,905 records, a native model path for 3,837, and exact bounds for 3,547. The
generated export manifest deduplicates those instances into 458 native legacy
assets, records 38 intentional no-display spell-focus objects, and isolates
the remaining nine missing-model display IDs and 68 no-bounds display IDs for
review.
- An initial live pass exposed colored procedural markers for adapted
chests/resources. Unreviewed source objects are now deliberately hidden,
non-blocking, and non-interactive so incomplete door scripts cannot soft-lock
a dungeon and placeholder art cannot leak into normal play. A second live
Wailing Caverns pass confirmed the clean 3D scene, party combat, HUD, minimap,
and single Fortitude entry. No uncaught client errors appeared; duplicate
KTX2-loader warnings occurred only across deliberate hot-reload cycles.
- The final runtime audit reports 54/54 reviewed dungeons. Fifty-one dungeons use
52 rule-bearing instance-controller definitions (Blackrock Spire has separate
lower- and upper-spire controllers), while three use verified source-exact
no-op scripts. Every catalog objective has a completion action, and the audit
found zero malformed-object, duplicate-id, or encounter-contract issues. All
51 rule-bearing dungeons retain explicit adaptation/gap notes; native object
models and full-route live traversal are not claimed complete.
- The source-combat follow-up gives every runtime-spawnable boss a sourced kit
unless the pinned source really is melee-only. The six deliberate exceptions
are Kresh, Deviate Faerie Dragon, Spirestone Battle Lord, Spirestone Butcher,
Crystal Fang, and Grubbis. Crystal Fang retains its source-exact 15% rare-spawn
behavior and death summon. Trial of the Champion, Utgarde Keep, Hellfire
Ramparts, Sethekk Halls, Mana-Tombs, and Slave Pens event bosses now use their
pinned spell IDs and timing windows; unsupported vehicle, proc, queue, shared-
health, phase, stack, and healing-reduction semantics are explicitly recorded
as adaptations instead of being silently invented.
- Wipe/reset validation exhaustively covered 673,664 reachable encounter states,
180 reset paths, every one of the 68 non-initial reset targets, and all 135
entity-timeout rules. Durable progression now fails closed on a missing entity,
legacy snapshots with unordered action history fail closed, and Frozen Reach's
Arktos is attempt-scoped so a wipe respawns him and can still advance the duo
encounter on the next pull. The two viable post-reset resume states in Scarlet
Cathedral and Halls of Stone are intentional, not soft locks.
- Same-process checkpoint restore and online follower hydration now accept their
trusted save/leader snapshots even when a retained local provider has a newer
reset revision; ordinary stale imports remain rejected. A renderer restart
preserves the current encounter snapshot. Encounter effects use one delivery
path at a time, and obsolete headless queues are cleared on reset or dungeon
switch instead of retaining already-applied envelopes for the process lifetime.
- The generated download topology now contains an installable logical pack for
every one of the 54 campaign dungeons. The three custom dungeons without their
own creature payload are represented by dependency-only packs, while every
non-bundled dungeon pulls its exact environment and shared-creature closure.
The existing live content feed was not deployed or mutated during this pass;
browser traversal therefore still reflects the packs already available there.
- Installed packs now persist v2 verification receipts containing their exact
file set, byte counts, hashes, and dependencies. Browser-cache and native-file
presence are revalidated before entry, production dungeon entry fails closed
when a pack or dependency is missing or stale, and `content:publish` validates
the complete 54-dungeon dependency graph before any release output is written.
- Run completion now leaves the final room active so loot can be collected before
the player explicitly exits and clears the checkpoint. A wipe returns the party
to the saved run spawn while preserving already-cleared bosses and durable run
progress; attempt-scoped actors and effects reset for the next pull.
- The live Priest check used the saved `Rolecheck` character, which advanced from
level 11 to level 12 during the dungeon passes. The latest Wailing Caverns run
displayed 677/677 health, one Power Word: Fortitude alongside Arcane Intellect
(and Holy Concentration while active), and one Frostbolt plus one Icy Touch
debuff. Repeated Frostbolt applications refreshed that one entry from 7.1 to
21 seconds rather than duplicating it. The deterministic geared level-8 check
produced 3,285 mana and increased health from 407 to 437 when Fortitude was
applied.
- Verification remains deliberately split: source coverage, runtime contracts,
reset reachability, and automated behavior are green, while the combined
production-fidelity audit remains 0/54. Its remaining blockers include native
object export/collision, explicitly listed source-semantic gaps, and end-to-end
traversal evidence for every production pack—not unfinished instance-script
review.
- Final release verification passed all 1,109 Vitest cases across 202 files,
TypeScript project compilation, and the production build with 967 modules
transformed. The build staged 5,587 browser-bootstrap files, validated all
eight arenas, audited 12,347 compressed textures with zero fallbacks, and found
no environment-performance regressions. The release-candidate check accepted
all 118 changed paths. The existing large-chunk advisory and Rapier
initialization deprecation warning remain informational.
+52 -12
View File
@@ -41,6 +41,32 @@ npm test
npm run build npm run build
``` ```
Boss-mechanic and dungeon-event extension points, telegraph rules, checkpoint
behavior, test workflow, and the explicit source-gap ledger are documented in
[`ENCOUNTER_AUTHORING.md`](ENCOUNTER_AUTHORING.md).
## Content downloads
Production browser and Android builds ship a compact required set: the game
runtime, interface, starter equipment, Wailing Caverns starter content, and a
basic male/female Human character model with its default appearance. Large
character and skin libraries, additional dungeons, Manastorm stages, and the
original spell-effects and sound pack are optional downloads.
Open **Downloads** from the main menu to download, update, or remove optional
packs on either platform. Browser downloads live in an app-managed verified
cache; Android downloads live in app-private storage. Removing a pack never
removes a roster or save. If a character's model/skin pack is unavailable, the
shared character renderer displays the matching-gender basic Human while
preserving that character's identity and progress for a later reinstall.
Generated spell effects and synthesized combat cues are the default and need
no original-media download. Players who want the packaged original visuals and
sounds can download that pack explicitly, select **Original** effects, and
remove the pack again to reclaim its storage. See
[`CONTENT_UPDATES.md`](CONTENT_UPDATES.md) for the content lifecycle and release
contract.
## Conquest of Azeroth classes ## Conquest of Azeroth classes
All 21 CoA classes use a checked-in live Vol'Jin catalog generated from All 21 CoA classes use a checked-in live Vol'Jin catalog generated from
@@ -81,12 +107,23 @@ validates the relational data and ships both a browser-safe JSON catalog and
for a future loot-browser screen. for a future loot-browser screen.
Every Wailing Caverns boss rolls one item when it dies. The item instance Every Wailing Caverns boss rolls one item when it dies. The item instance
captures the player's level at the killing blow, remains on the corpse until captures its item level at the killing blow, remains on the corpse until
looted, and is then saved in that character's inventory. The SQL loot source looted, and is then saved in that character's inventory. Drops use character
contains the original 3.3.5a attributes, ratings, armor, block, weapon damage, level through 79; level-80 drops begin the first endgame tier at item level 85.
weapon speed, regeneration, and spell-power values for each item. A scaled The SQL loot source contains the original 3.3.5a attributes, ratings, armor,
drop preserves that original stat distribution instead of replacing it with a block, weapon damage, weapon speed, regeneration, and spell-power values for
generic item-power budget. each item. A scaled drop preserves that original stat distribution instead of
replacing it with a generic item-power budget.
Every WoW and Conquest of Azeroth character has a saved specialization that
locks its activity role and selects a complete specialization-aware heirloom
loadout. Runes of Magic derives the same profile from its active primary class
and selected role. Virtual heirlooms fill every applicable unoccupied slot,
rescale through item level 79 for players and 80 for AI party members, never
enter inventory, and automatically return when earned equipment is removed.
During leveling their score is normalized above compatible same-level catalog
drops. At level 80 the item-level-85 boss tier contains real upgrades, which
the equipment and loot interfaces highlight without equipping automatically.
The equipment runtime uses the Wrath primary attributes and itemizable combat The equipment runtime uses the Wrath primary attributes and itemizable combat
stats. Strength, Agility, Stamina, Intellect, Spirit, Attack Power, Spell stats. Strength, Agility, Stamina, Intellect, Spirit, Attack Power, Spell
@@ -181,12 +218,13 @@ npm run android:apk
The debug APK is written under `android/app/build/outputs/apk/debug/`. To build The debug APK is written under `android/app/build/outputs/apk/debug/`. To build
and install directly onto a connected device, use `npm run android:install`. and install directly onto a connected device, use `npm run android:install`.
Android uses a separate compact `dist-android` build. It bundles the client, Android uses a compact `dist-android` build with the same required-content
interface, equipment, and Wailing Caverns starter content while optional boundary as the production browser build. Optional dungeons, character/skin
dungeons, character packs, and Manastorm stages are downloaded into app-private packs, Manastorm stages, and original spell media are downloaded into
storage. Installed content and local saves remain playable without a server app-private storage. Installed content and local saves remain playable without
connection and survive APK updates. See `CONTENT_UPDATES.md` for the update a server connection and survive APK updates. See `CONTENT_UPDATES.md` for the
contract and `DEPLOYMENT.md` for TrueNAS publishing and signed Gitea releases. update contract and `DEPLOYMENT.md` for TrueNAS publishing and signed Gitea
releases.
## Runtime details ## Runtime details
@@ -206,6 +244,8 @@ contract and `DEPLOYMENT.md` for TrueNAS publishing and signed Gitea releases.
compressed in GPU memory instead of expanding to uncompressed RGBA textures. compressed in GPU memory instead of expanding to uncompressed RGBA textures.
- Missing production GLBs activate a small cave proxy; malformed assets activate - Missing production GLBs activate a small cave proxy; malformed assets activate
the recoverable scene-error screen. the recoverable scene-error screen.
- Missing optional character or skin packs render the built-in basic Human
model instead of hiding the player, party member, or roster preview.
- The controller action HUD displays only the active eight-slot layer. Its - The controller action HUD displays only the active eight-slot layer. Its
face-button diamond, shoulders, and D-pad keep the physical controller layout face-button diamond, shoulders, and D-pad keep the physical controller layout
visible without showing all 24 bindings over the playfield. visible without showing all 24 bindings over the playfield.
+40 -12
View File
@@ -18,6 +18,21 @@ approval before it commits, pushes `main`, builds the signed APK, and publishes
the Gitea release. Signing passwords and the Gitea token are passed to the the Gitea release. Signing passwords and the Gitea token are passed to the
child process in memory rather than on its command line. child process in memory rather than on its command line.
Before changing versions or running the longer test/build sequence, the manager
runs an isolated release-candidate check. It validates tracked and untracked
files without changing the real Git index, so extra blank lines at EOF and
other whitespace errors fail immediately. Run the same fast check at any time:
```powershell
npm run release:check
```
Editors should honor the repository's `.editorconfig`. The checked-in VS Code
settings also trim extra final newlines whenever a file is saved.
Git may print a one-time CRLF-to-LF conversion warning when an existing Windows
working copy is first staged under `.gitattributes`; that warning is not a
release failure, and subsequent repository text stays consistently LF.
The local release key is `F:\secure\healer-man-release.jks`. When the companion The local release key is `F:\secure\healer-man-release.jks`. When the companion
`healer-man-release-password.dpapi` file is present, blank signing-password `healer-man-release-password.dpapi` file is present, blank signing-password
fields are filled from that Windows user-encrypted credential in memory. The fields are filled from that Windows user-encrypted credential in memory. The
@@ -56,9 +71,12 @@ file, use the shorter procedure at the end. Those updates can be published by
the server and downloaded by an already-installed APK without an Obtainium the server and downloaded by an already-installed APK without an Obtainium
release. release.
Single-player remains offline-capable. A fresh APK includes the runtime and Single-player remains offline-capable. A fresh APK includes the runtime,
starter content. Additional content that a player has downloaded is retained interface, starter equipment, Wailing Caverns, and the basic Human character
in Android app-private storage and can be used offline after download. fallback. Additional content that a player has downloaded is retained in
Android app-private storage and can be used offline after download. Generated
spell effects are available without downloading the optional original-media
pack.
## Fixed locations ## Fixed locations
@@ -219,10 +237,15 @@ Gitea tag after the signed APK builds successfully.
npm run content:test npm run content:test
npm run server:test npm run server:test
npm test npm test
npm run content:publish
npm run build npm run build
``` ```
All four commands must succeed. All five commands must succeed. `content:publish` is a fail-closed release gate:
it validates that the generated manifest contains all 54 WoW campaign dungeon
packs, their exact dependency closure, and every catalog-referenced asset before
it writes the ignored local `content/` output. Do not build or stage a release
if that validation fails.
Apply these additional targeted checks whenever the matching area was edited: Apply these additional targeted checks whenever the matching area was edited:
@@ -254,11 +277,14 @@ npm run dev
First check for whitespace errors and review the final file list: First check for whitespace errors and review the final file list:
```powershell ```powershell
git diff --check npm run release:check
git status --short git status --short
git diff --stat git diff --stat
``` ```
Use `npm run release:check` before the longer release validation. Unlike
`git diff --check`, it includes new, untracked files.
Stage the intended release: Stage the intended release:
```powershell ```powershell
@@ -269,7 +295,8 @@ git diff --cached --check
``` ```
Do not continue if the staged list contains a keystore, APK, `.env` file, Do not continue if the staged list contains a keystore, APK, `.env` file,
database, `content/`, `dist/`, `dist-android/`, or `.android-public/` output. database, `content/`, `dist/`, `dist-android/`, `.web-public/`, or
`.android-public/` output.
Unstage any accidental file with `git restore --staged -- <path>` without Unstage any accidental file with `git restore --staged -- <path>` without
deleting the local file. deleting the local file.
@@ -518,9 +545,10 @@ Do **not** bump the Android version. Run these exact PowerShell commands:
```powershell ```powershell
Set-Location F:\Projects\HealerMan Set-Location F:\Projects\HealerMan
npm run content:test npm run content:test
npm run content:publish
npm run build npm run build
git status --short git status --short
git diff --check npm run release:check
git add -A git add -A
git status --short git status --short
git diff --cached --stat git diff --cached --stat
@@ -607,12 +635,12 @@ An already-installed Android APK cannot be rolled back in place to a lower
still `com.phenomrom.healerman`, use the same signing key, and increase still `com.phenomrom.healerman`, use the same signing key, and increase
`versionCode`. `versionCode`.
- **Gitea APK upload returns an HTTP size error:** increase the Gitea/reverse - **Gitea APK upload returns an HTTP size error:** increase the Gitea/reverse
proxy release-upload limit or use Gitea's direct LAN web endpoint with the proxy release-upload limit or use Gitea's direct LAN web endpoint. The
script's `-GiteaBaseUrl` option. Do not assume `192.168.1.180:8080` is Gitea; publisher defaults to `http://192.168.1.180:30008`; port `8080` is not Gitea.
verify the actual Gitea web port first.
- **Release creation succeeds but attachment upload fails:** do not repeatedly - **Release creation succeeds but attachment upload fails:** do not repeatedly
create the same tag. Remove the incomplete release/tag in Gitea or upload the create the same tag. Use **Publish Current APK Only**. The publisher resumes
attachments to that release, then retry only after its state is understood. the existing release, skips correctly sized attachments, and retries missing
uploads through the direct LAN API.
## Appendix: known-good TrueNAS YAML ## Appendix: known-good TrueNAS YAML
+64
View File
@@ -0,0 +1,64 @@
# RuneWaker encounter content catalog
This is the reviewed runtime layer above the exhaustive, machine-generated RuneWaker
encounter audit. It intentionally contains only source behavior that can be mapped without
guessing. The executable catalog is `src/game/runewakerEncounterCatalog.ts`.
## Bounded reviewed coverage
| Dungeon | Deferred source rows mapped | Runtime behavior | Fidelity |
| --- | --- | --- | --- |
| Forsaken Abbey | `12230`, `12236`, `12238` | Three two-member Ghoul/Carrion Spider formations are created on encounter initialization. After the source `sleep(20)` (2 seconds because RuneWaker sleep units are tenths of a second), the encounter enters its patrol phase. | source-backed adapted |
| Treasure Trove | `5952428`, `5952438` | Killing Boulder Sidaar (`5952494`) arms switch `112100`; interacting with it activates the switch and lowers drawbridge `112098` once. | source-backed adapted |
The Forsaken mapping is backed by preserved Lua `00571.lua` and matrix helper `00727.lua`.
The Treasure Trove mapping is backed by preserved Lua `01159.lua`. Snapshot, mechanics-audit,
and source hashes are attached to each catalog review record.
“Source-backed adapted” is deliberate. Source IDs, trigger order, spawn membership, timing,
and placement transforms are retained. HealerMan supplies serializable phases, procedural
world-object geometry, projected heights, interaction range, and the packaged canonical Ghoul
visual/combat definition for the source-only level-scaled Ghoul template `100653`.
## Effective ledger after this review
The generated audit baseline inventories 4,113 deferred source rows and 1,136 unresolved
mechanics-evidence records. This catalog maps five unique deferred rows and clears five stable
evidence IDs, leaving:
| Ledger item | Baseline | Reviewed here | Remaining |
| --- | ---: | ---: | ---: |
| Deferred source rows | 4,113 | 5 | 4,108 |
| Unresolved mechanics-evidence records | 1,136 | 5 | 1,131 |
Per affected package, Forsaken Abbey moves from 101 to 98 deferred rows and 77 to 74
unresolved evidence records. Treasure Trove moves from 188 to 186 deferred rows and 47 to 45
unresolved evidence records. All other package counts remain unchanged.
The exhaustive generated JSON remains the immutable audit baseline until its generator learns
to consume the runtime catalog. The effective counts above are exported as
`RUNEWAKER_ENCOUNTER_CONTENT_LEDGER` and are regression tested.
## Explicit remaining gaps
- Forsaken formations remain at their source start positions after the two-second hold. The
source uses endless flag-path patrols; the encounter runtime has no reviewed path-following
action yet.
- Forsaken source template `100653` is a level-scaled Ghoul variant created only by Lua and has
no packaged actor row. The runtime alias reuses canonical Ghoul `100072`; this is not claimed
as an exact visual or formula mapping.
- The Forsaken keeper gate (`7883`) remains deferred. Its four Necromage deaths source-summon
Ghoul Drake `100073`, but that summon has neither a packaged entity nor a reviewed combat
definition. Opening the gate without that fight would be false fidelity.
- Black Mary's Hold Door (`5952433`) remains deferred because its source interaction consumes
inventory item `203550`; encounter guards currently expose no inventory predicate.
- Treasure Trove uses procedural bridge/switch proxies because source object meshes and ACT
motions are not packaged.
- The remaining 4,108 rows require the same source-by-source review. Bulk promotion from names,
model paths, or regex categories is not evidence of executable behavior.
## Validation
`src/game/runewakerEncounterCatalog.test.ts` validates each encounter definition and requires
every referenced runtime spawn, entity, encounter spawn group, world object state, and objective
to exist. It also simulates both reviewed state machines and locks the ledger arithmetic.
+35 -18
View File
@@ -1,8 +1,17 @@
# Five-player dungeon import checklist # Five-player dungeon import checklist
Each dungeon is complete only when its actual instance environment, collision, This checklist tracks the native asset and population import, not complete
instance gameplay. A checked dungeon has its environment, collision,
navigation, AzerothCore population, boss roster, and native animated creature navigation, AzerothCore population, boss roster, and native animated creature
models are packaged under `public/assets/game/dungeons/<slug>/`. models packaged under `public/assets/game/dungeons/<slug>/`. Use
`WOW_DUNGEON_FUNCTIONALITY_REPORT.md` for the separate production-fidelity gate
covering doors, objects, scripted progression, waves, escorts, vehicles,
traversal, resets, checkpoints, and completion playtests.
Instance-source review status (2026-09-08): 54/54 reviewed, 51/54 backed by an
executable instance controller, and 3/54 pinned as source-exact no-op instance
scripts. These counts describe implemented runtime coverage; they do not close
the native game-object export or end-to-end playtest gates.
Run one dungeon at a time: Run one dungeon at a time:
@@ -88,24 +97,28 @@ TypeScript/production bundle checks passed.
## Ascension-specific five-player instances ## Ascension-specific five-player instances
- [ ] Tinkertech Showdown (`821`) - blocked on authoritative Ascension server - [ ] Tinkertech Showdown (`821`) - playable HealerMan-authored adaptation.
population/model data. Encounter identity exists for Mechatron (`663012`), Mechatron (`663012`) and the environment are exact; the candidate machine
but no creature template, display mapping, or spawn rows exist locally. spell cluster, trash, cadence, positions, models, and phase rules remain
- [ ] Frozen Reach (`908`) - blocked on authoritative Ascension server explicitly authored because no server binding or spawn snapshot survived.
population/model data. Encounter identity exists for Alva (`97700`), but no - [ ] Frozen Reach (`908`) - playable source-backed adaptation. Alva (`97700`),
creature template, display mapping, or spawn rows exist locally. Arktos (`97701`), 85 exact spell rows, and summon links for entries `97703`,
- [ ] Forgotten Mine (`1781`) - blocked on authoritative Ascension server `97731`, and `97770` were recovered. Server cadence, positions, stats,
population/model data. Encounter identity exists for Geolord Vek (`254272`), models, targeting, and exact phase behavior remain authored.
but no creature template, display mapping, or spawn rows exist locally. - [ ] Forgotten Mine (`1781`) - playable source-backed adaptation. Geolord Vek
(`254272`), 33 exact spell rows, Geospike (`254278`), and Resonite Shard
(`254051`) were recovered. Server cadence, positions, trash, models, and the
exact crystal rule remain authored.
The individual command has been run for all three blocked instances. Their maps The individual import command has been run for all three source-limited
and encounter identities are present in the installed client, but the installed instances. Their checksummed recovery manifest lives under `ascension/` and is
client and available creature caches do not provide the server-only validated by `npm run dungeon:ascension:recovery:validate`. Runtime adapters
entry-to-display and spawn data needed to package their actual mobs/bosses. consume the recovered evidence while retaining explicit `source-backed-adapted`
They intentionally remain on the documented procedural fallback until an or `healer-man-authored` labels. The checklist remains open until an
Ascension server snapshot or reviewed creature/spawn export is supplied. authoritative Ascension creature/spawn/object/server-script snapshot and native
display mappings replace the remaining authored portions.
## Per-dungeon completion gate ## Per-dungeon asset/import gate
These gates passed for every checked dungeon above: These gates passed for every checked dungeon above:
@@ -116,3 +129,7 @@ These gates passed for every checked dungeon above:
- [x] Boss order, entrance, and coordinates reviewed. - [x] Boss order, entrance, and coordinates reviewed.
- [x] Generated campaign catalog points at `/assets/game/dungeons/<slug>/`. - [x] Generated campaign catalog points at `/assets/game/dungeons/<slug>/`.
- [x] Catalog verification, tests, type-check, and production bundle pass. - [x] Catalog verification, tests, type-check, and production bundle pass.
These checks do not certify instance-script behavior. A dungeon remains
functionally incomplete until its entry in `WOW_DUNGEON_FUNCTIONALITY_REPORT.md`
is green.
+71 -15
View File
@@ -73,10 +73,29 @@ attaches native animated client models by display ID. It writes:
- `src/game/generated/dungeonCampaignCatalog.compressed.ts`, the bundled catalog - `src/game/generated/dungeonCampaignCatalog.compressed.ts`, the bundled catalog
- `src/game/generated/dungeonAvailability.json`, the generated availability list - `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 Stock AzerothCore population is used for the standard dungeons. The three
Ascension-specific instances—Tinkertech Showdown, Frozen Reach, and Forgotten Ascension-specific instances—Tinkertech Showdown, Frozen Reach, and Forgotten
Mine—keep their client encounter identities and use an explicit procedural Mine—keep their recovered client identities, spell/summon evidence where
trash-population fallback. Non-Epoch recipes keep explicit procedural actor 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 bodies until reviewed display exports are available. Epoch actors use packaged
client GLBs with their complete native animation libraries; only event-only client GLBs with their complete native animation libraries; only event-only
controllers without a creature display fall back. controllers without a creature display fall back.
@@ -143,10 +162,13 @@ The audit verifies the complete 54-dungeon catalog, authoritative/fallback
classification, every native environment and creature URL, file sizes, classification, every native environment and creature URL, file sizes,
checksums, animation presence, and compiled entry-to-model bindings. The checksums, animation presence, and compiled entry-to-model bindings. The
2026-07-26 batch packaged 50 native imports; together with the Wailing Caverns 2026-07-26 batch packaged 50 native imports; together with the Wailing Caverns
golden fixture, 51/54 dungeons are authoritative. Tinkertech Showdown, Frozen golden fixture, 51/54 dungeons have authoritative WoW population packages.
Reach, and Forgotten Mine remain documented fallbacks because available local Tinkertech Showdown, Frozen Reach, and Forgotten Mine now have playable,
sources contain their maps and encounter identities but no authoritative provenance-labeled runtime adaptations backed by
Ascension creature templates, display mappings, or spawn rows. `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 1. `npm run dungeon:discover -- <slug>` writes deterministic client/server
snapshots, a provenance lock, review-required overrides, and—when server snapshots, a provenance lock, review-required overrides, and—when server
@@ -207,9 +229,14 @@ The default pass recompiles the 54-dungeon campaign, verifies all packaged
environment and creature assets, audits every mob and boss attack/mechanic, environment and creature assets, audits every mob and boss attack/mechanic,
opens every unique native creature GLB to verify idle, movement, attack, wound, 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 death clips, proves the procedural animation path for model-less actors,
and runs the actual runtime-registry coverage test. It writes deterministic runs the actual runtime-registry coverage test, and audits instance-level
JSON and Markdown reports to WOW_DUNGEON_CONTENT_REPORT.json and functionality. It writes deterministic JSON and Markdown reports to
WOW_DUNGEON_CONTENT_REPORT.md. 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: Useful batch options:
@@ -222,11 +249,40 @@ Useful batch options:
# Re-run green packages, then build the app after validation. # Re-run green packages, then build the app after validation.
npm run dungeon:wow:all -- --refresh --force --build npm run dungeon:wow:all -- --refresh --force --build
# Only re-run combat, mechanic, and animation coverage against current output. # Re-run combat, animation, and instance-functionality audits against current output.
npm run dungeon:wow:all -- --audit-only npm run dungeon:wow:all -- --audit-only
Kresh is intentionally recorded as a source-faithful melee-only boss: entry The functionality report is the production-fidelity gate. It separately checks
3653 has no spell or SmartAI row in the pinned AzerothCore snapshot. Trial of typed world-object contracts, source instance scripts, encounter orchestration,
the Champion is likewise documented as a boss-arena population rather than a required interactions, traversal evidence, resets, checkpoints, and completion
trash route. These exceptions are asserted by exact dungeon/entity IDs; any playtests. A green asset or combat audit does not imply that doors, escorts,
new basic-only boss or mob-less dungeon fails the batch. 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.
+243 -212
View File
@@ -1,22 +1,22 @@
{ {
"schemaVersion": 1, "schemaVersion": 1,
"status": "green", "status": "green",
"scope": "HealerMan WoW five-player campaign", "scope": "HealerMan WoW five-player combat and animation coverage",
"summary": { "summary": {
"dungeons": 54, "dungeons": 54,
"mobs": 1031, "mobs": 1193,
"bosses": 253, "bosses": 273,
"attacks": 2953, "attacks": 4026,
"specialAttacks": 1669, "specialAttacks": 2572,
"nativeModels": 1266, "nativeModels": 1275,
"proceduralModels": 18, "proceduralModels": 191,
"uniqueNativeModels": 1166, "uniqueNativeModels": 1167,
"nativeStateFallbacks": 16 "nativeStateFallbacks": 18
}, },
"documentedExceptions": [ "documentedExceptions": [
{ {
"type": "basic-only-boss", "type": "basic-only-boss",
"key": "wailing-caverns:entry-3653", "key": "wailing-caverns:kresh",
"reason": "Kresh is melee-only in the pinned AzerothCore snapshot; the historical server has no spell or SmartAI row for entry 3653." "reason": "Kresh is melee-only in the pinned AzerothCore snapshot; the historical server has no spell or SmartAI row for entry 3653."
}, },
{ {
@@ -25,9 +25,24 @@
"reason": "The server-faithful rare entry 5912 has no spell rows and is despawned by the Wailing Caverns initialization event." "reason": "The server-faithful rare entry 5912 has no spell rows and is despawned by the Wailing Caverns initialization event."
}, },
{ {
"type": "no-trash-instance", "type": "basic-only-boss",
"key": "trial-of-the-champion", "key": "gnomeregan:wow-classic-batch-three-entry-7361",
"reason": "Trial of the Champion is an encounter arena; its imported combat population is the five Grand Champion bosses, not a trash route." "reason": "Grubbis is melee-only in the pinned AzerothCore snapshot; entry 7361 has aggro dialogue and instance-completion rows but no combat spell cast."
},
{
"type": "basic-only-boss",
"key": "blackrock-spire:entry-9218",
"reason": "Spirestone Battle Lord is a 15% rare spawn in the pinned database and has no combat spell cast beyond its basic melee attack."
},
{
"type": "basic-only-boss",
"key": "blackrock-spire:entry-9219",
"reason": "Spirestone Butcher is a 15% rare spawn in the pinned database and has no combat spell cast beyond its basic melee attack."
},
{
"type": "basic-only-boss",
"key": "blackrock-spire:entry-10376",
"reason": "Crystal Fang is a 15% rare spawn with no active combat spell in the pinned database; its exact on-death Spire Spiderling summon is implemented by the instance adapter."
} }
], ],
"animationFallbacks": [ "animationFallbacks": [
@@ -47,6 +62,14 @@
], ],
"renderer": "OriginalCreatureModel combat fallback" "renderer": "OriginalCreatureModel combat fallback"
}, },
{
"url": "/assets/game/dungeons/dire-maul/creatures/display-14430-animated.glb",
"state": "move",
"users": [
"dire-maul:entry-14386"
],
"renderer": "AnimatedMobBody locomotion fallback"
},
{ {
"url": "/assets/game/dungeons/dire-maul/creatures/display-14430-animated.glb", "url": "/assets/game/dungeons/dire-maul/creatures/display-14430-animated.glb",
"state": "attack", "state": "attack",
@@ -56,7 +79,15 @@
"renderer": "OriginalCreatureModel combat fallback" "renderer": "OriginalCreatureModel combat fallback"
}, },
{ {
"url": "/assets/game/creatures/shared/2fbb8d2226a7fdf3e9a7af13568f6bb46cb1b27afc008732832b9fd42c2e510e.glb", "url": "/assets/game/dungeons/dire-maul/creatures/display-14430-animated.glb",
"state": "wound",
"users": [
"dire-maul:entry-14386"
],
"renderer": "OriginalCreatureModel combat fallback"
},
{
"url": "/assets/game/creatures/shared/52c8b3aea63f21f8e98ad84eaf601f2918d1df17a05525d41f5b3e17da53c8ff.glb",
"state": "wound", "state": "wound",
"users": [ "users": [
"steamvault:entry-21694", "steamvault:entry-21694",
@@ -164,14 +195,26 @@
], ],
"issues": [], "issues": [],
"dungeons": [ "dungeons": [
{
"id": "wailing-caverns",
"title": "Wailing Caverns",
"source": "azerothcore",
"mobs": 23,
"bosses": 9,
"attacks": 72,
"specialAttacks": 40,
"nativeModels": 24,
"proceduralModels": 8,
"status": "green"
},
{ {
"id": "shadowfang-keep", "id": "shadowfang-keep",
"title": "Shadowfang Keep", "title": "Shadowfang Keep",
"source": "azerothcore", "source": "azerothcore",
"mobs": 24, "mobs": 24,
"bosses": 7, "bosses": 7,
"attacks": 58, "attacks": 65,
"specialAttacks": 27, "specialAttacks": 34,
"nativeModels": 31, "nativeModels": 31,
"proceduralModels": 0, "proceduralModels": 0,
"status": "green" "status": "green"
@@ -182,8 +225,8 @@
"source": "azerothcore", "source": "azerothcore",
"mobs": 6, "mobs": 6,
"bosses": 5, "bosses": 5,
"attacks": 32, "attacks": 42,
"specialAttacks": 21, "specialAttacks": 31,
"nativeModels": 11, "nativeModels": 11,
"proceduralModels": 0, "proceduralModels": 0,
"status": "green" "status": "green"
@@ -194,32 +237,20 @@
"source": "azerothcore", "source": "azerothcore",
"mobs": 15, "mobs": 15,
"bosses": 7, "bosses": 7,
"attacks": 48, "attacks": 55,
"specialAttacks": 26, "specialAttacks": 33,
"nativeModels": 22, "nativeModels": 22,
"proceduralModels": 0, "proceduralModels": 0,
"status": "green" "status": "green"
}, },
{
"id": "wailing-caverns",
"title": "Wailing Caverns",
"source": "azerothcore",
"mobs": 12,
"bosses": 8,
"attacks": 51,
"specialAttacks": 31,
"nativeModels": 15,
"proceduralModels": 5,
"status": "green"
},
{ {
"id": "razorfen-kraul", "id": "razorfen-kraul",
"title": "Razorfen Kraul", "title": "Razorfen Kraul",
"source": "azerothcore", "source": "azerothcore",
"mobs": 31, "mobs": 31,
"bosses": 7, "bosses": 7,
"attacks": 78, "attacks": 87,
"specialAttacks": 40, "specialAttacks": 49,
"nativeModels": 38, "nativeModels": 38,
"proceduralModels": 0, "proceduralModels": 0,
"status": "green" "status": "green"
@@ -228,12 +259,12 @@
"id": "blackfathom-deeps", "id": "blackfathom-deeps",
"title": "Blackfathom Deeps", "title": "Blackfathom Deeps",
"source": "azerothcore", "source": "azerothcore",
"mobs": 21, "mobs": 23,
"bosses": 6, "bosses": 6,
"attacks": 58, "attacks": 67,
"specialAttacks": 31, "specialAttacks": 38,
"nativeModels": 27, "nativeModels": 27,
"proceduralModels": 0, "proceduralModels": 2,
"status": "green" "status": "green"
}, },
{ {
@@ -242,8 +273,8 @@
"source": "azerothcore", "source": "azerothcore",
"mobs": 31, "mobs": 31,
"bosses": 7, "bosses": 7,
"attacks": 85, "attacks": 104,
"specialAttacks": 47, "specialAttacks": 66,
"nativeModels": 38, "nativeModels": 38,
"proceduralModels": 0, "proceduralModels": 0,
"status": "green" "status": "green"
@@ -252,36 +283,36 @@
"id": "gnomeregan", "id": "gnomeregan",
"title": "Gnomeregan", "title": "Gnomeregan",
"source": "azerothcore", "source": "azerothcore",
"mobs": 27, "mobs": 28,
"bosses": 4, "bosses": 5,
"attacks": 68, "attacks": 84,
"specialAttacks": 37, "specialAttacks": 51,
"nativeModels": 31, "nativeModels": 31,
"proceduralModels": 0, "proceduralModels": 2,
"status": "green" "status": "green"
}, },
{ {
"id": "sunken-temple", "id": "sunken-temple",
"title": "Sunken Temple", "title": "Sunken Temple",
"source": "azerothcore", "source": "azerothcore",
"mobs": 29, "mobs": 31,
"bosses": 4, "bosses": 4,
"attacks": 86, "attacks": 95,
"specialAttacks": 53, "specialAttacks": 60,
"nativeModels": 33, "nativeModels": 33,
"proceduralModels": 0, "proceduralModels": 2,
"status": "green" "status": "green"
}, },
{ {
"id": "razorfen-downs", "id": "razorfen-downs",
"title": "Razorfen Downs", "title": "Razorfen Downs",
"source": "azerothcore", "source": "azerothcore",
"mobs": 19, "mobs": 21,
"bosses": 6, "bosses": 6,
"attacks": 55, "attacks": 65,
"specialAttacks": 30, "specialAttacks": 38,
"nativeModels": 25, "nativeModels": 25,
"proceduralModels": 0, "proceduralModels": 2,
"status": "green" "status": "green"
}, },
{ {
@@ -290,8 +321,8 @@
"source": "azerothcore", "source": "azerothcore",
"mobs": 32, "mobs": 32,
"bosses": 5, "bosses": 5,
"attacks": 89, "attacks": 107,
"specialAttacks": 52, "specialAttacks": 70,
"nativeModels": 37, "nativeModels": 37,
"proceduralModels": 0, "proceduralModels": 0,
"status": "green" "status": "green"
@@ -300,60 +331,60 @@
"id": "zulfarrak", "id": "zulfarrak",
"title": "Zul'Farrak", "title": "Zul'Farrak",
"source": "azerothcore", "source": "azerothcore",
"mobs": 16, "mobs": 23,
"bosses": 5, "bosses": 5,
"attacks": 53, "attacks": 76,
"specialAttacks": 32, "specialAttacks": 48,
"nativeModels": 21, "nativeModels": 21,
"proceduralModels": 0, "proceduralModels": 7,
"status": "green" "status": "green"
}, },
{ {
"id": "blackrock-spire", "id": "blackrock-spire",
"title": "Blackrock Spire", "title": "Blackrock Spire",
"source": "azerothcore", "source": "azerothcore",
"mobs": 63, "mobs": 66,
"bosses": 15, "bosses": 17,
"attacks": 210, "attacks": 285,
"specialAttacks": 132, "specialAttacks": 202,
"nativeModels": 78, "nativeModels": 78,
"proceduralModels": 0, "proceduralModels": 5,
"status": "green" "status": "green"
}, },
{ {
"id": "blackrock-depths", "id": "blackrock-depths",
"title": "Blackrock Depths", "title": "Blackrock Depths",
"source": "azerothcore", "source": "azerothcore",
"mobs": 48, "mobs": 58,
"bosses": 13, "bosses": 13,
"attacks": 145, "attacks": 192,
"specialAttacks": 84, "specialAttacks": 121,
"nativeModels": 61, "nativeModels": 61,
"proceduralModels": 0, "proceduralModels": 10,
"status": "green" "status": "green"
}, },
{ {
"id": "scholomance", "id": "scholomance",
"title": "Scholomance", "title": "Scholomance",
"source": "azerothcore", "source": "azerothcore",
"mobs": 30, "mobs": 31,
"bosses": 8, "bosses": 8,
"attacks": 115, "attacks": 151,
"specialAttacks": 77, "specialAttacks": 112,
"nativeModels": 38, "nativeModels": 38,
"proceduralModels": 0, "proceduralModels": 1,
"status": "green" "status": "green"
}, },
{ {
"id": "stratholme", "id": "stratholme",
"title": "Stratholme", "title": "Stratholme",
"source": "azerothcore", "source": "azerothcore",
"mobs": 41, "mobs": 45,
"bosses": 9, "bosses": 9,
"attacks": 131, "attacks": 180,
"specialAttacks": 81, "specialAttacks": 126,
"nativeModels": 50, "nativeModels": 50,
"proceduralModels": 0, "proceduralModels": 4,
"status": "green" "status": "green"
}, },
{ {
@@ -362,8 +393,8 @@
"source": "azerothcore", "source": "azerothcore",
"mobs": 25, "mobs": 25,
"bosses": 8, "bosses": 8,
"attacks": 83, "attacks": 95,
"specialAttacks": 50, "specialAttacks": 62,
"nativeModels": 33, "nativeModels": 33,
"proceduralModels": 0, "proceduralModels": 0,
"status": "green" "status": "green"
@@ -374,8 +405,8 @@
"source": "azerothcore", "source": "azerothcore",
"mobs": 7, "mobs": 7,
"bosses": 4, "bosses": 4,
"attacks": 21, "attacks": 23,
"specialAttacks": 10, "specialAttacks": 12,
"nativeModels": 11, "nativeModels": 11,
"proceduralModels": 0, "proceduralModels": 0,
"status": "green" "status": "green"
@@ -386,8 +417,8 @@
"source": "azerothcore", "source": "azerothcore",
"mobs": 63, "mobs": 63,
"bosses": 12, "bosses": 12,
"attacks": 184, "attacks": 242,
"specialAttacks": 109, "specialAttacks": 167,
"nativeModels": 75, "nativeModels": 75,
"proceduralModels": 0, "proceduralModels": 0,
"status": "green" "status": "green"
@@ -398,8 +429,8 @@
"source": "azerothcore", "source": "azerothcore",
"mobs": 29, "mobs": 29,
"bosses": 3, "bosses": 3,
"attacks": 74, "attacks": 92,
"specialAttacks": 42, "specialAttacks": 60,
"nativeModels": 32, "nativeModels": 32,
"proceduralModels": 0, "proceduralModels": 0,
"status": "green" "status": "green"
@@ -410,8 +441,8 @@
"source": "azerothcore", "source": "azerothcore",
"mobs": 14, "mobs": 14,
"bosses": 3, "bosses": 3,
"attacks": 44, "attacks": 53,
"specialAttacks": 27, "specialAttacks": 36,
"nativeModels": 17, "nativeModels": 17,
"proceduralModels": 0, "proceduralModels": 0,
"status": "green" "status": "green"
@@ -420,12 +451,12 @@
"id": "hellfire-ramparts", "id": "hellfire-ramparts",
"title": "Hellfire Citadel: Ramparts", "title": "Hellfire Citadel: Ramparts",
"source": "azerothcore", "source": "azerothcore",
"mobs": 10, "mobs": 11,
"bosses": 2, "bosses": 4,
"attacks": 36, "attacks": 47,
"specialAttacks": 24, "specialAttacks": 32,
"nativeModels": 12, "nativeModels": 12,
"proceduralModels": 0, "proceduralModels": 3,
"status": "green" "status": "green"
}, },
{ {
@@ -434,8 +465,8 @@
"source": "azerothcore", "source": "azerothcore",
"mobs": 14, "mobs": 14,
"bosses": 3, "bosses": 3,
"attacks": 50, "attacks": 63,
"specialAttacks": 33, "specialAttacks": 46,
"nativeModels": 17, "nativeModels": 17,
"proceduralModels": 0, "proceduralModels": 0,
"status": "green" "status": "green"
@@ -444,48 +475,48 @@
"id": "underbog", "id": "underbog",
"title": "Coilfang: The Underbog", "title": "Coilfang: The Underbog",
"source": "azerothcore", "source": "azerothcore",
"mobs": 18, "mobs": 20,
"bosses": 4, "bosses": 4,
"attacks": 59, "attacks": 82,
"specialAttacks": 37, "specialAttacks": 58,
"nativeModels": 22, "nativeModels": 22,
"proceduralModels": 0, "proceduralModels": 2,
"status": "green" "status": "green"
}, },
{ {
"id": "slave-pens", "id": "slave-pens",
"title": "Coilfang: The Slave Pens", "title": "Coilfang: The Slave Pens",
"source": "azerothcore", "source": "azerothcore",
"mobs": 18, "mobs": 21,
"bosses": 3, "bosses": 4,
"attacks": 53, "attacks": 66,
"specialAttacks": 32, "specialAttacks": 43,
"nativeModels": 21, "nativeModels": 21,
"proceduralModels": 0, "proceduralModels": 4,
"status": "green" "status": "green"
}, },
{ {
"id": "arcatraz", "id": "arcatraz",
"title": "Tempest Keep: The Arcatraz", "title": "Tempest Keep: The Arcatraz",
"source": "azerothcore", "source": "azerothcore",
"mobs": 25, "mobs": 28,
"bosses": 4, "bosses": 4,
"attacks": 73, "attacks": 108,
"specialAttacks": 44, "specialAttacks": 76,
"nativeModels": 29, "nativeModels": 29,
"proceduralModels": 0, "proceduralModels": 3,
"status": "green" "status": "green"
}, },
{ {
"id": "botanica", "id": "botanica",
"title": "Tempest Keep: The Botanica", "title": "Tempest Keep: The Botanica",
"source": "azerothcore", "source": "azerothcore",
"mobs": 24, "mobs": 28,
"bosses": 5, "bosses": 5,
"attacks": 67, "attacks": 89,
"specialAttacks": 38, "specialAttacks": 56,
"nativeModels": 29, "nativeModels": 29,
"proceduralModels": 0, "proceduralModels": 4,
"status": "green" "status": "green"
}, },
{ {
@@ -494,8 +525,8 @@
"source": "azerothcore", "source": "azerothcore",
"mobs": 14, "mobs": 14,
"bosses": 3, "bosses": 3,
"attacks": 45, "attacks": 69,
"specialAttacks": 28, "specialAttacks": 52,
"nativeModels": 17, "nativeModels": 17,
"proceduralModels": 0, "proceduralModels": 0,
"status": "green" "status": "green"
@@ -506,8 +537,8 @@
"source": "azerothcore", "source": "azerothcore",
"mobs": 18, "mobs": 18,
"bosses": 4, "bosses": 4,
"attacks": 46, "attacks": 67,
"specialAttacks": 24, "specialAttacks": 45,
"nativeModels": 22, "nativeModels": 22,
"proceduralModels": 0, "proceduralModels": 0,
"status": "green" "status": "green"
@@ -516,72 +547,72 @@
"id": "sethekk-halls", "id": "sethekk-halls",
"title": "Auchindoun: Sethekk Halls", "title": "Auchindoun: Sethekk Halls",
"source": "azerothcore", "source": "azerothcore",
"mobs": 14, "mobs": 19,
"bosses": 2, "bosses": 3,
"attacks": 39, "attacks": 59,
"specialAttacks": 23, "specialAttacks": 37,
"nativeModels": 16, "nativeModels": 16,
"proceduralModels": 0, "proceduralModels": 6,
"status": "green" "status": "green"
}, },
{ {
"id": "mana-tombs", "id": "mana-tombs",
"title": "Auchindoun: Mana-Tombs", "title": "Auchindoun: Mana-Tombs",
"source": "azerothcore", "source": "azerothcore",
"mobs": 11, "mobs": 12,
"bosses": 3, "bosses": 4,
"attacks": 33, "attacks": 50,
"specialAttacks": 19, "specialAttacks": 34,
"nativeModels": 14, "nativeModels": 14,
"proceduralModels": 0, "proceduralModels": 2,
"status": "green" "status": "green"
}, },
{ {
"id": "auchenai-crypts", "id": "auchenai-crypts",
"title": "Auchindoun: Auchenai Crypts", "title": "Auchindoun: Auchenai Crypts",
"source": "azerothcore", "source": "azerothcore",
"mobs": 12, "mobs": 13,
"bosses": 2, "bosses": 3,
"attacks": 30, "attacks": 48,
"specialAttacks": 16, "specialAttacks": 32,
"nativeModels": 14, "nativeModels": 14,
"proceduralModels": 0, "proceduralModels": 2,
"status": "green" "status": "green"
}, },
{ {
"id": "magisters-terrace", "id": "magisters-terrace",
"title": "Magister's Terrace", "title": "Magister's Terrace",
"source": "azerothcore", "source": "azerothcore",
"mobs": 15, "mobs": 23,
"bosses": 3, "bosses": 3,
"attacks": 33, "attacks": 65,
"specialAttacks": 15, "specialAttacks": 39,
"nativeModels": 18, "nativeModels": 18,
"proceduralModels": 0, "proceduralModels": 8,
"status": "green" "status": "green"
}, },
{ {
"id": "black-morass", "id": "black-morass",
"title": "The Black Morass", "title": "The Black Morass",
"source": "azerothcore", "source": "azerothcore",
"mobs": 4, "mobs": 13,
"bosses": 3, "bosses": 3,
"attacks": 20, "attacks": 34,
"specialAttacks": 13, "specialAttacks": 18,
"nativeModels": 7, "nativeModels": 7,
"proceduralModels": 0, "proceduralModels": 9,
"status": "green" "status": "green"
}, },
{ {
"id": "escape-from-durnholde", "id": "escape-from-durnholde",
"title": "The Escape From Durnholde", "title": "The Escape From Durnholde",
"source": "azerothcore", "source": "azerothcore",
"mobs": 26, "mobs": 32,
"bosses": 3, "bosses": 3,
"attacks": 45, "attacks": 59,
"specialAttacks": 16, "specialAttacks": 24,
"nativeModels": 29, "nativeModels": 29,
"proceduralModels": 0, "proceduralModels": 6,
"status": "green" "status": "green"
}, },
{ {
@@ -589,107 +620,107 @@
"title": "Utgarde Keep", "title": "Utgarde Keep",
"source": "azerothcore", "source": "azerothcore",
"mobs": 19, "mobs": 19,
"bosses": 3, "bosses": 6,
"attacks": 35, "attacks": 55,
"specialAttacks": 13, "specialAttacks": 30,
"nativeModels": 22, "nativeModels": 22,
"proceduralModels": 0, "proceduralModels": 3,
"status": "green" "status": "green"
}, },
{ {
"id": "utgarde-pinnacle", "id": "utgarde-pinnacle",
"title": "Utgarde Pinnacle", "title": "Utgarde Pinnacle",
"source": "azerothcore", "source": "azerothcore",
"mobs": 13, "mobs": 19,
"bosses": 4, "bosses": 4,
"attacks": 32, "attacks": 50,
"specialAttacks": 15, "specialAttacks": 27,
"nativeModels": 17, "nativeModels": 17,
"proceduralModels": 0, "proceduralModels": 6,
"status": "green" "status": "green"
}, },
{ {
"id": "the-nexus", "id": "the-nexus",
"title": "The Nexus", "title": "The Nexus",
"source": "azerothcore", "source": "azerothcore",
"mobs": 21, "mobs": 24,
"bosses": 5, "bosses": 5,
"attacks": 50, "attacks": 64,
"specialAttacks": 24, "specialAttacks": 35,
"nativeModels": 26, "nativeModels": 26,
"proceduralModels": 0, "proceduralModels": 3,
"status": "green" "status": "green"
}, },
{ {
"id": "the-oculus", "id": "the-oculus",
"title": "The Oculus", "title": "The Oculus",
"source": "azerothcore", "source": "azerothcore",
"mobs": 8, "mobs": 17,
"bosses": 4, "bosses": 4,
"attacks": 27, "attacks": 42,
"specialAttacks": 15, "specialAttacks": 21,
"nativeModels": 12, "nativeModels": 12,
"proceduralModels": 0, "proceduralModels": 9,
"status": "green" "status": "green"
}, },
{ {
"id": "culling-of-stratholme", "id": "culling-of-stratholme",
"title": "The Culling of Stratholme", "title": "The Culling of Stratholme",
"source": "azerothcore", "source": "azerothcore",
"mobs": 16, "mobs": 21,
"bosses": 4, "bosses": 4,
"attacks": 41, "attacks": 49,
"specialAttacks": 21, "specialAttacks": 24,
"nativeModels": 20, "nativeModels": 20,
"proceduralModels": 0, "proceduralModels": 5,
"status": "green" "status": "green"
}, },
{ {
"id": "halls-of-stone", "id": "halls-of-stone",
"title": "Halls of Stone", "title": "Halls of Stone",
"source": "azerothcore", "source": "azerothcore",
"mobs": 13, "mobs": 16,
"bosses": 4, "bosses": 4,
"attacks": 32, "attacks": 45,
"specialAttacks": 15, "specialAttacks": 25,
"nativeModels": 16, "nativeModels": 16,
"proceduralModels": 1, "proceduralModels": 4,
"status": "green" "status": "green"
}, },
{ {
"id": "draktharon-keep", "id": "draktharon-keep",
"title": "Drak'Tharon Keep", "title": "Drak'Tharon Keep",
"source": "azerothcore", "source": "azerothcore",
"mobs": 18, "mobs": 20,
"bosses": 4, "bosses": 4,
"attacks": 38, "attacks": 47,
"specialAttacks": 16, "specialAttacks": 23,
"nativeModels": 22, "nativeModels": 22,
"proceduralModels": 0, "proceduralModels": 2,
"status": "green" "status": "green"
}, },
{ {
"id": "azjol-nerub", "id": "azjol-nerub",
"title": "Azjol-Nerub", "title": "Azjol-Nerub",
"source": "azerothcore", "source": "azerothcore",
"mobs": 10, "mobs": 18,
"bosses": 3, "bosses": 3,
"attacks": 25, "attacks": 38,
"specialAttacks": 12, "specialAttacks": 17,
"nativeModels": 13, "nativeModels": 13,
"proceduralModels": 0, "proceduralModels": 8,
"status": "green" "status": "green"
}, },
{ {
"id": "halls-of-lightning", "id": "halls-of-lightning",
"title": "Halls of Lightning", "title": "Halls of Lightning",
"source": "azerothcore", "source": "azerothcore",
"mobs": 16, "mobs": 19,
"bosses": 4, "bosses": 4,
"attacks": 35, "attacks": 52,
"specialAttacks": 15, "specialAttacks": 29,
"nativeModels": 20, "nativeModels": 20,
"proceduralModels": 0, "proceduralModels": 3,
"status": "green" "status": "green"
}, },
{ {
@@ -698,8 +729,8 @@
"source": "azerothcore", "source": "azerothcore",
"mobs": 15, "mobs": 15,
"bosses": 5, "bosses": 5,
"attacks": 43, "attacks": 53,
"specialAttacks": 23, "specialAttacks": 33,
"nativeModels": 20, "nativeModels": 20,
"proceduralModels": 0, "proceduralModels": 0,
"status": "green" "status": "green"
@@ -708,24 +739,24 @@
"id": "violet-hold", "id": "violet-hold",
"title": "Violet Hold", "title": "Violet Hold",
"source": "azerothcore", "source": "azerothcore",
"mobs": 2, "mobs": 17,
"bosses": 3, "bosses": 3,
"attacks": 19, "attacks": 39,
"specialAttacks": 14, "specialAttacks": 19,
"nativeModels": 5, "nativeModels": 5,
"proceduralModels": 0, "proceduralModels": 15,
"status": "green" "status": "green"
}, },
{ {
"id": "ahnkahet-old-kingdom", "id": "ahnkahet-old-kingdom",
"title": "Ahn'kahet: The Old Kingdom", "title": "Ahn'kahet: The Old Kingdom",
"source": "azerothcore", "source": "azerothcore",
"mobs": 19, "mobs": 23,
"bosses": 5, "bosses": 5,
"attacks": 43, "attacks": 64,
"specialAttacks": 19, "specialAttacks": 36,
"nativeModels": 24, "nativeModels": 24,
"proceduralModels": 0, "proceduralModels": 4,
"status": "green" "status": "green"
}, },
{ {
@@ -734,8 +765,8 @@
"source": "azerothcore", "source": "azerothcore",
"mobs": 11, "mobs": 11,
"bosses": 2, "bosses": 2,
"attacks": 21, "attacks": 23,
"specialAttacks": 8, "specialAttacks": 10,
"nativeModels": 13, "nativeModels": 13,
"proceduralModels": 0, "proceduralModels": 0,
"status": "green" "status": "green"
@@ -744,36 +775,36 @@
"id": "trial-of-the-champion", "id": "trial-of-the-champion",
"title": "Trial of the Champion", "title": "Trial of the Champion",
"source": "azerothcore", "source": "azerothcore",
"mobs": 0, "mobs": 6,
"bosses": 5, "bosses": 12,
"attacks": 22, "attacks": 123,
"specialAttacks": 17, "specialAttacks": 105,
"nativeModels": 5, "nativeModels": 5,
"proceduralModels": 0, "proceduralModels": 13,
"status": "green" "status": "green"
}, },
{ {
"id": "pit-of-saron", "id": "pit-of-saron",
"title": "Pit of Saron", "title": "Pit of Saron",
"source": "azerothcore", "source": "azerothcore",
"mobs": 27, "mobs": 31,
"bosses": 3, "bosses": 3,
"attacks": 43, "attacks": 53,
"specialAttacks": 13, "specialAttacks": 19,
"nativeModels": 30, "nativeModels": 30,
"proceduralModels": 0, "proceduralModels": 4,
"status": "green" "status": "green"
}, },
{ {
"id": "halls-of-reflection", "id": "halls-of-reflection",
"title": "Halls of Reflection", "title": "Halls of Reflection",
"source": "azerothcore", "source": "azerothcore",
"mobs": 8, "mobs": 16,
"bosses": 2, "bosses": 2,
"attacks": 26, "attacks": 46,
"specialAttacks": 16, "specialAttacks": 28,
"nativeModels": 10, "nativeModels": 10,
"proceduralModels": 0, "proceduralModels": 8,
"status": "green" "status": "green"
}, },
{ {
@@ -782,8 +813,8 @@
"source": "procedural-fallback", "source": "procedural-fallback",
"mobs": 3, "mobs": 3,
"bosses": 1, "bosses": 1,
"attacks": 8, "attacks": 13,
"specialAttacks": 4, "specialAttacks": 12,
"nativeModels": 0, "nativeModels": 0,
"proceduralModels": 4, "proceduralModels": 4,
"status": "green" "status": "green"
@@ -792,24 +823,24 @@
"id": "frozen-reach", "id": "frozen-reach",
"title": "Frozen Reach", "title": "Frozen Reach",
"source": "procedural-fallback", "source": "procedural-fallback",
"mobs": 3, "mobs": 2,
"bosses": 1, "bosses": 1,
"attacks": 8, "attacks": 19,
"specialAttacks": 4, "specialAttacks": 19,
"nativeModels": 0, "nativeModels": 0,
"proceduralModels": 4, "proceduralModels": 3,
"status": "green" "status": "green"
}, },
{ {
"id": "forgotten-mine", "id": "forgotten-mine",
"title": "Forgotten Mine", "title": "Forgotten Mine",
"source": "procedural-fallback", "source": "procedural-fallback",
"mobs": 3, "mobs": 4,
"bosses": 1, "bosses": 1,
"attacks": 8, "attacks": 13,
"specialAttacks": 4, "specialAttacks": 12,
"nativeModels": 0, "nativeModels": 0,
"proceduralModels": 4, "proceduralModels": 5,
"status": "green" "status": "green"
} }
] ]
+64 -59
View File
@@ -1,73 +1,78 @@
# WoW dungeon content report # WoW dungeon combat and animation report
Status: **green** Status: **green**
Coverage: 54 dungeons, 1031 mobs, 253 bosses, 2953 executable attacks, and 1669 special attacks/mechanics. Scope: executable combat populations and creature animation bindings. This report does not certify instance scripts, doors, interactables, escorts, waves, vehicles, or navigation.
Animation paths: 1266 native model bindings and 18 procedural bindings across 1166 unique native GLBs; 16 missing native states use the shared procedural fallback. Coverage: 54 dungeons, 1193 mobs, 273 bosses, 4026 executable attacks, and 2572 special attacks/mechanics.
Animation paths: 1275 native model bindings and 191 procedural bindings across 1167 unique native GLBs; 18 missing native states use the shared procedural fallback.
| Dungeon | Mobs | Bosses | Attacks | Specials | Native | Procedural | Status | | Dungeon | Mobs | Bosses | Attacks | Specials | Native | Procedural | Status |
| --- | ---: | ---: | ---: | ---: | ---: | ---: | --- | | --- | ---: | ---: | ---: | ---: | ---: | ---: | --- |
| Shadowfang Keep | 24 | 7 | 58 | 27 | 31 | 0 | green | | Wailing Caverns | 23 | 9 | 72 | 40 | 24 | 8 | green |
| Stormwind Stockade | 6 | 5 | 32 | 21 | 11 | 0 | green | | Shadowfang Keep | 24 | 7 | 65 | 34 | 31 | 0 | green |
| The Deadmines | 15 | 7 | 48 | 26 | 22 | 0 | green | | Stormwind Stockade | 6 | 5 | 42 | 31 | 11 | 0 | green |
| Wailing Caverns | 12 | 8 | 51 | 31 | 15 | 5 | green | | The Deadmines | 15 | 7 | 55 | 33 | 22 | 0 | green |
| Razorfen Kraul | 31 | 7 | 78 | 40 | 38 | 0 | green | | Razorfen Kraul | 31 | 7 | 87 | 49 | 38 | 0 | green |
| Blackfathom Deeps | 21 | 6 | 58 | 31 | 27 | 0 | green | | Blackfathom Deeps | 23 | 6 | 67 | 38 | 27 | 2 | green |
| Uldaman | 31 | 7 | 85 | 47 | 38 | 0 | green | | Uldaman | 31 | 7 | 104 | 66 | 38 | 0 | green |
| Gnomeregan | 27 | 4 | 68 | 37 | 31 | 0 | green | | Gnomeregan | 28 | 5 | 84 | 51 | 31 | 2 | green |
| Sunken Temple | 29 | 4 | 86 | 53 | 33 | 0 | green | | Sunken Temple | 31 | 4 | 95 | 60 | 33 | 2 | green |
| Razorfen Downs | 19 | 6 | 55 | 30 | 25 | 0 | green | | Razorfen Downs | 21 | 6 | 65 | 38 | 25 | 2 | green |
| Scarlet Monastery | 32 | 5 | 89 | 52 | 37 | 0 | green | | Scarlet Monastery | 32 | 5 | 107 | 70 | 37 | 0 | green |
| Zul'Farrak | 16 | 5 | 53 | 32 | 21 | 0 | green | | Zul'Farrak | 23 | 5 | 76 | 48 | 21 | 7 | green |
| Blackrock Spire | 63 | 15 | 210 | 132 | 78 | 0 | green | | Blackrock Spire | 66 | 17 | 285 | 202 | 78 | 5 | green |
| Blackrock Depths | 48 | 13 | 145 | 84 | 61 | 0 | green | | Blackrock Depths | 58 | 13 | 192 | 121 | 61 | 10 | green |
| Scholomance | 30 | 8 | 115 | 77 | 38 | 0 | green | | Scholomance | 31 | 8 | 151 | 112 | 38 | 1 | green |
| Stratholme | 41 | 9 | 131 | 81 | 50 | 0 | green | | Stratholme | 45 | 9 | 180 | 126 | 50 | 4 | green |
| Maraudon | 25 | 8 | 83 | 50 | 33 | 0 | green | | Maraudon | 25 | 8 | 95 | 62 | 33 | 0 | green |
| Ragefire Chasm | 7 | 4 | 21 | 10 | 11 | 0 | green | | Ragefire Chasm | 7 | 4 | 23 | 12 | 11 | 0 | green |
| Dire Maul | 63 | 12 | 184 | 109 | 75 | 0 | green | | Dire Maul | 63 | 12 | 242 | 167 | 75 | 0 | green |
| Hellfire Citadel: The Shattered Halls | 29 | 3 | 74 | 42 | 32 | 0 | green | | Hellfire Citadel: The Shattered Halls | 29 | 3 | 92 | 60 | 32 | 0 | green |
| Hellfire Citadel: The Blood Furnace | 14 | 3 | 44 | 27 | 17 | 0 | green | | Hellfire Citadel: The Blood Furnace | 14 | 3 | 53 | 36 | 17 | 0 | green |
| Hellfire Citadel: Ramparts | 10 | 2 | 36 | 24 | 12 | 0 | green | | Hellfire Citadel: Ramparts | 11 | 4 | 47 | 32 | 12 | 3 | green |
| Coilfang: The Steamvault | 14 | 3 | 50 | 33 | 17 | 0 | green | | Coilfang: The Steamvault | 14 | 3 | 63 | 46 | 17 | 0 | green |
| Coilfang: The Underbog | 18 | 4 | 59 | 37 | 22 | 0 | green | | Coilfang: The Underbog | 20 | 4 | 82 | 58 | 22 | 2 | green |
| Coilfang: The Slave Pens | 18 | 3 | 53 | 32 | 21 | 0 | green | | Coilfang: The Slave Pens | 21 | 4 | 66 | 43 | 21 | 4 | green |
| Tempest Keep: The Arcatraz | 25 | 4 | 73 | 44 | 29 | 0 | green | | Tempest Keep: The Arcatraz | 28 | 4 | 108 | 76 | 29 | 3 | green |
| Tempest Keep: The Botanica | 24 | 5 | 67 | 38 | 29 | 0 | green | | Tempest Keep: The Botanica | 28 | 5 | 89 | 56 | 29 | 4 | green |
| Tempest Keep: The Mechanar | 14 | 3 | 45 | 28 | 17 | 0 | green | | Tempest Keep: The Mechanar | 14 | 3 | 69 | 52 | 17 | 0 | green |
| Auchindoun: Shadow Labyrinth | 18 | 4 | 46 | 24 | 22 | 0 | green | | Auchindoun: Shadow Labyrinth | 18 | 4 | 67 | 45 | 22 | 0 | green |
| Auchindoun: Sethekk Halls | 14 | 2 | 39 | 23 | 16 | 0 | green | | Auchindoun: Sethekk Halls | 19 | 3 | 59 | 37 | 16 | 6 | green |
| Auchindoun: Mana-Tombs | 11 | 3 | 33 | 19 | 14 | 0 | green | | Auchindoun: Mana-Tombs | 12 | 4 | 50 | 34 | 14 | 2 | green |
| Auchindoun: Auchenai Crypts | 12 | 2 | 30 | 16 | 14 | 0 | green | | Auchindoun: Auchenai Crypts | 13 | 3 | 48 | 32 | 14 | 2 | green |
| Magister's Terrace | 15 | 3 | 33 | 15 | 18 | 0 | green | | Magister's Terrace | 23 | 3 | 65 | 39 | 18 | 8 | green |
| The Black Morass | 4 | 3 | 20 | 13 | 7 | 0 | green | | The Black Morass | 13 | 3 | 34 | 18 | 7 | 9 | green |
| The Escape From Durnholde | 26 | 3 | 45 | 16 | 29 | 0 | green | | The Escape From Durnholde | 32 | 3 | 59 | 24 | 29 | 6 | green |
| Utgarde Keep | 19 | 3 | 35 | 13 | 22 | 0 | green | | Utgarde Keep | 19 | 6 | 55 | 30 | 22 | 3 | green |
| Utgarde Pinnacle | 13 | 4 | 32 | 15 | 17 | 0 | green | | Utgarde Pinnacle | 19 | 4 | 50 | 27 | 17 | 6 | green |
| The Nexus | 21 | 5 | 50 | 24 | 26 | 0 | green | | The Nexus | 24 | 5 | 64 | 35 | 26 | 3 | green |
| The Oculus | 8 | 4 | 27 | 15 | 12 | 0 | green | | The Oculus | 17 | 4 | 42 | 21 | 12 | 9 | green |
| The Culling of Stratholme | 16 | 4 | 41 | 21 | 20 | 0 | green | | The Culling of Stratholme | 21 | 4 | 49 | 24 | 20 | 5 | green |
| Halls of Stone | 13 | 4 | 32 | 15 | 16 | 1 | green | | Halls of Stone | 16 | 4 | 45 | 25 | 16 | 4 | green |
| Drak'Tharon Keep | 18 | 4 | 38 | 16 | 22 | 0 | green | | Drak'Tharon Keep | 20 | 4 | 47 | 23 | 22 | 2 | green |
| Azjol-Nerub | 10 | 3 | 25 | 12 | 13 | 0 | green | | Azjol-Nerub | 18 | 3 | 38 | 17 | 13 | 8 | green |
| Halls of Lightning | 16 | 4 | 35 | 15 | 20 | 0 | green | | Halls of Lightning | 19 | 4 | 52 | 29 | 20 | 3 | green |
| Gundrak | 15 | 5 | 43 | 23 | 20 | 0 | green | | Gundrak | 15 | 5 | 53 | 33 | 20 | 0 | green |
| Violet Hold | 2 | 3 | 19 | 14 | 5 | 0 | green | | Violet Hold | 17 | 3 | 39 | 19 | 5 | 15 | green |
| Ahn'kahet: The Old Kingdom | 19 | 5 | 43 | 19 | 24 | 0 | green | | Ahn'kahet: The Old Kingdom | 23 | 5 | 64 | 36 | 24 | 4 | green |
| The Forge of Souls | 11 | 2 | 21 | 8 | 13 | 0 | green | | The Forge of Souls | 11 | 2 | 23 | 10 | 13 | 0 | green |
| Trial of the Champion | 0 | 5 | 22 | 17 | 5 | 0 | green | | Trial of the Champion | 6 | 12 | 123 | 105 | 5 | 13 | green |
| Pit of Saron | 27 | 3 | 43 | 13 | 30 | 0 | green | | Pit of Saron | 31 | 3 | 53 | 19 | 30 | 4 | green |
| Halls of Reflection | 8 | 2 | 26 | 16 | 10 | 0 | green | | Halls of Reflection | 16 | 2 | 46 | 28 | 10 | 8 | green |
| Tinkertech Showdown | 3 | 1 | 8 | 4 | 0 | 4 | green | | Tinkertech Showdown | 3 | 1 | 13 | 12 | 0 | 4 | green |
| Frozen Reach | 3 | 1 | 8 | 4 | 0 | 4 | green | | Frozen Reach | 2 | 1 | 19 | 19 | 0 | 3 | green |
| Forgotten Mine | 3 | 1 | 8 | 4 | 0 | 4 | green | | Forgotten Mine | 4 | 1 | 13 | 12 | 0 | 5 | green |
## Documented source-faithful exceptions ## Documented source-faithful exceptions
- wailing-caverns:entry-3653: Kresh is melee-only in the pinned AzerothCore snapshot; the historical server has no spell or SmartAI row for entry 3653. - wailing-caverns:kresh: Kresh is melee-only in the pinned AzerothCore snapshot; the historical server has no spell or SmartAI row for entry 3653.
- wailing-caverns:deviate-faerie-dragon: The server-faithful rare entry 5912 has no spell rows and is despawned by the Wailing Caverns initialization event. - wailing-caverns:deviate-faerie-dragon: The server-faithful rare entry 5912 has no spell rows and is despawned by the Wailing Caverns initialization event.
- trial-of-the-champion: Trial of the Champion is an encounter arena; its imported combat population is the five Grand Champion bosses, not a trash route. - gnomeregan:wow-classic-batch-three-entry-7361: Grubbis is melee-only in the pinned AzerothCore snapshot; entry 7361 has aggro dialogue and instance-completion rows but no combat spell cast.
- blackrock-spire:entry-9218: Spirestone Battle Lord is a 15% rare spawn in the pinned database and has no combat spell cast beyond its basic melee attack.
- blackrock-spire:entry-9219: Spirestone Butcher is a 15% rare spawn in the pinned database and has no combat spell cast beyond its basic melee attack.
- blackrock-spire:entry-10376: Crystal Fang is a 15% rare spawn with no active combat spell in the pinned database; its exact on-death Spire Spiderling summon is implemented by the instance adapter.
## Issues ## Issues
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,858 @@
{
"schemaVersion": 1,
"scope": "ascension-custom-five-player-source-recovery",
"status": "partial-authoritative-recovery",
"sourcePolicy": {
"exact": "Values copied from installed-client DBC rows or already checksummed map packages.",
"spellLinked": "Creature and gameobject IDs recovered from summon effects in installed-client Spell.dbc. The link is exact even when the missing creature_template or gameobject_template name is inferred from the spell context.",
"authored": "Timing, phase ownership, placement, health tuning, and any entity explicitly marked authored are adaptation decisions, not claims about Ascension server behavior."
},
"sources": [
{
"id": "ascension-area52-spell-dbc",
"kind": "installed-client-dbc",
"pathHint": "../LadiksMPQEditor/client-current/area-52/patch-D/DBFilesClient/Spell.dbc",
"sha256": "2f77f18b91ffbae32a19568e4bc05ec78ee384b6ba8dd2a6e05f0e97abbb2dce",
"header": {
"signature": "WDBC",
"recordCount": 238891,
"fieldCount": 234,
"recordSize": 936,
"stringBlockSize": 14058299
},
"localeField": "enUS",
"confidence": "exact"
},
{
"id": "manastorm-runtime-catalog",
"kind": "installed-client-encounter-export",
"path": "src/game/generated/manastormRuntimeCatalog.json",
"confidence": "exact"
},
{
"id": "manastorm-asset-packages",
"kind": "installed-client-map-export",
"path": "src/game/generated/manastormAssetPackages.json",
"confidence": "exact-environment-provisional-semantics"
},
{
"id": "campaign-runtime-snapshot",
"kind": "generated-runtime-catalog",
"path": "src/game/generated/dungeonCampaignCatalog.json",
"confidence": "exact-current-state"
},
{
"id": "ascension-db-alva",
"kind": "official-public-database",
"url": "https://db.ascension.gg/?npc=97700",
"confidence": "exact"
},
{
"id": "ascension-db-arktos",
"kind": "official-public-database",
"url": "https://db.ascension.gg/?npc=97701",
"confidence": "exact"
},
{
"id": "ascension-changelog-frozen-reach-blast-arrow",
"kind": "official-changelog",
"url": "https://ascension.gg/en/changelog/1?page=7",
"confidence": "exact-wording-name-differs"
},
{
"id": "ascension-changelog-frozen-reach-rebirth",
"kind": "official-changelog",
"url": "https://ascension.gg/en/changelog/1?page=8",
"confidence": "exact"
},
{
"id": "ascension-changelog-forgotten-mine-crystals",
"kind": "official-changelog",
"url": "https://ascension.gg/en/changelog/1?page=51",
"confidence": "exact"
},
{
"id": "ascension-changelog-forgotten-mine-geospike",
"kind": "official-changelog",
"url": "https://ascension.gg/en/changelog/1?page=29",
"confidence": "exact"
}
],
"localSearchAudit": {
"searchedRoots": [
"../wow-pvt-server-backups-2",
"../WoW-Pvt-Server-Backups",
"../wow-private-server-notes",
"../LadiksMPQEditor",
"../wow335a/Cache",
"../resources/client/Cache"
],
"searchedArtifacts": [
"creature_template and creature spawn SQL",
"gameobject_template and gameobject spawn SQL",
"SmartAI and ScriptName bindings",
"Lua/XML/JSON/CSV encounter data",
"creaturecache.wdb and gameobjectcache.wdb records"
],
"missingAuthoritativeData": [
"creature templates and display mappings for 663012, 97700, and 254272",
"world spawn rows for maps 821, 908, and 1781",
"server-side encounter scripts and cast cadence",
"authoritative trash population and patrol routes",
"authoritative gameobject placements"
],
"publicSnapshotCheck": {
"repository": "https://github.com/Ascension-Addons/Questie-X-AscensionDB.git",
"commit": "cf6710ef94c264d842cf2ea94c4b50e9ece6dd61",
"result": "No target boss IDs, names, spawns, or encounter scripts were present."
}
},
"dungeons": [
{
"mapId": 821,
"id": "tinkertech-showdown",
"title": "Tinkertech Showdown",
"mapDirectory": "TinketechShowdown",
"sourceClassification": "identity-and-environment-only",
"environment": {
"sourceHash": "323c47c081d0a6c39daf9878284863c21e3e38dbced2ba3f58d1d157d080d41d",
"rootWmo": "World/wmo/Dungeon/AZ_Subway/Subway_Dungeon.wmo",
"anchors": {
"player": [
3.648781,
-4.167801,
66.263252
],
"trash": [
10.220209,
-126.067818,
1266.206177
],
"boss": [
-15.779793,
-4.267807,
2439.406006
]
},
"semanticStatus": "provisional-geometry-derived"
},
"encounters": [
{
"encounterId": 9013,
"modeId": 2,
"name": "Mechatron",
"creatureId": 663012,
"identityConfidence": "exact"
}
],
"currentRuntime": {
"bossEntityId": "entry-663012",
"proceduralTrashSpawnCount": 15,
"proceduralMobEntries": [
{
"entityId": "tinkertech-showdown-guardian",
"serverEntry": 2629079128
},
{
"entityId": "tinkertech-showdown-caster",
"serverEntry": 3849447491
},
{
"entityId": "tinkertech-showdown-brute",
"serverEntry": 1787979165
}
]
},
"sourceRecovery": {
"association": "candidate-client-cluster-only",
"associationConfidence": "low",
"reason": "These adjacent client rows form a coherent mechanical-machine kit and include Sound: Goblin Head Machine Loop, but no recovered server row links them to creature 663012.",
"spellRows": {
"257438": "Rocket",
"257459": "Gatling Missile Barrage",
"257460": "Gatling Missile",
"257461": "Gatling Missile",
"257462": "Sound: Goblin Head Machine Loop",
"257470": "Incineration Beam",
"257471": "Energy Ball",
"257472": "Electrified Zone",
"257473": "Electric Shock"
},
"families": {
"rocket": [
257438
],
"gatlingMissileBarrage": [
257459,
257460,
257461
],
"incinerationBeam": [
257470
],
"electrifiedZone": [
257472,
257473
]
}
},
"adaptation": {
"status": "custom-authoring-required",
"populationPlan": {
"disposition": "retain-current-route-as-explicit-adaptation",
"packCount": 5,
"membersPerPack": 3,
"authoredMobs": [
{
"serverEntry": 2629079128,
"name": "Tinkertech Guardbot",
"role": "melee-interceptor"
},
{
"serverEntry": 3849447491,
"name": "Tinkertech Coilcaster",
"role": "electrical-ranged"
},
{
"serverEntry": 1787979165,
"name": "Tinkertech Demolisher",
"role": "rocket-bruiser"
}
]
},
"encounterPlan": [
"Mechatron remains creature 663012 at the provisional boss anchor.",
"Rocket uses a 2.0 second target reticle and splash damage on an authored 8 second cadence.",
"Gatling Missile Barrage uses a 3.0 second warning followed by eight lane impacts over 4 seconds on an authored 14 second cadence.",
"Incineration Beam uses a 2.5 second wind-up and sweeps the subway lane for 5 seconds; immutable web geometry means it visually disables lane sections instead of permanently destroying client platforms.",
"Electrified Zone alternates floor strips after a 1.5 second warning, remains active for 8 seconds, and applies a 1.5 second stun on contact.",
"At 35 percent health, cadence accelerates by 20 percent and two authored Coilcasters enter from the previous pack anchor."
],
"mustBeCustomAuthored": [
"all trash identities, placements, and AI",
"all boss timing and phase thresholds",
"the decision to associate candidate spells 257438 and 257459-257473 with Mechatron",
"platform or lane disable behavior",
"boss and trash visual composites",
"loot and completion scripting"
]
},
"unresolved": [
"No authoritative Mechatron spell-to-creature binding was found.",
"No authoritative trash or gameobject IDs were found.",
"The custom ADT placement transform and all semantic anchors still require playtest approval."
]
},
{
"mapId": 908,
"id": "frozen-reach",
"title": "Frozen Reach",
"mapDirectory": "Alvaencounter",
"sourceClassification": "encounter-spells-and-summons-recovered",
"environment": {
"sourceHash": "5ab771df79c0e062cea3ebda4e416a9245bcf8a4cc6da048077df5e674081f97",
"anchors": {
"player": [
1858.534668,
78.860199,
2229.334473
],
"trash": [
2100.134766,
80.860199,
2132.93457
],
"boss": [
2344.134766,
62.460205,
2134.334717
]
},
"semanticStatus": "provisional-elevated-encounter-component"
},
"encounters": [
{
"encounterId": 2168,
"modeId": 0,
"name": "Alva",
"creatureId": 97700,
"identityConfidence": "exact"
},
{
"encounterId": 2170,
"modeId": 2,
"name": "Alva",
"creatureId": 97700,
"identityConfidence": "exact"
}
],
"entities": [
{
"entryId": 97700,
"name": "Alva",
"role": "boss",
"sourceKind": "encounter-dbc-and-official-db"
},
{
"entryId": 97701,
"name": "Arktos",
"role": "boss-companion",
"sourceKind": "official-db"
},
{
"entryId": 97703,
"name": "Blast Arrow summoned unit",
"role": "area-trigger",
"sourceKind": "spell-linked-name-inferred"
},
{
"entryId": 97731,
"name": "Explosive Trap summoned unit",
"role": "trap",
"sourceKind": "spell-linked-name-inferred"
},
{
"entryId": 97770,
"name": "Alvajar summoned unit",
"role": "add",
"sourceKind": "spell-linked-name-inferred"
}
],
"currentRuntime": {
"bossEntityId": "entry-97700",
"proceduralTrashSpawnCount": 15,
"proceduralMobEntries": [
{
"entityId": "frozen-reach-guardian",
"serverEntry": 1606324391
},
{
"entityId": "frozen-reach-caster",
"serverEntry": 854807736
},
{
"entityId": "frozen-reach-brute",
"serverEntry": 2855026892
}
]
},
"sourceRecovery": {
"association": "explicit-alva-arktos-client-cluster",
"associationConfidence": "high",
"spellRows": {
"255347": "Auto Shot",
"255349": "Rain of Arrows",
"255351": "Rain of Arrows",
"255352": "Unbridled Arrows",
"255353": "Unbridled Arrows",
"255358": "Blast Arrow",
"255359": "Blast Arrow",
"255360": "Pact of the Hunt",
"255362": "Blast Arrow",
"255363": "Blast Arrow",
"255374": "Ice Rock",
"255375": "Ice Rock",
"255377": "Ice Rock",
"255378": "Unholy Frenzy",
"255379": "Carnivorous Bite",
"255380": "Frost Shield",
"255381": "Set Ablaze",
"255382": "Blaze",
"255387": "Frost Strike",
"255389": "Shadow Shroud Surge",
"255390": "Shadow Shroud Rebirth",
"255393": "Sphere of Grief and Wrath",
"255394": "Vengeful Bolt",
"255395": "Vengeful Bolt",
"255397": "Shadow Veil Lance",
"255398": "Shadow Veil Lance",
"255399": "Frost Roar",
"255401": "Cluster Shot",
"255402": "Cluster Shot",
"255403": "Cluster Shot",
"255410": "Alva's Grief",
"255411": "Alva's Grief",
"255412": "Frost orb",
"255413": "Frozen Pulse",
"255417": "Shield Wall",
"255418": "Shield Wall",
"255419": "Alva's Wrath",
"255420": "Throw Explosive Trap",
"255421": "Explosive Trap",
"255423": "Trap Explosion",
"255424": "Charging",
"255426": "Explosive Trap",
"255427": "Frostblade Strike",
"255428": "Frostblade Strike",
"255432": "Army of the Dead",
"255433": "Army of the Dead",
"255434": "Lacerate",
"255435": "Lacerate",
"255436": "Lacerate",
"255437": "Arcing Slice",
"255438": "Rain of Arrows",
"255439": "Rain of Arrows",
"255440": "Cluster Shot",
"255441": "Cluster Shot",
"255442": "Unbridled Arrows",
"255443": "Unbridled Arrows",
"255444": "Blast Arrow",
"255445": "Blast Arrow",
"255446": "Frost Roar",
"255447": "Frost Roar",
"255448": "Vengeful Bolt",
"255449": "Vengeful Bolt",
"255450": "Ice Rock",
"255451": "Ice Rock",
"255452": "Frostblade Strike",
"255453": "Frostblade Strike",
"255454": "Shadow Shroud Surge",
"255455": "Shadow Shroud Surge",
"255456": "Shadow Shroud Rebirth",
"255457": "Shadow Shroud Rebirth",
"255458": "Shadow Veil Lance",
"255459": "Shadow Veil Lance",
"255460": "Alva's Wrath",
"255461": "Alva's Wrath",
"255462": "Sphere of Grief and Wrath",
"255463": "Sphere of Grief and Wrath",
"255464": "Frost Strike",
"255465": "Frost Strike",
"255466": "Predator's Fury",
"255467": "Alva's Grief",
"255468": "Alva's Grief",
"255469": "Trap Explosion",
"255470": "Trap Explosion",
"255471": "Frozen Pulse",
"255472": "Frozen Pulse"
},
"families": {
"alvaRanged": [
255347,
255349,
255351,
255352,
255353,
255358,
255359,
255401,
255402,
255403,
255420,
255421,
255423,
255424
],
"arktos": [
255360,
255374,
255375,
255377,
255378,
255379,
255380,
255381,
255382,
255387,
255399,
255417,
255418,
255434
],
"alvaVengeance": [
255389,
255390,
255393,
255394,
255395,
255397,
255398,
255410,
255411,
255419,
255432,
255433
],
"difficultyOneAndTwoVariants": [
255435,
255436,
255438,
255439,
255440,
255441,
255442,
255443,
255444,
255445,
255446,
255447,
255448,
255449,
255450,
255451,
255452,
255453,
255454,
255455,
255456,
255457,
255458,
255459,
255460,
255461,
255462,
255463,
255464,
255465,
255467,
255468,
255469,
255470,
255471,
255472
]
},
"summonLinks": [
{
"spellId": 255363,
"effectIndex": 0,
"effectType": 28,
"targetKind": "creature",
"entryId": 97703
},
{
"spellId": 255421,
"effectIndex": 0,
"effectType": 28,
"targetKind": "creature",
"entryId": 97731
},
{
"spellId": 255433,
"effectIndex": 0,
"effectType": 28,
"targetKind": "creature",
"entryId": 97770
}
]
},
"adaptation": {
"status": "source-backed-custom-cadence-required",
"populationPlan": {
"disposition": "remove-unverified-generic-trash",
"reason": "Alvaencounter and the recovered spell cluster describe a contained Alva/Arktos encounter; no evidence supports the current 15 generic hallway creatures.",
"encounterEntities": [
97700,
97701,
97703,
97731,
97770
]
},
"encounterPlan": [
"Phase one starts Alva 97700 and Arktos 97701 together, with Pact of the Hunt 255360 active while they remain close.",
"Alva uses Rain of Arrows, Unbridled Arrows, Blast Arrow, Cluster Shot, and summoned Explosive Traps; Arktos uses Carnivorous Bite, Ice Rock, Frost Roar, Lacerate, and defensive Frost Shield or Shield Wall.",
"Blast Arrow can strike Arktos and apply Set Ablaze 255381, causing panic movement, Blaze 255382, and increased damage taken. This matches the official changelog's Blast Shot/Arktos interaction despite the DBC naming it Blast Arrow.",
"Arktos death leaves Alva's Grief 255410 around the corpse and transitions Alva to the vengeance kit.",
"The transition casts Shadow Shroud Rebirth 255390 and summons four Alvajar 97770 around the arena. Rebirth damage must scale by living group size, reaching full value at five or more players per the official changelog.",
"Phase two rotates Vengeful Bolt, Shadow Veil Lance, Sphere of Grief and Wrath, Army of the Dead, and stacking Alva's Wrath as the soft enrage.",
"Wire ASC D0 rows to the current normal experience. Preserve D1 and D2 rows but do not assign public difficulty labels until an authoritative mode mapping is recovered."
],
"authoredCadence": {
"rainOfArrowsMs": 12000,
"unbridledArrowsMs": 20000,
"blastArrowMs": 15000,
"clusterShotMs": 18000,
"explosiveTrapMs": 16000,
"arktosIceRockMs": 12000,
"arktosFrostRoarMs": 18000,
"vengefulBoltMs": 7000,
"shadowVeilLanceMs": 12000,
"sphereOfGriefMs": 20000,
"alvasWrathMs": 25000
},
"mustBeCustomAuthored": [
"all cast cadence and target-selection rules",
"Arktos initial placement and companion pathing",
"phase transition and exact death threshold behavior",
"Alvajar formation and spawn placement",
"trap and area-trigger web-runtime behavior",
"boss and add visual composites",
"loot and completion scripting"
]
},
"unresolved": [
"The server-side spell schedule and encounter script are absent.",
"Creature template stats, display IDs, and exact positions are absent.",
"ASC D0/D1/D2 spell ranks cannot be mapped safely beyond D0 without a surviving difficulty script."
]
},
{
"mapId": 1781,
"id": "forgotten-mine",
"title": "Forgotten Mine",
"mapDirectory": "ForgottenMine",
"sourceClassification": "encounter-spells-creature-summon-and-gameobject-recovered",
"environment": {
"sourceHash": "693b7067aa1109e14beb944bc95aed8299bf64e2ec6ae3dc43f4fab7d18f57b6",
"anchors": {
"player": [
1285.886108,
149.58075,
1724.264526
],
"trash": [
1857.461304,
136.080749,
1871.884277
],
"boss": [
2246.06665,
198.180786,
2147.866699
]
},
"semanticStatus": "provisional-main-navigation-component"
},
"encounters": [
{
"encounterId": 5069,
"modeId": 0,
"name": "Geolord Vek",
"creatureId": 254272,
"identityConfidence": "exact"
},
{
"encounterId": 5071,
"modeId": 2,
"name": "Geolord Vek",
"creatureId": 254272,
"identityConfidence": "exact"
}
],
"entities": [
{
"entryId": 254272,
"name": "Geolord Vek",
"role": "boss",
"sourceKind": "encounter-dbc"
},
{
"entryId": 254278,
"name": "Geospike summoned unit",
"role": "hazard",
"sourceKind": "spell-linked-name-inferred"
}
],
"gameObjects": [
{
"entryId": 254051,
"name": "Resonite Shard",
"role": "clickable-encounter-countermeasure",
"sourceKind": "spell-linked-name-from-create-spell"
}
],
"currentRuntime": {
"bossEntityId": "entry-254272",
"proceduralTrashSpawnCount": 15,
"proceduralMobEntries": [
{
"entityId": "forgotten-mine-guardian",
"serverEntry": 4175632753
},
{
"entityId": "forgotten-mine-caster",
"serverEntry": 647988074
},
{
"entityId": "forgotten-mine-brute",
"serverEntry": 2677742134
}
]
},
"sourceRecovery": {
"association": "explicit-vek-client-cluster",
"associationConfidence": "high",
"reason": "The contiguous cluster contains Vek Death and Vek Reset control rows alongside the complete earth and Resonite kit.",
"spellRows": {
"354000": "Stonebreaker",
"354001": "Quake",
"354002": "Stone Shield",
"354003": "Cosmetic Fear",
"354004": "Geospike",
"354005": "Geospike",
"354006": "Geospike",
"354007": "Vek Death",
"354008": "Vek Reset",
"354009": "Quake",
"354010": "Quake",
"354011": "Stone Shield",
"354012": "Stone Shield",
"354013": "Resonance",
"354014": "Resonance",
"354015": "Geode Barrage",
"354016": "Geode Barrage",
"354017": "Ruptured Earth",
"354018": "Ruptured Earth",
"354019": "Stoneskin",
"354020": "Stoneskin",
"354021": "Stonebreaker",
"354022": "Stonebreaker",
"354023": "Stonebreaker",
"354024": "Stonebreaker",
"354025": "Geospike",
"354026": "Geospike",
"354027": "Geode Barrage",
"354028": "Geode Barrage",
"354029": "Geode Barrage",
"354030": "Geode Barrage",
"354031": "Resonite Cleanse",
"354032": "Create Resonite Shard"
},
"families": {
"control": [
354007,
354008
],
"quake": [
354001,
354009,
354010
],
"stoneShield": [
354002,
354011,
354012
],
"geospike": [
354004,
354005,
354006,
354025,
354026
],
"resonance": [
354013,
354014
],
"geodeBarrage": [
354015,
354016,
354027,
354028,
354029,
354030
],
"rupturedEarth": [
354017,
354018
],
"stoneskin": [
354019,
354020
],
"stonebreaker": [
354000,
354021,
354022,
354023,
354024
],
"resonite": [
354031,
354032
]
},
"summonLinks": [
{
"spellId": 354004,
"effectIndex": 0,
"effectType": 28,
"targetKind": "creature",
"entryId": 254278
},
{
"spellId": 354032,
"effectIndex": 0,
"effectType": 76,
"targetKind": "gameobject",
"entryId": 254051
}
]
},
"adaptation": {
"status": "source-backed-custom-cadence-required",
"populationPlan": {
"disposition": "retain-current-route-as-explicit-adaptation",
"packCount": 5,
"membersPerPack": 3,
"authoredMobs": [
{
"serverEntry": 4175632753,
"name": "Forgotten Mine Stoneguard",
"role": "shielding-melee"
},
{
"serverEntry": 647988074,
"name": "Forgotten Mine Geomancer",
"role": "geode-ranged"
},
{
"serverEntry": 2677742134,
"name": "Forgotten Mine Quarry Brute",
"role": "frontal-bruiser"
}
]
},
"encounterPlan": [
"Geolord Vek 254272 remains at the provisional boss anchor and opens with Stone Shield.",
"Stonebreaker is a telegraphed frontal strike; Quake is a short-range raid pulse; Geode Barrage repeatedly targets one player; Ruptured Earth creates a marked split-damage pillar.",
"Geospike 354004 summons entry 254278 after a clearly visible ground telegraph. The hazard erupts with the matching Geospike damage row and then despawns.",
"Three clickable Resonite Shard gameobjects 254051 appear at authored offsets around the boss. Clicking consumes one and applies Resonite Cleanse 354031, which removes one active earth protection or prevents the next Resonance hit.",
"At 50 percent health, Resonance begins and Vek alternates Quake with Ruptured Earth. Missing crystals respawn once per 30 second cycle.",
"The official changelog requires large, obvious clickable crystal bounds and a high-contrast Geospike telegraph."
],
"authoredGameObjectOffsetsFromBoss": [
[
-12,
0,
0
],
[
6,
0,
10.392
],
[
6,
0,
-10.392
]
],
"authoredCadence": {
"stonebreakerMs": 6500,
"geodeBarrageMs": 11000,
"geospikeMs": 15000,
"quakeMs": 18000,
"rupturedEarthMs": 22000,
"resoniteCycleMs": 30000
},
"mustBeCustomAuthored": [
"all trash identities, placements, and AI",
"all boss cadence, target selection, and phase thresholds",
"the exact Resonite Cleanse interaction because the server script is absent",
"crystal placement, interaction bounds, and respawn rules",
"Geospike hazard placement and lifetime",
"boss, hazard, trash, and crystal visual composites",
"loot and completion scripting"
]
},
"unresolved": [
"Paired low/high-value spell rows do not expose a safe difficulty-label mapping.",
"The authoritative creature and gameobject spawn coordinates are absent.",
"Creature template stats and visual display IDs are absent.",
"The exact Resonite click result is only constrained by client spell text and official changelog behavior."
]
}
]
}
@@ -0,0 +1,97 @@
# Ascension custom dungeon source recovery
This report separates recoverable client facts from the behavior that HealerMan must author for Tinkertech Showdown (821), Frozen Reach (908), and Forgotten Mine (1781). The machine-readable companion is `ASCENSION_CUSTOM_DUNGEON_RECOVERY.json`; its validator checks both the current generated catalogs and the original installed-client `Spell.dbc`.
## Result
| Map | Recovered exactly | Still requires adaptation |
| --- | --- | --- |
| 821 Tinkertech Showdown | Client environment, encounter 9013, boss creature 663012 | Every spawn, trash identity, gameobject, spell binding, boss schedule, phase, visual, loot, and completion rule |
| 908 Frozen Reach | Client environment, encounters 2168/2170, Alva 97700, Arktos 97701, three summoned entries, and 85 encounter spell rows | Positions, stats, cast schedule, target rules, phase scripting, web hazards, visuals, loot, and completion rules |
| 1781 Forgotten Mine | Client environment, encounters 5069/5071, Geolord Vek 254272, Geospike summon 254278, Resonite Shard gameobject 254051, and 33 encounter spell rows | Positions, stats, cast schedule, trash roster, crystal behavior, hazard lifetime, visuals, loot, and completion rules |
The local server/reference repositories, installed WDB caches, addon databases, and the public Questie Ascension snapshot do not contain surviving creature templates, world spawn rows, SmartAI, or encounter scripts for these maps. Client spell rows prove names and summon targets, but they do not prove cast cadence, ownership in every case, or coordinates.
## 821: Tinkertech Showdown
Exact client facts:
- Map directory: `TinketechShowdown` (the client spelling omits the second `r`). Source hash: `323c47c081d0a6c39daf9878284863c21e3e38dbced2ba3f58d1d157d080d41d`.
- The recovered root WMO is `World/wmo/Dungeon/AZ_Subway/Subway_Dungeon.wmo`.
- Manastorm encounter 9013 names Mechatron and binds it to creature 663012 in mode 2.
- The player, trash, and boss anchors in the manifest are geometry-derived and provisional, not recovered server spawn points.
Candidate-only evidence:
- Spell 257438 `Rocket`.
- Spells 257459-257461 `Gatling Missile Barrage` / `Gatling Missile`.
- Spell 257462 `Sound: Goblin Head Machine Loop`.
- Spell 257470 `Incineration Beam`, spell 257471 `Energy Ball`, and spells 257472-257473 `Electrified Zone` / `Electric Shock`.
Those rows form a coherent goblin-machine cluster, but no surviving source binds them to creature 663012. They must stay labeled as an adaptation if used.
Concrete adaptation:
- Retain the current route as five authored three-creature packs. Recast generated entries 2629079128, 3849447491, and 1787979165 as `Tinkertech Guardbot`, `Tinkertech Coilcaster`, and `Tinkertech Demolisher`; these IDs and names remain HealerMan-owned.
- Keep Mechatron 663012 at the provisional boss anchor.
- Use an authored rotation of Rocket reticles, Gatling lane impacts, Incineration Beam lane sweeps, and alternating Electrified Zones. At 35% health, accelerate the rotation and add two Coilcasters.
- Model platform destruction as temporary lane disabling because the imported web geometry is immutable.
Everything in that combat implementation except the boss identity and candidate spell names is custom-authored. It should not be represented as recovered Ascension parity.
## 908: Frozen Reach
Exact client facts:
- Map directory: `Alvaencounter`. Source hash: `5ab771df79c0e062cea3ebda4e416a9245bcf8a4cc6da048077df5e674081f97`.
- Manastorm encounters 2168 and 2170 name Alva and bind her to creature 97700 in modes 0 and 2.
- The official Ascension database identifies Alva as creature 97700 and Arktos as creature 97701.
- Spell 255363 summons creature 97703, spell 255421 summons creature 97731, and spell 255433 summons creature 97770. In context these are the Blast Arrow unit, Explosive Trap, and Alvajar add.
- The client cluster spans 85 exact rows from 255347 through 255472. The principal families are Rain of Arrows, Unbridled Arrows, Blast Arrow, Cluster Shot, Pact of the Hunt, Ice Rock, Carnivorous Bite, Frost Shield, Set Ablaze, Blaze, Frost Strike, Frost Roar, Lacerate, Shield Wall, Shadow Shroud Surge/Rebirth, Vengeful Bolt, Shadow Veil Lance, Sphere of Grief and Wrath, Alva's Grief/Wrath, Explosive Trap, and Army of the Dead.
- The official changelog confirms that the Blast Arrow/“Blast Shot” interaction can hit Arktos and that Shadow Shroud Rebirth reaches full damage scaling at five or more players.
Concrete adaptation:
- Remove the current 15 procedural hallway creatures (entries 1606324391, 854807736, and 2855026892). Available evidence describes a contained Alva/Arktos encounter and provides no support for that generic trash population.
- Start Alva 97700 and Arktos 97701 together with Pact of the Hunt. Give Alva the recovered ranged/trap kit and Arktos the recovered bite, ice, roar, lacerate, and defensive kit.
- Allow Blast Arrow to apply Set Ablaze to Arktos, forcing panic movement and increased damage taken.
- On Arktos's death, leave Alva's Grief at the corpse, cast Shadow Shroud Rebirth, summon four Alvajar 97770, and move Alva into the recovered vengeance spell family.
- Preserve D1/D2 spell variants as source data but use D0 for the current normal experience until a surviving difficulty mapping is found.
The exact cadence in the JSON is an explicit HealerMan proposal. Initial positions, transition rules, summon formation, stats, targeting, and hazard implementation all remain custom-authored.
## 1781: Forgotten Mine
Exact client facts:
- Map directory: `ForgottenMine`. Source hash: `693b7067aa1109e14beb944bc95aed8299bf64e2ec6ae3dc43f4fab7d18f57b6`.
- Manastorm encounters 5069 and 5071 name Geolord Vek and bind him to creature 254272 in modes 0 and 2.
- The contiguous 354000-354032 spell cluster explicitly contains `Vek Death` and `Vek Reset`, tying the cluster to Vek.
- The recovered families are Stonebreaker, Quake, Stone Shield, Geospike, Resonance, Geode Barrage, Ruptured Earth, Stoneskin, Resonite Cleanse, and Create Resonite Shard.
- Spell 354004 summons Geospike creature 254278. Spell 354032 creates gameobject 254051, named by the spell as a Resonite Shard.
- Client text says Resonite counters the power of Earth. Official changelogs additionally require larger clickable crystal bounds and a visible Geospike telegraph.
Concrete adaptation:
- Retain five authored three-creature route packs only as an explicit approximation. Recast generated entries 4175632753, 647988074, and 2677742134 as `Forgotten Mine Stoneguard`, `Forgotten Mine Geomancer`, and `Forgotten Mine Quarry Brute`; these are not recovered Ascension creatures.
- Keep Geolord Vek 254272 at the provisional boss anchor. Rotate Stonebreaker, Quake, Geode Barrage, Geospike, and Ruptured Earth, then begin Resonance at 50% health.
- Spawn three clickable Resonite Shards 254051 at the authored triangular offsets in the JSON. Consuming a shard applies Resonite Cleanse 354031 and removes one active earth protection or prevents the next Resonance hit.
- Give Geospike 254278 a high-contrast ground warning, eruption, and despawn sequence. Make crystal interaction bounds deliberately generous.
The crystal effect is constrained by spell text and changelog behavior but its exact server-side rule did not survive. Trash, timing, targeting, positions, respawn cadence, and visuals are custom-authored.
## Integration boundary
The recovery files intentionally do not change `compile-campaign-catalog.mjs`. Runtime integration should consume the recovered IDs and family lists while preserving three provenance labels:
- `exact`: copied from checksummed client/catalog data.
- `spellLinked`: an entry ID read directly from a DBC summon effect; its descriptive name can still be contextual.
- `authored`: HealerMan timing, placement, visuals, or behavior.
Validate the recovery against the current catalogs and installed client with:
```powershell
node scripts/dungeon-pipeline/validate-ascension-custom-dungeon-recovery.mjs
```
Use `--skip-dbc` only on machines without the checksummed Area-52 client, or pass another byte-identical file with `--dbc <path>`.
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
@@ -27,6 +27,7 @@
} }
], ],
"environmentMode": "detect", "environmentMode": "detect",
"coordinateAlignment": "source",
"exceptions": [], "exceptions": [],
"expansion": "wrath", "expansion": "wrath",
"extraction": { "extraction": {
+5 -1
View File
@@ -8,7 +8,11 @@
"clientBuild": "3.3.5a-Ascension", "clientBuild": "3.3.5a-Ascension",
"mapDirectory": "World/Maps/TempestKeepArcane", "mapDirectory": "World/Maps/TempestKeepArcane",
"environmentMode": "global-wmo", "environmentMode": "global-wmo",
"difficultyVariants": [{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [65, 70]}], "coordinateAlignment": "source",
"difficultyVariants": [
{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [65, 70]},
{"id": "heroic", "difficulty": "heroic", "spawnMask": 2, "levelRange": [70, 70]}
],
"clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"}, "clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"},
"serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true}, "serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true},
"extraction": {"rootWmo": "World/wmo/Dungeon/OL_TempestKeep/TK_Arcane.wmo", "doodadSets": ["Set_$DefaultGlobal"]}, "extraction": {"rootWmo": "World/wmo/Dungeon/OL_TempestKeep/TK_Arcane.wmo", "doodadSets": ["Set_$DefaultGlobal"]},
@@ -8,7 +8,11 @@
"clientBuild": "3.3.5a-Ascension", "clientBuild": "3.3.5a-Ascension",
"mapDirectory": "World/Maps/AuchindounDraenei", "mapDirectory": "World/Maps/AuchindounDraenei",
"environmentMode": "global-wmo", "environmentMode": "global-wmo",
"difficultyVariants": [{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [65, 70]}], "coordinateAlignment": "source",
"difficultyVariants": [
{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [65, 70]},
{"id": "heroic", "difficulty": "heroic", "spawnMask": 2, "levelRange": [70, 70]}
],
"clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"}, "clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"},
"serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true}, "serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true},
"extraction": {"rootWmo": "World/wmo/Dungeon/OL_Auchindoun/Draenei_wing.wmo", "doodadSets": ["Set_$DefaultGlobal"]}, "extraction": {"rootWmo": "World/wmo/Dungeon/OL_Auchindoun/Draenei_wing.wmo", "doodadSets": ["Set_$DefaultGlobal"]},
@@ -27,6 +27,7 @@
} }
], ],
"environmentMode": "detect", "environmentMode": "detect",
"coordinateAlignment": "source",
"exceptions": [], "exceptions": [],
"expansion": "wrath", "expansion": "wrath",
"extraction": { "extraction": {
@@ -27,6 +27,7 @@
} }
], ],
"environmentMode": "detect", "environmentMode": "detect",
"coordinateAlignment": "source",
"exceptions": [], "exceptions": [],
"expansion": "burning-crusade", "expansion": "burning-crusade",
"extraction": { "extraction": {
@@ -8,6 +8,7 @@
"clientBuild": "3.3.5a-Ascension", "clientBuild": "3.3.5a-Ascension",
"mapDirectory": "World/Maps/Blackfathom", "mapDirectory": "World/Maps/Blackfathom",
"environmentMode": "global-wmo", "environmentMode": "global-wmo",
"coordinateAlignment": "source",
"difficultyVariants": [{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [20, 30]}], "difficultyVariants": [{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [20, 30]}],
"clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"}, "clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"},
"serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true}, "serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true},
@@ -8,6 +8,7 @@
"clientBuild": "3.3.5a-Ascension", "clientBuild": "3.3.5a-Ascension",
"mapDirectory": "World/Maps/BlackrockDepths", "mapDirectory": "World/Maps/BlackrockDepths",
"environmentMode": "global-wmo", "environmentMode": "global-wmo",
"coordinateAlignment": "source",
"difficultyVariants": [{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [50, 60]}], "difficultyVariants": [{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [50, 60]}],
"clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"}, "clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"},
"serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true}, "serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true},
@@ -8,6 +8,7 @@
"clientBuild": "3.3.5a-Ascension", "clientBuild": "3.3.5a-Ascension",
"mapDirectory": "World/Maps/BlackRockSpire", "mapDirectory": "World/Maps/BlackRockSpire",
"environmentMode": "global-wmo", "environmentMode": "global-wmo",
"coordinateAlignment": "source",
"difficultyVariants": [{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [55, 60]}], "difficultyVariants": [{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [55, 60]}],
"clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"}, "clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"},
"serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true}, "serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true},
@@ -0,0 +1,18 @@
{
"schemaVersion": 1,
"slug": "blades-edge-arena",
"title": "Blade's Edge Arena",
"mapId": 562,
"lfgDungeonIds": [],
"expansion": "the-burning-crusade",
"clientBuild": "3.3.5a",
"mapDirectory": "World/Maps/bladesedgearena",
"environmentMode": "global-wmo",
"difficultyVariants": [{"id": "rated", "difficulty": "normal", "spawnMask": 1, "levelRange": [80, 80]}],
"clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"},
"serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true},
"extraction": {"rootWmo": "World/wmo/PvP/Buildings/AncientOrcArena/ancorc_PVPstadium.wmo", "doodadSets": ["Set_$DefaultGlobal"]},
"navigation": {"cellSize": 0.2, "cellHeight": 0.1, "agentHeight": 1.8, "agentRadius": 0.36, "agentMaxClimb": 0.5, "agentMaxSlope": 50},
"review": {"entrance": "required", "bossOrder": "not-applicable", "optionalEncounters": "not-applicable", "presentation": "required", "offMeshLinks": "required"},
"exceptions": []
}
+5 -1
View File
@@ -8,7 +8,11 @@
"clientBuild": "3.3.5a-Ascension", "clientBuild": "3.3.5a-Ascension",
"mapDirectory": "World/Maps/HellfireDemon", "mapDirectory": "World/Maps/HellfireDemon",
"environmentMode": "global-wmo", "environmentMode": "global-wmo",
"difficultyVariants": [{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [58, 70]}], "coordinateAlignment": "source",
"difficultyVariants": [
{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [58, 70]},
{"id": "heroic", "difficulty": "heroic", "spawnMask": 2, "levelRange": [70, 70]}
],
"clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"}, "clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"},
"serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true}, "serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true},
"extraction": {"rootWmo": "World/wmo/Dungeon/Hellfire/hellfire_DemonWing.wmo", "doodadSets": ["Set_$DefaultGlobal"]}, "extraction": {"rootWmo": "World/wmo/Dungeon/Hellfire/hellfire_DemonWing.wmo", "doodadSets": ["Set_$DefaultGlobal"]},
+5 -1
View File
@@ -8,7 +8,11 @@
"clientBuild": "3.3.5a-Ascension", "clientBuild": "3.3.5a-Ascension",
"mapDirectory": "World/Maps/TempestKeepAtrium", "mapDirectory": "World/Maps/TempestKeepAtrium",
"environmentMode": "global-wmo", "environmentMode": "global-wmo",
"difficultyVariants": [{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [65, 70]}], "coordinateAlignment": "source",
"difficultyVariants": [
{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [65, 70]},
{"id": "heroic", "difficulty": "heroic", "spawnMask": 2, "levelRange": [70, 70]}
],
"clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"}, "clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"},
"serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true}, "serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true},
"extraction": {"rootWmo": "World/wmo/Dungeon/OL_TempestKeep/TK_Atrium.wmo", "doodadSets": ["Set_$DefaultGlobal"]}, "extraction": {"rootWmo": "World/wmo/Dungeon/OL_TempestKeep/TK_Atrium.wmo", "doodadSets": ["Set_$DefaultGlobal"]},
@@ -27,6 +27,7 @@
} }
], ],
"environmentMode": "detect", "environmentMode": "detect",
"coordinateAlignment": "source",
"exceptions": [], "exceptions": [],
"expansion": "wrath", "expansion": "wrath",
"extraction": { "extraction": {
@@ -0,0 +1,18 @@
{
"schemaVersion": 1,
"slug": "dalaran-sewers",
"title": "Dalaran Sewers",
"mapId": 617,
"lfgDungeonIds": [],
"expansion": "wrath-of-the-lich-king",
"clientBuild": "3.3.5a",
"mapDirectory": "World/Maps/DalaranArena",
"environmentMode": "global-wmo",
"difficultyVariants": [{"id": "rated", "difficulty": "normal", "spawnMask": 1, "levelRange": [80, 80]}],
"clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"},
"serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true},
"extraction": {"rootWmo": "World/wmo/PvP/Buildings/Dalaran/dalaran_sewer_arena.wmo", "doodadSets": ["Set_$DefaultGlobal"]},
"navigation": {"cellSize": 0.2, "cellHeight": 0.1, "agentHeight": 1.8, "agentRadius": 0.36, "agentMaxClimb": 0.5, "agentMaxSlope": 50},
"review": {"entrance": "required", "bossOrder": "not-applicable", "optionalEncounters": "not-applicable", "presentation": "required", "offMeshLinks": "required"},
"exceptions": []
}
+2
View File
@@ -8,6 +8,8 @@
"clientBuild": "3.3.5a-Ascension", "clientBuild": "3.3.5a-Ascension",
"mapDirectory": "World/Maps/DireMaul", "mapDirectory": "World/Maps/DireMaul",
"environmentMode": "global-wmo", "environmentMode": "global-wmo",
"coordinateAlignment": "source-transform",
"coordinateTransform": {"origin": [0, 0, 0], "yawDegrees": 180},
"difficultyVariants": [{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [50, 60]}], "difficultyVariants": [{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [50, 60]}],
"clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"}, "clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"},
"serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true}, "serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true},
@@ -27,6 +27,7 @@
} }
], ],
"environmentMode": "detect", "environmentMode": "detect",
"coordinateAlignment": "source",
"exceptions": [], "exceptions": [],
"expansion": "wrath", "expansion": "wrath",
"extraction": { "extraction": {
@@ -27,6 +27,7 @@
} }
], ],
"environmentMode": "detect", "environmentMode": "detect",
"coordinateAlignment": "source",
"exceptions": [], "exceptions": [],
"expansion": "burning-crusade", "expansion": "burning-crusade",
"extraction": { "extraction": {
@@ -27,6 +27,7 @@
} }
], ],
"environmentMode": "detect", "environmentMode": "detect",
"coordinateAlignment": "source",
"exceptions": [], "exceptions": [],
"expansion": "wrath", "expansion": "wrath",
"extraction": { "extraction": {
+1
View File
@@ -8,6 +8,7 @@
"clientBuild": "3.3.5a-Ascension", "clientBuild": "3.3.5a-Ascension",
"mapDirectory": "World/Maps/GnomeragonInstance", "mapDirectory": "World/Maps/GnomeragonInstance",
"environmentMode": "global-wmo", "environmentMode": "global-wmo",
"coordinateAlignment": "source",
"difficultyVariants": [{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [25, 40]}], "difficultyVariants": [{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [25, 40]}],
"clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"}, "clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"},
"serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true}, "serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true},
+1
View File
@@ -27,6 +27,7 @@
} }
], ],
"environmentMode": "detect", "environmentMode": "detect",
"coordinateAlignment": "source",
"exceptions": [], "exceptions": [],
"expansion": "wrath", "expansion": "wrath",
"extraction": { "extraction": {
@@ -27,6 +27,7 @@
} }
], ],
"environmentMode": "detect", "environmentMode": "detect",
"coordinateAlignment": "source",
"exceptions": [], "exceptions": [],
"expansion": "wrath", "expansion": "wrath",
"extraction": { "extraction": {
@@ -27,6 +27,7 @@
} }
], ],
"environmentMode": "detect", "environmentMode": "detect",
"coordinateAlignment": "source",
"exceptions": [], "exceptions": [],
"expansion": "wrath", "expansion": "wrath",
"extraction": { "extraction": {
@@ -27,6 +27,7 @@
} }
], ],
"environmentMode": "detect", "environmentMode": "detect",
"coordinateAlignment": "source",
"exceptions": [], "exceptions": [],
"expansion": "wrath", "expansion": "wrath",
"extraction": { "extraction": {
@@ -8,7 +8,12 @@
"clientBuild": "3.3.5a-Ascension", "clientBuild": "3.3.5a-Ascension",
"mapDirectory": "World/Maps/HellfireRampart", "mapDirectory": "World/Maps/HellfireRampart",
"environmentMode": "global-wmo", "environmentMode": "global-wmo",
"difficultyVariants": [{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [58, 70]}], "coordinateAlignment": "source-transform",
"coordinateTransform": {"origin": [1262.4427, -60.8902, 1622.5397], "yawDegrees": 262.143},
"difficultyVariants": [
{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [58, 70]},
{"id": "heroic", "difficulty": "heroic", "spawnMask": 2, "levelRange": [70, 70]}
],
"clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"}, "clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"},
"serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true}, "serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true},
"extraction": {"rootWmo": "World/wmo/Dungeon/Hellfire/Hellfire_ramparts.wmo", "doodadSets": ["Set_$DefaultGlobal"]}, "extraction": {"rootWmo": "World/wmo/Dungeon/Hellfire/Hellfire_ramparts.wmo", "doodadSets": ["Set_$DefaultGlobal"]},
@@ -8,7 +8,11 @@
"clientBuild": "3.3.5a-Ascension", "clientBuild": "3.3.5a-Ascension",
"mapDirectory": "World/Maps/Sunwell5ManFix", "mapDirectory": "World/Maps/Sunwell5ManFix",
"environmentMode": "global-wmo", "environmentMode": "global-wmo",
"difficultyVariants": [{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [70, 70]}], "coordinateAlignment": "source",
"difficultyVariants": [
{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [70, 70]},
{"id": "heroic", "difficulty": "heroic", "spawnMask": 2, "levelRange": [70, 70]}
],
"clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"}, "clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"},
"serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true}, "serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true},
"extraction": {"rootWmo": "World/wmo/Dungeon/QT_Sunwell_5Man/Sunwell_5Man.wmo", "doodadSets": ["Set_$DefaultGlobal"]}, "extraction": {"rootWmo": "World/wmo/Dungeon/QT_Sunwell_5Man/Sunwell_5Man.wmo", "doodadSets": ["Set_$DefaultGlobal"]},
+5 -1
View File
@@ -8,7 +8,11 @@
"clientBuild": "3.3.5a-Ascension", "clientBuild": "3.3.5a-Ascension",
"mapDirectory": "World/Maps/AuchindounEthereal", "mapDirectory": "World/Maps/AuchindounEthereal",
"environmentMode": "global-wmo", "environmentMode": "global-wmo",
"difficultyVariants": [{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [65, 70]}], "coordinateAlignment": "source",
"difficultyVariants": [
{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [65, 70]},
{"id": "heroic", "difficulty": "heroic", "spawnMask": 2, "levelRange": [70, 70]}
],
"clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"}, "clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"},
"serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true}, "serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true},
"extraction": {"rootWmo": "World/wmo/Dungeon/OL_Auchindoun/ethereal_wing.wmo", "doodadSets": ["Set_$DefaultGlobal"]}, "extraction": {"rootWmo": "World/wmo/Dungeon/OL_Auchindoun/ethereal_wing.wmo", "doodadSets": ["Set_$DefaultGlobal"]},
+1
View File
@@ -8,6 +8,7 @@
"clientBuild": "3.3.5a-Ascension", "clientBuild": "3.3.5a-Ascension",
"mapDirectory": "World/Maps/Mauradon", "mapDirectory": "World/Maps/Mauradon",
"environmentMode": "global-wmo", "environmentMode": "global-wmo",
"coordinateAlignment": "source",
"difficultyVariants": [{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [40, 55]}], "difficultyVariants": [{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [40, 55]}],
"clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"}, "clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"},
"serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true}, "serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true},
+5 -1
View File
@@ -8,7 +8,11 @@
"clientBuild": "3.3.5a-Ascension", "clientBuild": "3.3.5a-Ascension",
"mapDirectory": "World/Maps/TempestKeepFactory", "mapDirectory": "World/Maps/TempestKeepFactory",
"environmentMode": "global-wmo", "environmentMode": "global-wmo",
"difficultyVariants": [{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [65, 70]}], "coordinateAlignment": "source",
"difficultyVariants": [
{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [65, 70]},
{"id": "heroic", "difficulty": "heroic", "spawnMask": 2, "levelRange": [70, 70]}
],
"clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"}, "clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"},
"serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true}, "serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true},
"extraction": {"rootWmo": "World/wmo/Dungeon/OL_TempestKeep/TK_Factory.wmo", "doodadSets": ["Set_$DefaultGlobal"]}, "extraction": {"rootWmo": "World/wmo/Dungeon/OL_TempestKeep/TK_Factory.wmo", "doodadSets": ["Set_$DefaultGlobal"]},
@@ -0,0 +1,18 @@
{
"schemaVersion": 1,
"slug": "nagrand-arena",
"title": "Nagrand Arena",
"mapId": 559,
"lfgDungeonIds": [],
"expansion": "the-burning-crusade",
"clientBuild": "3.3.5a",
"mapDirectory": "World/Maps/PVPZone01",
"environmentMode": "global-wmo",
"difficultyVariants": [{"id": "rated", "difficulty": "normal", "spawnMask": 1, "levelRange": [80, 80]}],
"clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"},
"serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true},
"extraction": {"rootWmo": "World/wmo/Dungeon/OL_OgreHuts/PVP_Ogre_Arena01.wmo", "doodadSets": ["Set_$DefaultGlobal"]},
"navigation": {"cellSize": 0.2, "cellHeight": 0.1, "agentHeight": 1.8, "agentRadius": 0.36, "agentMaxClimb": 0.5, "agentMaxSlope": 50},
"review": {"entrance": "required", "bossOrder": "not-applicable", "optionalEncounters": "not-applicable", "presentation": "required", "offMeshLinks": "required"},
"exceptions": []
}
@@ -27,6 +27,7 @@
} }
], ],
"environmentMode": "detect", "environmentMode": "detect",
"coordinateAlignment": "source",
"exceptions": [], "exceptions": [],
"expansion": "wrath", "expansion": "wrath",
"extraction": { "extraction": {
@@ -8,6 +8,7 @@
"clientBuild": "3.3.5a-Ascension", "clientBuild": "3.3.5a-Ascension",
"mapDirectory": "World/Maps/OrgrimmarInstance", "mapDirectory": "World/Maps/OrgrimmarInstance",
"environmentMode": "global-wmo", "environmentMode": "global-wmo",
"globalWmoAlignment": "source",
"difficultyVariants": [{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [13, 25]}], "difficultyVariants": [{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [13, 25]}],
"clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"}, "clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"},
"serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true}, "serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true},
@@ -8,6 +8,8 @@
"clientBuild": "3.3.5a-Ascension", "clientBuild": "3.3.5a-Ascension",
"mapDirectory": "World/Maps/RazorfenDowns", "mapDirectory": "World/Maps/RazorfenDowns",
"environmentMode": "global-wmo", "environmentMode": "global-wmo",
"coordinateAlignment": "source-transform",
"coordinateTransform": {"origin": [-2402.2809, 62, 1208.3219], "yawDegrees": 0},
"difficultyVariants": [{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [35, 50]}], "difficultyVariants": [{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [35, 50]}],
"clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"}, "clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"},
"serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true}, "serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true},
+2 -1
View File
@@ -8,7 +8,8 @@
"clientBuild": "3.3.5a-Ascension", "clientBuild": "3.3.5a-Ascension",
"mapDirectory": "World/Maps/RazorfenKraulInstance", "mapDirectory": "World/Maps/RazorfenKraulInstance",
"environmentMode": "global-wmo", "environmentMode": "global-wmo",
"globalWmoSourceBasis": "flip-x", "coordinateAlignment": "source-transform",
"coordinateTransform": {"origin": [-1952.1803, 87.684, 1587.8923], "yawDegrees": -133},
"difficultyVariants": [{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [25, 40]}], "difficultyVariants": [{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [25, 40]}],
"clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"}, "clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"},
"serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true}, "serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true},
@@ -0,0 +1,18 @@
{
"schemaVersion": 1,
"slug": "ring-of-valor",
"title": "Ring of Valor",
"mapId": 618,
"lfgDungeonIds": [],
"expansion": "wrath-of-the-lich-king",
"clientBuild": "3.3.5a",
"mapDirectory": "World/Maps/OrgrimmarArena",
"environmentMode": "global-wmo",
"difficultyVariants": [{"id": "rated", "difficulty": "normal", "spawnMask": 1, "levelRange": [80, 80]}],
"clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"},
"serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true},
"extraction": {"rootWmo": "World/wmo/PvP/Buildings/Orgrimmar/OrgrimmarArena.wmo", "doodadSets": ["Set_$DefaultGlobal"]},
"navigation": {"cellSize": 0.2, "cellHeight": 0.1, "agentHeight": 1.8, "agentRadius": 0.36, "agentMaxClimb": 0.5, "agentMaxSlope": 50},
"review": {"entrance": "required", "bossOrder": "not-applicable", "optionalEncounters": "not-applicable", "presentation": "required", "offMeshLinks": "required"},
"exceptions": []
}
@@ -0,0 +1,18 @@
{
"schemaVersion": 1,
"slug": "ruins-of-lordaeron",
"title": "Ruins of Lordaeron",
"mapId": 572,
"lfgDungeonIds": [],
"expansion": "the-burning-crusade",
"clientBuild": "3.3.5a",
"mapDirectory": "World/Maps/PVPLordaeron",
"environmentMode": "global-wmo",
"difficultyVariants": [{"id": "rated", "difficulty": "normal", "spawnMask": 1, "levelRange": [80, 80]}],
"clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"},
"serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true},
"extraction": {"rootWmo": "World/wmo/PvP/Buildings/Lordaeron/PVP_Lordaeron_Arena.wmo", "doodadSets": ["Set_$DefaultGlobal"]},
"navigation": {"cellSize": 0.2, "cellHeight": 0.1, "agentHeight": 1.8, "agentRadius": 0.36, "agentMaxClimb": 0.5, "agentMaxSlope": 50},
"review": {"entrance": "required", "bossOrder": "not-applicable", "optionalEncounters": "not-applicable", "presentation": "required", "offMeshLinks": "required"},
"exceptions": []
}
@@ -8,6 +8,8 @@
"clientBuild": "3.3.5a", "clientBuild": "3.3.5a",
"mapDirectory": "World/Maps/MonasteryInstances", "mapDirectory": "World/Maps/MonasteryInstances",
"environmentMode": "detect", "environmentMode": "detect",
"coordinateAlignment": "source",
"adtSourceBasis": "z-y-negative-x",
"difficultyVariants": [ "difficultyVariants": [
{ "id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [26, 45] } { "id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [26, 45] }
], ],
@@ -8,6 +8,8 @@
"clientBuild": "3.3.5a-Ascension", "clientBuild": "3.3.5a-Ascension",
"mapDirectory": "World/Maps/SchoolofNecromancy", "mapDirectory": "World/Maps/SchoolofNecromancy",
"environmentMode": "global-wmo", "environmentMode": "global-wmo",
"coordinateAlignment": "source-transform",
"coordinateTransform": {"origin": [-141.694, 148.0683, 105.6784], "yawDegrees": 1},
"difficultyVariants": [{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [55, 60]}], "difficultyVariants": [{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [55, 60]}],
"clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"}, "clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"},
"serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true}, "serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true},
+5 -1
View File
@@ -8,7 +8,11 @@
"clientBuild": "3.3.5a-Ascension", "clientBuild": "3.3.5a-Ascension",
"mapDirectory": "World/Maps/AuchindounDemon", "mapDirectory": "World/Maps/AuchindounDemon",
"environmentMode": "global-wmo", "environmentMode": "global-wmo",
"difficultyVariants": [{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [65, 70]}], "coordinateAlignment": "source",
"difficultyVariants": [
{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [65, 70]},
{"id": "heroic", "difficulty": "heroic", "spawnMask": 2, "levelRange": [70, 70]}
],
"clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"}, "clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"},
"serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true}, "serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true},
"extraction": {"rootWmo": "World/wmo/Dungeon/OL_Auchindoun/demon_wing.wmo", "doodadSets": ["Set_$DefaultGlobal"]}, "extraction": {"rootWmo": "World/wmo/Dungeon/OL_Auchindoun/demon_wing.wmo", "doodadSets": ["Set_$DefaultGlobal"]},
@@ -8,7 +8,11 @@
"clientBuild": "3.3.5a-Ascension", "clientBuild": "3.3.5a-Ascension",
"mapDirectory": "World/Maps/AuchindounShadow", "mapDirectory": "World/Maps/AuchindounShadow",
"environmentMode": "global-wmo", "environmentMode": "global-wmo",
"difficultyVariants": [{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [65, 70]}], "coordinateAlignment": "source",
"difficultyVariants": [
{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [65, 70]},
{"id": "heroic", "difficulty": "heroic", "spawnMask": 2, "levelRange": [70, 70]}
],
"clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"}, "clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"},
"serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true}, "serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true},
"extraction": {"rootWmo": "World/wmo/Dungeon/OL_Auchindoun/shadow_council_wing.wmo", "doodadSets": ["Set_$DefaultGlobal"]}, "extraction": {"rootWmo": "World/wmo/Dungeon/OL_Auchindoun/shadow_council_wing.wmo", "doodadSets": ["Set_$DefaultGlobal"]},
@@ -7,12 +7,14 @@
"expansion": "classic", "expansion": "classic",
"clientBuild": "3.3.5a-Ascension", "clientBuild": "3.3.5a-Ascension",
"mapDirectory": "World/Maps/Shadowfang", "mapDirectory": "World/Maps/Shadowfang",
"environmentMode": "global-wmo", "environmentMode": "detect",
"coordinateAlignment": "source",
"adtSourceBasis": "z-y-negative-x",
"difficultyVariants": [{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [18, 30]}], "difficultyVariants": [{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [18, 30]}],
"clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"}, "clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"},
"serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true}, "serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true},
"extraction": {"rootWmo": "World/wmo/Dungeon/LD_ShadowFang/LD_ShadowFang.wmo", "doodadSets": ["Set_$DefaultGlobal"]}, "extraction": {"adtTiles": "all-present"},
"navigation": {"cellSize": 0.2, "cellHeight": 0.1, "agentHeight": 1.8, "agentRadius": 0.36, "agentMaxClimb": 0.5, "agentMaxSlope": 50}, "navigation": {"cellSize": 0.2, "cellHeight": 0.1, "tileSize": 256, "retainTileIntermediates": false, "agentHeight": 1.8, "agentRadius": 0.36, "agentMaxClimb": 0.5, "agentMaxSlope": 50},
"review": {"entrance": "required", "bossOrder": "required", "optionalEncounters": "required", "presentation": "required", "offMeshLinks": "required"}, "review": {"entrance": "required", "bossOrder": "required", "optionalEncounters": "required", "presentation": "required", "offMeshLinks": "required"},
"exceptions": [] "exceptions": []
} }
@@ -8,7 +8,11 @@
"clientBuild": "3.3.5a-Ascension", "clientBuild": "3.3.5a-Ascension",
"mapDirectory": "World/Maps/HellfireMilitary", "mapDirectory": "World/Maps/HellfireMilitary",
"environmentMode": "global-wmo", "environmentMode": "global-wmo",
"difficultyVariants": [{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [60, 70]}], "coordinateAlignment": "source",
"difficultyVariants": [
{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [60, 70]},
{"id": "heroic", "difficulty": "heroic", "spawnMask": 2, "levelRange": [70, 70]}
],
"clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"}, "clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"},
"serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true}, "serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true},
"extraction": {"rootWmo": "World/wmo/Dungeon/Hellfire/Hellfire_Military.wmo", "doodadSets": ["Set_$DefaultGlobal"]}, "extraction": {"rootWmo": "World/wmo/Dungeon/Hellfire/Hellfire_Military.wmo", "doodadSets": ["Set_$DefaultGlobal"]},
+5 -1
View File
@@ -8,7 +8,11 @@
"clientBuild": "3.3.5a-Ascension", "clientBuild": "3.3.5a-Ascension",
"mapDirectory": "World/Maps/CoilfangDraenei", "mapDirectory": "World/Maps/CoilfangDraenei",
"environmentMode": "global-wmo", "environmentMode": "global-wmo",
"difficultyVariants": [{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [60, 70]}], "coordinateAlignment": "source",
"difficultyVariants": [
{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [60, 70]},
{"id": "heroic", "difficulty": "heroic", "spawnMask": 2, "levelRange": [70, 70]}
],
"clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"}, "clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"},
"serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true}, "serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true},
"extraction": {"rootWmo": "World/wmo/Dungeon/OL_Coilfang/Coilfang_Draenei.wmo", "doodadSets": ["Set_$DefaultGlobal"]}, "extraction": {"rootWmo": "World/wmo/Dungeon/OL_Coilfang/Coilfang_Draenei.wmo", "doodadSets": ["Set_$DefaultGlobal"]},
+5 -1
View File
@@ -8,7 +8,11 @@
"clientBuild": "3.3.5a-Ascension", "clientBuild": "3.3.5a-Ascension",
"mapDirectory": "World/Maps/CoilfangPumping", "mapDirectory": "World/Maps/CoilfangPumping",
"environmentMode": "global-wmo", "environmentMode": "global-wmo",
"difficultyVariants": [{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [60, 70]}], "coordinateAlignment": "source",
"difficultyVariants": [
{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [60, 70]},
{"id": "heroic", "difficulty": "heroic", "spawnMask": 2, "levelRange": [70, 70]}
],
"clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"}, "clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"},
"serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true}, "serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true},
"extraction": {"rootWmo": "World/wmo/Dungeon/OL_Coilfang/Coilfang_Pumping.wmo", "doodadSets": ["Set_$DefaultGlobal"]}, "extraction": {"rootWmo": "World/wmo/Dungeon/OL_Coilfang/Coilfang_Pumping.wmo", "doodadSets": ["Set_$DefaultGlobal"]},
@@ -8,6 +8,7 @@
"clientBuild": "3.3.5a-Ascension", "clientBuild": "3.3.5a-Ascension",
"mapDirectory": "World/Maps/StormwindJail", "mapDirectory": "World/Maps/StormwindJail",
"environmentMode": "global-wmo", "environmentMode": "global-wmo",
"globalWmoAlignment": "source",
"difficultyVariants": [ "difficultyVariants": [
{ {
"id": "normal", "id": "normal",
+2
View File
@@ -8,6 +8,8 @@
"clientBuild": "3.3.5a-Ascension", "clientBuild": "3.3.5a-Ascension",
"mapDirectory": "World/Maps/Stratholme", "mapDirectory": "World/Maps/Stratholme",
"environmentMode": "global-wmo", "environmentMode": "global-wmo",
"coordinateAlignment": "source-transform",
"coordinateTransform": {"origin": [-3449.6608, 144.3848, -3379.6966], "yawDegrees": 0},
"difficultyVariants": [{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [55, 60]}], "difficultyVariants": [{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [55, 60]}],
"clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"}, "clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"},
"serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true}, "serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true},
@@ -8,6 +8,7 @@
"clientBuild": "3.3.5a-Ascension", "clientBuild": "3.3.5a-Ascension",
"mapDirectory": "World/Maps/SunkenTemple", "mapDirectory": "World/Maps/SunkenTemple",
"environmentMode": "global-wmo", "environmentMode": "global-wmo",
"coordinateAlignment": "source",
"difficultyVariants": [{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [45, 55]}], "difficultyVariants": [{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [45, 55]}],
"clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"}, "clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"},
"serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true}, "serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true},
+1
View File
@@ -27,6 +27,7 @@
} }
], ],
"environmentMode": "detect", "environmentMode": "detect",
"coordinateAlignment": "source",
"exceptions": [], "exceptions": [],
"expansion": "wrath", "expansion": "wrath",
"extraction": { "extraction": {
+1
View File
@@ -27,6 +27,7 @@
} }
], ],
"environmentMode": "detect", "environmentMode": "detect",
"coordinateAlignment": "source",
"exceptions": [], "exceptions": [],
"expansion": "wrath", "expansion": "wrath",
"extraction": { "extraction": {
@@ -27,6 +27,7 @@
} }
], ],
"environmentMode": "detect", "environmentMode": "detect",
"coordinateAlignment": "source",
"exceptions": [], "exceptions": [],
"expansion": "wrath", "expansion": "wrath",
"extraction": { "extraction": {
+1
View File
@@ -8,6 +8,7 @@
"clientBuild": "3.3.5a-Ascension", "clientBuild": "3.3.5a-Ascension",
"mapDirectory": "World/Maps/Uldaman", "mapDirectory": "World/Maps/Uldaman",
"environmentMode": "global-wmo", "environmentMode": "global-wmo",
"coordinateAlignment": "source",
"difficultyVariants": [ "difficultyVariants": [
{ {
"id": "normal", "id": "normal",
+5 -1
View File
@@ -8,7 +8,11 @@
"clientBuild": "3.3.5a-Ascension", "clientBuild": "3.3.5a-Ascension",
"mapDirectory": "World/Maps/CoilfangMarsh", "mapDirectory": "World/Maps/CoilfangMarsh",
"environmentMode": "global-wmo", "environmentMode": "global-wmo",
"difficultyVariants": [{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [60, 70]}], "coordinateAlignment": "source",
"difficultyVariants": [
{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [60, 70]},
{"id": "heroic", "difficulty": "heroic", "spawnMask": 2, "levelRange": [70, 70]}
],
"clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"}, "clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"},
"serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true}, "serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true},
"extraction": {"rootWmo": "World/wmo/Dungeon/OL_Coilfang/Coilfang_Marsh.wmo", "doodadSets": ["Set_$DefaultGlobal"]}, "extraction": {"rootWmo": "World/wmo/Dungeon/OL_Coilfang/Coilfang_Marsh.wmo", "doodadSets": ["Set_$DefaultGlobal"]},
@@ -27,6 +27,7 @@
} }
], ],
"environmentMode": "detect", "environmentMode": "detect",
"coordinateAlignment": "source",
"exceptions": [], "exceptions": [],
"expansion": "wrath", "expansion": "wrath",
"extraction": { "extraction": {
@@ -27,6 +27,7 @@
} }
], ],
"environmentMode": "detect", "environmentMode": "detect",
"coordinateAlignment": "source",
"exceptions": [], "exceptions": [],
"expansion": "wrath", "expansion": "wrath",
"extraction": { "extraction": {
@@ -27,6 +27,7 @@
} }
], ],
"environmentMode": "detect", "environmentMode": "detect",
"coordinateAlignment": "source",
"exceptions": [], "exceptions": [],
"expansion": "wrath", "expansion": "wrath",
"extraction": { "extraction": {
+2
View File
@@ -8,6 +8,8 @@
"clientBuild": "3.3.5a-Ascension", "clientBuild": "3.3.5a-Ascension",
"mapDirectory": "World/Maps/TanarisInstance", "mapDirectory": "World/Maps/TanarisInstance",
"environmentMode": "detect", "environmentMode": "detect",
"coordinateAlignment": "source",
"adtSourceBasis": "z-y-negative-x",
"difficultyVariants": [ "difficultyVariants": [
{ "id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [40, 54] } { "id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [40, 54] }
], ],
+3 -2
View File
@@ -1,12 +1,12 @@
{ {
"name": "healer-man", "name": "healer-man",
"version": "0.1.3", "version": "0.1.22",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "healer-man", "name": "healer-man",
"version": "0.1.3", "version": "0.1.22",
"dependencies": { "dependencies": {
"@capacitor/android": "8.4.1", "@capacitor/android": "8.4.1",
"@capacitor/core": "8.4.1", "@capacitor/core": "8.4.1",
@@ -21,6 +21,7 @@
}, },
"devDependencies": { "devDependencies": {
"@capacitor/cli": "8.4.1", "@capacitor/cli": "8.4.1",
"@dimforge/rapier3d-compat": "0.19.2",
"@gltf-transform/cli": "^4.4.1", "@gltf-transform/cli": "^4.4.1",
"@gltf-transform/core": "^4.4.2", "@gltf-transform/core": "^4.4.2",
"@recast-navigation/core": "0.43.1", "@recast-navigation/core": "0.43.1",
+28 -7
View File
@@ -1,7 +1,7 @@
{ {
"name": "healer-man", "name": "healer-man",
"private": true, "private": true,
"version": "0.1.3", "version": "0.1.22",
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite --host 0.0.0.0", "dev": "vite --host 0.0.0.0",
@@ -10,14 +10,20 @@
"db:backup": "node scripts/backup-game-database.mjs", "db:backup": "node scripts/backup-game-database.mjs",
"server:test": "node --test server/*.test.mjs", "server:test": "node --test server/*.test.mjs",
"content:publish": "node scripts/content/publish-content.mjs", "content:publish": "node scripts/content/publish-content.mjs",
"web:prepare": "node scripts/content/prepare-web-bootstrap.mjs",
"android:prepare": "node scripts/content/prepare-android-bootstrap.mjs", "android:prepare": "node scripts/content/prepare-android-bootstrap.mjs",
"content:test": "node --test scripts/content/*.test.mjs", "content:test": "node --test scripts/content/*.test.mjs",
"effects:generate": "node scripts/combat-effects/generate-manifest.mjs --package-audio && node scripts/combat-effects/package-priest-original.mjs",
"effects:audit": "node scripts/combat-effects/generate-manifest.mjs --package-audio --audit && node scripts/combat-effects/package-priest-original.mjs --audit",
"effects:priest": "node scripts/combat-effects/package-priest-original.mjs",
"effects:test": "node --test scripts/combat-effects/*.test.mjs",
"wow335:abilities": "node scripts/generate-wow335-abilities.mjs", "wow335:abilities": "node scripts/generate-wow335-abilities.mjs",
"coa:sync": "node scripts/sync-ascension-coa.mjs", "coa:sync": "node scripts/sync-ascension-coa.mjs",
"coa:sync:live": "node scripts/sync-ascension-coa.mjs --tooltips", "coa:sync:live": "node scripts/sync-ascension-coa.mjs --tooltips",
"coa:icons": "node scripts/export-spell-icons.mjs", "coa:icons": "node scripts/export-spell-icons.mjs",
"ascension:talents": "node scripts/generate-wow335-talents.mjs ../wow335a/Interface/AddOns/PlayerBotManager/PBM/PBM_TalentData.lua ../LadiksMPQEditor/client-current/area-52/patch-D/DBFilesClient/Spell.dbc src/game/wow335Talents.generated.ts ../LadiksMPQEditor/client-current/area-52/patch-D/DBFilesClient/Talent.dbc", "ascension:talents": "node scripts/generate-wow335-talents.mjs ../wow335a/Interface/AddOns/PlayerBotManager/PBM/PBM_TalentData.lua ../LadiksMPQEditor/client-current/area-52/patch-D/DBFilesClient/Spell.dbc src/game/wow335Talents.generated.ts ../LadiksMPQEditor/client-current/area-52/patch-D/DBFilesClient/Talent.dbc",
"ascension:sync": "npm run coa:sync && npm run wow335:abilities && npm run ascension:talents && npm run coa:icons", "catalogs:shard": "vite-node scripts/generate-catalog-shards.ts",
"ascension:sync": "npm run coa:sync && npm run wow335:abilities && npm run ascension:talents && npm run coa:icons && npm run catalogs:shard",
"manastorm:import": "node scripts/manastorm-import/cli.mjs", "manastorm:import": "node scripts/manastorm-import/cli.mjs",
"manastorm:forensics": "node scripts/manastorm-import/forensics-cli.mjs", "manastorm:forensics": "node scripts/manastorm-import/forensics-cli.mjs",
"manastorm:sync": "npm run manastorm:import && npm run manastorm:forensics && npm run coa:icons", "manastorm:sync": "npm run manastorm:import && npm run manastorm:forensics && npm run coa:icons",
@@ -46,8 +52,11 @@
"dungeon:five-player:import": "node scripts/dungeon-pipeline/import-five-player-dungeon.mjs", "dungeon:five-player:import": "node scripts/dungeon-pipeline/import-five-player-dungeon.mjs",
"dungeon:five-player:import:remaining": "node scripts/dungeon-pipeline/import-remaining-five-player-dungeons.mjs", "dungeon:five-player:import:remaining": "node scripts/dungeon-pipeline/import-remaining-five-player-dungeons.mjs",
"dungeon:five-player:verify": "node scripts/dungeon-pipeline/verify-five-player-dungeon-imports.mjs", "dungeon:five-player:verify": "node scripts/dungeon-pipeline/verify-five-player-dungeon-imports.mjs",
"dungeon:wow:audit": "node scripts/dungeon-pipeline/audit-wow-dungeon-content.mjs", "dungeon:wow:audit": "vite-node scripts/dungeon-pipeline/audit-wow-dungeon-content.mjs",
"dungeon:wow:functionality:audit": "vite-node scripts/dungeon-pipeline/audit-wow-dungeon-functionality.ts",
"dungeon:wow:test": "vitest run src/game/wowDungeonContent.test.ts", "dungeon:wow:test": "vitest run src/game/wowDungeonContent.test.ts",
"dungeon:wow:export-tool:test": "node --test scripts/dungeon-pipeline/wow-export-tool.test.mjs",
"dungeon:ascension:recovery:validate": "node scripts/dungeon-pipeline/validate-ascension-custom-dungeon-recovery.mjs --skip-dbc",
"dungeon:wow:all": "node scripts/dungeon-pipeline/run-all-wow-dungeons.mjs", "dungeon:wow:all": "node scripts/dungeon-pipeline/run-all-wow-dungeons.mjs",
"dungeon:extract": "node scripts/dungeon-pipeline/cli.mjs extract", "dungeon:extract": "node scripts/dungeon-pipeline/cli.mjs extract",
"dungeon:creatures": "node scripts/dungeon-pipeline/cli.mjs creatures", "dungeon:creatures": "node scripts/dungeon-pipeline/cli.mjs creatures",
@@ -57,6 +66,8 @@
"dungeon:navmesh": "node scripts/dungeon-pipeline/cli.mjs navmesh", "dungeon:navmesh": "node scripts/dungeon-pipeline/cli.mjs navmesh",
"dungeon:navmesh:conversion": "node scripts/dungeon-pipeline/cli.mjs navmesh-conversion", "dungeon:navmesh:conversion": "node scripts/dungeon-pipeline/cli.mjs navmesh-conversion",
"dungeon:validate": "node scripts/dungeon-pipeline/cli.mjs validate", "dungeon:validate": "node scripts/dungeon-pipeline/cli.mjs validate",
"arena:assets:build": "node scripts/arena-pipeline/build-wmo-arenas.mjs && node scripts/arena-pipeline/build-custom-arenas.mjs && node scripts/arena-pipeline/prepare-warnorken.mjs",
"arena:assets:validate": "node scripts/arena-pipeline/validate-arenas.mjs",
"dungeon:enable": "node scripts/dungeon-pipeline/cli.mjs enable", "dungeon:enable": "node scripts/dungeon-pipeline/cli.mjs enable",
"runewaker:forsaken": "node \"%INIT_CWD%\\scripts\\runewaker-pipeline\\build-forsaken-abbey.mjs\"", "runewaker:forsaken": "node \"%INIT_CWD%\\scripts\\runewaker-pipeline\\build-forsaken-abbey.mjs\"",
"runewaker:forsaken:actors": "node scripts/runewaker-pipeline/build-forsaken-population.mjs --actors-only", "runewaker:forsaken:actors": "node scripts/runewaker-pipeline/build-forsaken-population.mjs --actors-only",
@@ -68,6 +79,9 @@
"runewaker:register:all": "node scripts/runewaker-pipeline/cli.mjs register-all", "runewaker:register:all": "node scripts/runewaker-pipeline/cli.mjs register-all",
"runewaker:refresh:all": "node scripts/runewaker-pipeline/cli.mjs refresh-all", "runewaker:refresh:all": "node scripts/runewaker-pipeline/cli.mjs refresh-all",
"runewaker:spells:refresh": "node scripts/runewaker-pipeline/export-spell-catalog.mjs", "runewaker:spells:refresh": "node scripts/runewaker-pipeline/export-spell-catalog.mjs",
"runewaker:loot:refresh": "node scripts/runewaker-pipeline/export-loot-catalog.mjs",
"runewaker:audit:formula-loot": "node --test scripts/runewaker-pipeline/runewaker-formula-export.test.mjs scripts/runewaker-pipeline/runewaker-loot-import.test.mjs && vitest run src/game/runewakerCombatFormula.test.ts src/game/runewakerLootCatalog.test.ts",
"runewaker:bosses:refresh": "npm run runewaker:spells:refresh && node scripts/runewaker-pipeline/import-boss-mechanics.mjs",
"runewaker:players:refresh": "node scripts/runewaker-pipeline/export-player-catalog.mjs && npm run runewaker:players:avatars", "runewaker:players:refresh": "node scripts/runewaker-pipeline/export-player-catalog.mjs && npm run runewaker:players:avatars",
"runewaker:players:avatars": "node scripts/runewaker-pipeline/build-population.mjs --recipe scripts/runewaker-pipeline/recipes/runewaker-player-avatars.json --actors-only && node scripts/runewaker-pipeline/finalize-player-avatar-manifest.mjs", "runewaker:players:avatars": "node scripts/runewaker-pipeline/build-population.mjs --recipe scripts/runewaker-pipeline/recipes/runewaker-player-avatars.json --actors-only && node scripts/runewaker-pipeline/finalize-player-avatar-manifest.mjs",
"runewaker:paperdolls:refresh": "node scripts/runewaker-pipeline/refresh-paperdoll-appearances.mjs", "runewaker:paperdolls:refresh": "node scripts/runewaker-pipeline/refresh-paperdoll-appearances.mjs",
@@ -77,7 +91,9 @@
"runewaker:audit:pose-batch": "node scripts/runewaker-pipeline/audit-animated-poses.mjs", "runewaker:audit:pose-batch": "node scripts/runewaker-pipeline/audit-animated-poses.mjs",
"runewaker:audit:pose-master": "node scripts/runewaker-pipeline/generate-master-actor-pose-audit.mjs", "runewaker:audit:pose-master": "node scripts/runewaker-pipeline/generate-master-actor-pose-audit.mjs",
"runewaker:audit:animations": "npm run runewaker:audit:animation-readiness && vitest run src/game/runewakerDungeonAnimation.test.ts src/game/mobAnimation.test.ts src/game/runewakerDungeonRegistry.test.ts", "runewaker:audit:animations": "npm run runewaker:audit:animation-readiness && vitest run src/game/runewakerDungeonAnimation.test.ts src/game/mobAnimation.test.ts src/game/runewakerDungeonRegistry.test.ts",
"runewaker:audit:gameplay": "node scripts/runewaker-pipeline/audit-gameplay-content.mjs", "runewaker:audit:gameplay": "node scripts/runewaker-pipeline/audit-gameplay-content.mjs && node --test scripts/runewaker-pipeline/encounter-implementation-report.test.mjs",
"runewaker:audit:encounters": "node scripts/runewaker-pipeline/audit-encounter-implementation.mjs && node --test scripts/runewaker-pipeline/encounter-implementation-report.test.mjs",
"runewaker:audit:environment-assembly": "node scripts/runewaker-pipeline/audit-environment-assembly.mjs && node --test scripts/runewaker-pipeline/environment-assembly.test.mjs",
"runewaker:audit:navigation": "node scripts/runewaker-pipeline/analyze-navigation-gaps.mjs && vitest run src/game/runewakerObjectiveRouteAudit.test.ts", "runewaker:audit:navigation": "node scripts/runewaker-pipeline/analyze-navigation-gaps.mjs && vitest run src/game/runewakerObjectiveRouteAudit.test.ts",
"assets:wailing:instance": "gltf-transform instance ../wow335a/dungeon-export-work/WailingCaverns/converted/wailing-caverns.visual.glb src/assets/game/dungeons/wailing-caverns/wailing-caverns-visual.glb --min 3", "assets:wailing:instance": "gltf-transform instance ../wow335a/dungeon-export-work/WailingCaverns/converted/wailing-caverns.visual.glb src/assets/game/dungeons/wailing-caverns/wailing-caverns-visual.glb --min 3",
"assets:wailing:creatures:animated": "node scripts/prepareAnimatedCreatures.mjs", "assets:wailing:creatures:animated": "node scripts/prepareAnimatedCreatures.mjs",
@@ -88,13 +104,17 @@
"assets:ktx2:creatures": "node scripts/asset-pipeline/compress-creature-ktx2.mjs", "assets:ktx2:creatures": "node scripts/asset-pipeline/compress-creature-ktx2.mjs",
"assets:ktx2:audit": "node scripts/asset-pipeline/audit-ktx2.mjs --visual-only --require-all", "assets:ktx2:audit": "node scripts/asset-pipeline/audit-ktx2.mjs --visual-only --require-all",
"assets:ktx2:refresh-metadata": "node scripts/asset-pipeline/refresh-ktx2-metadata.mjs", "assets:ktx2:refresh-metadata": "node scripts/asset-pipeline/refresh-ktx2-metadata.mjs",
"prebuild": "npm run loot:generate && npm run assets:ktx2:audit", "assets:performance:audit": "node scripts/asset-pipeline/audit-environment-performance.mjs",
"build": "tsc -b && vite build", "balance:benchmark": "vite-node scripts/combat-benchmark/run.ts",
"build:android:web": "npm run prebuild && npm run android:prepare && tsc -b && node --max-old-space-size=8192 node_modules/vite/bin/vite.js build --mode android", "balance:smoke": "vite-node scripts/combat-benchmark/run.ts --class mage --role damage --scenario damage-single-burst --seeds 1 --duration-scale 0.2",
"prebuild": "npm run loot:generate && npm run web:prepare && npm run arena:assets:validate && npm run assets:ktx2:audit && npm run assets:performance:audit",
"build": "node --max-old-space-size=8192 node_modules/typescript/bin/tsc -b && node --max-old-space-size=8192 node_modules/vite/bin/vite.js build",
"build:android:web": "npm run prebuild && npm run android:prepare && node --max-old-space-size=8192 node_modules/typescript/bin/tsc -b && node --max-old-space-size=8192 node_modules/vite/bin/vite.js build --mode android",
"android:sync": "npm run build:android:web && cap sync android", "android:sync": "npm run build:android:web && cap sync android",
"android:apk": "npm run android:sync && powershell.exe -NoProfile -ExecutionPolicy Bypass -File scripts/runAndroidGradle.ps1 assembleDebug", "android:apk": "npm run android:sync && powershell.exe -NoProfile -ExecutionPolicy Bypass -File scripts/runAndroidGradle.ps1 assembleDebug",
"android:apk:release": "npm run android:sync && powershell.exe -NoProfile -ExecutionPolicy Bypass -File scripts/runAndroidGradle.ps1 assembleRelease", "android:apk:release": "npm run android:sync && powershell.exe -NoProfile -ExecutionPolicy Bypass -File scripts/runAndroidGradle.ps1 assembleRelease",
"android:install": "npm run android:sync && powershell.exe -NoProfile -ExecutionPolicy Bypass -File scripts/runAndroidGradle.ps1 installDebug", "android:install": "npm run android:sync && powershell.exe -NoProfile -ExecutionPolicy Bypass -File scripts/runAndroidGradle.ps1 installDebug",
"release:check": "python scripts/release_manager.py --check-release",
"release:gui": "python scripts/release_manager.py", "release:gui": "python scripts/release_manager.py",
"preview": "vite preview --host 0.0.0.0", "preview": "vite preview --host 0.0.0.0",
"pretest": "npm run loot:generate", "pretest": "npm run loot:generate",
@@ -115,6 +135,7 @@
}, },
"devDependencies": { "devDependencies": {
"@capacitor/cli": "8.4.1", "@capacitor/cli": "8.4.1",
"@dimforge/rapier3d-compat": "0.19.2",
"@gltf-transform/cli": "^4.4.1", "@gltf-transform/cli": "^4.4.1",
"@gltf-transform/core": "^4.4.2", "@gltf-transform/core": "^4.4.2",
"@recast-navigation/core": "0.43.1", "@recast-navigation/core": "0.43.1",
@@ -0,0 +1,127 @@
{
"build": {
"attempts": [
{
"failures": [],
"tileCount": 1,
"tileSize": null,
"valid": true
}
],
"gridCells": 258876,
"gridHeight": 564,
"gridWidth": 459,
"ignoredEmptyTilePackingFailures": 0,
"intermediateRetention": null,
"mode": "solo",
"partition": "watershed",
"populatedTileCount": 1,
"tileColumns": 1,
"tileCount": 1,
"tileRows": 1,
"tileSize": null
},
"dungeonId": "ashamanes-fall",
"generator": "@recast-navigation/three@0.43.1",
"geometry": {
"bounds": [
[
16.435361862182617,
-2.676706314086914,
4.506431579589844
],
[
65.03536224365234,
26.523292541503906,
43.1064338684082
]
],
"boundsTolerance": 0.4,
"rejectedOutOfBoundsTriangles": 0,
"sourceTriangles": 353,
"sourceVertices": 1059,
"triangles": 353,
"vertices": 1059
},
"input": {
"bounds": [
[
-6.364639759063721,
-19.976707458496094,
-59.093570709228516
],
[
85.27696990966797,
36.782005310058594,
53.62468338012695
]
],
"degenerateTriangleCount": 0,
"invalidIndexCount": 0,
"meshCount": 1,
"nonFiniteCoordinateCount": 0,
"triangleCount": 2783,
"vertexCount": 8349
},
"inputChunkChecksums": {
"public/assets/game/arenas/ashamanes-fall/navigation-collision.glb": "cdc39b903da6a6f9f21bd9e5e0b2ca61e76b09e13575b02349ca92d68815e5a8"
},
"inputChunks": [
"public/assets/game/arenas/ashamanes-fall/navigation-collision.glb"
],
"output": "public/assets/game/arenas/ashamanes-fall/navigation-raw.glb",
"schemaVersion": 1,
"settings": {
"agentHeight": 1.8,
"agentMaxClimb": 0.5,
"agentMaxSlope": 50,
"agentRadius": 0.36,
"cellHeight": 0.1,
"cellSize": 0.2
},
"source": {
"adtFiles": [
"valsharaharena_20_24.adt",
"valsharaharena_20_25.adt",
"valsharaharena_20_26.adt",
"valsharaharena_21_24.adt",
"valsharaharena_21_25.adt",
"valsharaharena_21_26.adt",
"valsharaharena_22_24.adt",
"valsharaharena_22_25.adt",
"valsharaharena_22_26.adt"
],
"gameplayBounds": {
"max": [
58,
16,
36
],
"min": [
14,
-4,
2
]
},
"kind": "adt-placed-wmo-repair",
"legacyCollision": "public/assets/game/manastorm/1785-valsharaharena/collision.glb",
"placedWmos": [
"../LadiksMPQEditor/patch-WC1/WORLD/WMO/BROKENISLES/NIGHTELF/7NE_NIGHTELF_RETAINERCURVED02.WMO",
"../LadiksMPQEditor/patch-WC1/WORLD/WMO/BROKENISLES/NIGHTELF/7NE_NIGHTELF_RETAINERCURVED02.WMO",
"../LadiksMPQEditor/patch-WC1/WORLD/WMO/BROKENISLES/NIGHTELF/7NE_NIGHTELF_RETAINERCURVED02.WMO",
"../LadiksMPQEditor/patch-WC1/WORLD/WMO/BROKENISLES/NIGHTELF/7NE_NIGHTELF_RETAINERCURVED02.WMO",
"../LadiksMPQEditor/patch-WC1/WORLD/WMO/BROKENISLES/NIGHTELF/7NE_NIGHTELF_RETAINERCURVED02.WMO",
"../LadiksMPQEditor/patch-WC1/WORLD/WMO/BROKENISLES/NIGHTELF/7NE_NIGHTELF_RETAINERCURVED02.WMO",
"../LadiksMPQEditor/patch-WC1/WORLD/WMO/BROKENISLES/NIGHTELF/7NE_NIGHTELF_RETAINERCURVED02.WMO",
"../LadiksMPQEditor/patch-WC1/WORLD/WMO/BROKENISLES/VALSHARAH/7VS_CAVEMICRO01.WMO",
"../LadiksMPQEditor/patch-WC1/WORLD/WMO/BROKENISLES/NIGHTELF/7NE_NIGHTELF_RUINPIECE06.WMO",
"../LadiksMPQEditor/patch-WC1/WORLD/WMO/BROKENISLES/NIGHTELF/7NE_DRUID_BRIDGE01.WMO",
"../LadiksMPQEditor/patch-WC1/WORLD/WMO/BROKENISLES/NIGHTELF/7NE_DRUID_BRIDGE01.WMO",
"../LadiksMPQEditor/patch-WC1/WORLD/WMO/BROKENISLES/NIGHTELF/7NE_DRUID_TOWER01_NIGHTMARE.WMO",
"../LadiksMPQEditor/patch-WC1/WORLD/WMO/BROKENISLES/NIGHTELF/7NE_DRUID_BRIDGE01_NIGHTMARE.WMO",
"../LadiksMPQEditor/patch-WC1/WORLD/WMO/BROKENISLES/NIGHTELF/7NE_NIGHTELF_RUINPIECE06.WMO",
"../LadiksMPQEditor/patch-WC1/WORLD/WMO/BROKENISLES/NIGHTELF/7NE_NIGHTELF_BRIDGESHORT.WMO",
"../LadiksMPQEditor/patch-WC1/WORLD/WMO/DUNGEON/PVP/CUSTOM_VALSHARAH_ARENA.WMO"
]
}
}
@@ -0,0 +1,99 @@
{
"schemaVersion": 1,
"id": "ashamanes-fall",
"title": "Ashamane's Fall",
"status": "generated-review-required",
"source": {
"mapDirectory": "patch-WB2/world/maps/valsharaharena",
"adtFiles": [
"valsharaharena_20_24.adt",
"valsharaharena_20_25.adt",
"valsharaharena_20_26.adt",
"valsharaharena_21_24.adt",
"valsharaharena_21_25.adt",
"valsharaharena_21_26.adt",
"valsharaharena_22_24.adt",
"valsharaharena_22_25.adt",
"valsharaharena_22_26.adt"
],
"placementCount": 16,
"placedWmos": [
"../LadiksMPQEditor/patch-WC1/WORLD/WMO/BROKENISLES/NIGHTELF/7NE_NIGHTELF_RETAINERCURVED02.WMO",
"../LadiksMPQEditor/patch-WC1/WORLD/WMO/BROKENISLES/NIGHTELF/7NE_NIGHTELF_RETAINERCURVED02.WMO",
"../LadiksMPQEditor/patch-WC1/WORLD/WMO/BROKENISLES/NIGHTELF/7NE_NIGHTELF_RETAINERCURVED02.WMO",
"../LadiksMPQEditor/patch-WC1/WORLD/WMO/BROKENISLES/NIGHTELF/7NE_NIGHTELF_RETAINERCURVED02.WMO",
"../LadiksMPQEditor/patch-WC1/WORLD/WMO/BROKENISLES/NIGHTELF/7NE_NIGHTELF_RETAINERCURVED02.WMO",
"../LadiksMPQEditor/patch-WC1/WORLD/WMO/BROKENISLES/NIGHTELF/7NE_NIGHTELF_RETAINERCURVED02.WMO",
"../LadiksMPQEditor/patch-WC1/WORLD/WMO/BROKENISLES/NIGHTELF/7NE_NIGHTELF_RETAINERCURVED02.WMO",
"../LadiksMPQEditor/patch-WC1/WORLD/WMO/BROKENISLES/VALSHARAH/7VS_CAVEMICRO01.WMO",
"../LadiksMPQEditor/patch-WC1/WORLD/WMO/BROKENISLES/NIGHTELF/7NE_NIGHTELF_RUINPIECE06.WMO",
"../LadiksMPQEditor/patch-WC1/WORLD/WMO/BROKENISLES/NIGHTELF/7NE_DRUID_BRIDGE01.WMO",
"../LadiksMPQEditor/patch-WC1/WORLD/WMO/BROKENISLES/NIGHTELF/7NE_DRUID_BRIDGE01.WMO",
"../LadiksMPQEditor/patch-WC1/WORLD/WMO/BROKENISLES/NIGHTELF/7NE_DRUID_TOWER01_NIGHTMARE.WMO",
"../LadiksMPQEditor/patch-WC1/WORLD/WMO/BROKENISLES/NIGHTELF/7NE_DRUID_BRIDGE01_NIGHTMARE.WMO",
"../LadiksMPQEditor/patch-WC1/WORLD/WMO/BROKENISLES/NIGHTELF/7NE_NIGHTELF_RUINPIECE06.WMO",
"../LadiksMPQEditor/patch-WC1/WORLD/WMO/BROKENISLES/NIGHTELF/7NE_NIGHTELF_BRIDGESHORT.WMO",
"../LadiksMPQEditor/patch-WC1/WORLD/WMO/DUNGEON/PVP/CUSTOM_VALSHARAH_ARENA.WMO"
]
},
"coordinateSystem": {
"conversion": "three(x,y,z)=(-wow.x,wow.z,wow.y)",
"rebasedOrigin": [
6.0437164306640625,
-37.49217987060547,
30.740463256835938
],
"alignmentOffset": [
34.174934,
-32.347685,
20.31486
],
"alignment": "primary WMO matched to the existing HealerMan stage coordinate frame"
},
"bounds": {
"min": [
-289.133544921875,
-32.347686767578125,
-200.8459930419922
],
"max": [
357.4833984375,
316.2064514160156,
241.47572326660156
]
},
"geometry": {
"groups": 18,
"triangles": 82815,
"collisionTriangles": 82815,
"collisionChunks": 1
},
"navigation": {
"triangles": 209,
"vertices": 627,
"sourceComponents": 20,
"spawnDistances": [
0.5941920148506428,
0.0212655626862784
],
"rawTriangles": 353,
"report": "recast-report.json"
},
"assets": [
{
"file": "visual.glb",
"bytes": 2611788,
"sha256": "25e8a0d63d420559a6bc965dc2b930039d951de8cdc189d785a00edc3610b112"
},
{
"file": "collision.glb",
"bytes": 1805536,
"sha256": "48f45c434687f07969a618e1251e05e8672061d16a1f3a88338dbc667e33e78e"
},
{
"file": "navigation.glb",
"bytes": 10936,
"sha256": "ac69ef1e845f632576598a8b2a5d0bbfa8086b21ed5d7fd17af06d5a565a5248"
}
]
}
Binary file not shown.
@@ -0,0 +1,114 @@
{
"build": {
"attempts": [
{
"failures": [],
"tileCount": 1,
"tileSize": null,
"valid": true
}
],
"gridCells": 2074478,
"gridHeight": 994,
"gridWidth": 2087,
"ignoredEmptyTilePackingFailures": 0,
"intermediateRetention": null,
"mode": "solo",
"partition": "watershed",
"populatedTileCount": 1,
"tileColumns": 1,
"tileCount": 1,
"tileRows": 1,
"tileSize": null
},
"dungeonId": "black-rook-hold-arena",
"generator": "@recast-navigation/three@0.43.1",
"geometry": {
"bounds": [
[
-92.08255767822266,
-16.14961814880371,
-279.4311218261719
],
[
321.9174499511719,
37.25038528442383,
-82.83113098144531
]
],
"boundsTolerance": 0.4,
"rejectedOutOfBoundsTriangles": 0,
"sourceTriangles": 7170,
"sourceVertices": 21510,
"triangles": 7170,
"vertices": 21510
},
"input": {
"bounds": [
[
-93.08255767822266,
-39.549617767333984,
-280.0311279296875
],
[
324.1624450683594,
69.1881103515625,
-81.26593780517578
]
],
"degenerateTriangleCount": 0,
"invalidIndexCount": 0,
"meshCount": 1,
"nonFiniteCoordinateCount": 0,
"triangleCount": 49821,
"vertexCount": 149463
},
"inputChunkChecksums": {
"public/assets/game/arenas/black-rook-hold-arena/navigation-collision.glb": "285bdce7d5b5085eef7d25f82a5b6a5b380605a310c539e8e94984182c835749"
},
"inputChunks": [
"public/assets/game/arenas/black-rook-hold-arena/navigation-collision.glb"
],
"output": "public/assets/game/arenas/black-rook-hold-arena/navigation-raw.glb",
"schemaVersion": 1,
"settings": {
"agentHeight": 1.8,
"agentMaxClimb": 0.5,
"agentMaxSlope": 50,
"agentRadius": 0.36,
"cellHeight": 0.1,
"cellSize": 0.2
},
"source": {
"adtFiles": [
"blackrookholdarena_28_28.adt",
"blackrookholdarena_28_29.adt",
"blackrookholdarena_28_30.adt",
"blackrookholdarena_29_28.adt",
"blackrookholdarena_29_29.adt",
"blackrookholdarena_29_30.adt",
"blackrookholdarena_30_28.adt",
"blackrookholdarena_30_29.adt",
"blackrookholdarena_30_30.adt"
],
"gameplayBounds": {
"max": [
312,
30,
-110
],
"min": [
-82,
-10,
-242
]
},
"kind": "adt-placed-wmo-repair",
"legacyCollision": "public/assets/game/manastorm/1784-blackrookholdarena/collision.glb",
"placedWmos": [
"../LadiksMPQEditor/patch-WC1/WORLD/WMO/BROKENISLES/VALSHARAH/7VS_BLACKROOKHOLD_MICRO01.WMO",
"../LadiksMPQEditor/patch-WC1/WORLD/WMO/PVP/BUILDINGS/BLACKROOKHOLD/7VS_BLACKROOKHOLD_ARENA.WMO",
"../LadiksMPQEditor/patch-WC1/WORLD/WMO/PVP/BUILDINGS/BLACKROOKHOLD/BLACKROOKHOLD_ARENA_PLATFORMTEST.WMO"
]
}
}
@@ -0,0 +1,101 @@
{
"schemaVersion": 1,
"id": "black-rook-hold-arena",
"title": "Black Rook Hold Arena",
"status": "generated-review-required",
"source": {
"mapDirectory": "patch-WB1/world/maps/blackrookholdarena",
"adtFiles": [
"blackrookholdarena_28_28.adt",
"blackrookholdarena_28_29.adt",
"blackrookholdarena_28_30.adt",
"blackrookholdarena_29_28.adt",
"blackrookholdarena_29_29.adt",
"blackrookholdarena_29_30.adt",
"blackrookholdarena_30_28.adt",
"blackrookholdarena_30_29.adt",
"blackrookholdarena_30_30.adt"
],
"placementCount": 3,
"placedWmos": [
"../LadiksMPQEditor/patch-WC1/WORLD/WMO/BROKENISLES/VALSHARAH/7VS_BLACKROOKHOLD_MICRO01.WMO",
"../LadiksMPQEditor/patch-WC1/WORLD/WMO/PVP/BUILDINGS/BLACKROOKHOLD/7VS_BLACKROOKHOLD_ARENA.WMO",
"../LadiksMPQEditor/patch-WC1/WORLD/WMO/PVP/BUILDINGS/BLACKROOKHOLD/BLACKROOKHOLD_ARENA_PLATFORMTEST.WMO"
]
},
"coordinateSystem": {
"conversion": "three(x,y,z)=(-wow.x,wow.z,wow.y)",
"rebasedOrigin": [
-117.73179244995117,
-104.28124237060547,
60.68927764892578
],
"alignmentOffset": [
117.542488,
-102.29949,
-224.463489
],
"alignment": "primary WMO matched to the existing HealerMan stage coordinate frame"
},
"bounds": {
"min": [
-110.3111343383789,
-102.29949188232422,
-519.4838256835938
],
"max": [
345.3961181640625,
410.11322021484375,
70.55683898925781
]
},
"geometry": {
"groups": 20,
"triangles": 298817,
"collisionTriangles": 298817,
"collisionChunks": 4
},
"navigation": {
"triangles": 4948,
"vertices": 14844,
"sourceComponents": 805,
"spawnDistances": [
0.009180110009213026,
0.01568599673120942
],
"rawTriangles": 7170,
"report": "recast-report.json"
},
"assets": [
{
"file": "visual.glb",
"bytes": 9908648,
"sha256": "622c0832eb5a3bca85837de418b02be6dc5dad54db3b05e69e740d93c870e319"
},
{
"file": "collision.glb",
"bytes": 2059780,
"sha256": "27a698c59e08744bd7bf6cfe9585f643a28aea45850da85020e3b4bac45ce92f"
},
{
"file": "collision-001.glb",
"bytes": 2443032,
"sha256": "914702646d8a6a657d677bd9f69b1b0aea13f4033952c143ff85d8932127a82f"
},
{
"file": "collision-002.glb",
"bytes": 2377504,
"sha256": "33622cbbc5e82cebee74049a53cd9fbb4e1ca8196322697f751916a3dd9d30ec"
},
{
"file": "collision-003.glb",
"bytes": 916280,
"sha256": "2f405e27efcf4e7b4d41d2286293dcbe700d854edf4d5aa276bf5b0523e9748a"
},
{
"file": "navigation.glb",
"bytes": 238420,
"sha256": "e463a0220842a4793b2150e95f4fd704f575def288813c781792b021afe8d3f0"
}
]
}
@@ -0,0 +1,89 @@
{
"build": {
"attempts": [
{
"failures": [],
"tileCount": 1,
"tileSize": null,
"valid": true
}
],
"gridCells": 652881,
"gridHeight": 849,
"gridWidth": 769,
"ignoredEmptyTilePackingFailures": 0,
"intermediateRetention": null,
"mode": "solo",
"partition": "watershed",
"populatedTileCount": 1,
"tileColumns": 1,
"tileCount": 1,
"tileRows": 1,
"tileSize": null
},
"dungeonId": "blades-edge-arena",
"generator": "@recast-navigation/three@0.43.1",
"geometry": {
"bounds": [
[
-75.85150146484375,
6.099999904632568,
-80.292236328125
],
[
76.14849853515625,
82.0999984741211,
80.3077621459961
]
],
"boundsTolerance": 0.4,
"rejectedOutOfBoundsTriangles": 0,
"sourceTriangles": 3932,
"sourceVertices": 11796,
"triangles": 3932,
"vertices": 11796
},
"input": {
"bounds": [
[
-76.85150146484375,
0,
-84.8922348022461
],
[
76.85150146484375,
82.12013244628906,
84.8922348022461
]
],
"degenerateTriangleCount": 0,
"invalidIndexCount": 0,
"meshCount": 1,
"nonFiniteCoordinateCount": 0,
"triangleCount": 7327,
"vertexCount": 7086
},
"inputChunkChecksums": {
"public/assets/game/arenas/blades-edge-arena/collision.glb": "96bb151cc43fcac887cee1e573878221e14d4690e023bc4cf7b5b40c2788333a"
},
"inputChunks": [
"public/assets/game/arenas/blades-edge-arena/collision.glb"
],
"output": "public/assets/game/arenas/blades-edge-arena/navigation-raw.glb",
"schemaVersion": 1,
"settings": {
"agentHeight": 1.8,
"agentMaxClimb": 0.5,
"agentMaxSlope": 50,
"agentRadius": 0.36,
"cellHeight": 0.1,
"cellSize": 0.2
},
"source": {
"files": [
"../LadiksMPQEditor/common-2.mpq/World/wmo/PvP/Buildings/AncientOrcArena/ancorc_PVPstadium.wmo",
"../LadiksMPQEditor/common-2.mpq/World/wmo/PvP/Buildings/AncientOrcArena/ancorc_PVPstadium_000.wmo"
],
"kind": "direct-wmo-parser"
}
}
@@ -0,0 +1,92 @@
{
"schemaVersion": 1,
"id": "blades-edge-arena",
"title": "Blade's Edge Arena",
"status": "generated-review-required",
"source": {
"root": "../LadiksMPQEditor/common-2.mpq/World/wmo/PvP/Buildings/AncientOrcArena/ancorc_PVPstadium.wmo",
"groupCount": 1
},
"coordinateSystem": {
"conversion": "three(x,y,z)=(-wow.x,wow.z,wow.y)",
"rebasedOrigin": [
-0.32387542724609375,
-3.3863677978515625,
-0.1770477294921875
]
},
"sourceBounds": {
"min": [
-77.17537689208984,
-3.3863677978515625,
-85.06928253173828
],
"max": [
76.52762603759766,
78.7337646484375,
84.7151870727539
]
},
"bounds": {
"min": [
-76.85150146484375,
0,
-84.8922348022461
],
"max": [
76.85150146484375,
82.12013244628906,
84.8922348022461
]
},
"geometry": {
"groups": 1,
"vertices": 7086,
"triangles": 7327,
"collisionTriangles": 7327,
"triangleFlags": [
{
"group": "group-000",
"counts": {
"8": 680,
"36": 616,
"38": 137,
"72": 2729,
"100": 2922,
"102": 243
}
}
]
},
"navigation": {
"triangles": 465,
"vertices": 1395,
"sourceComponents": 134,
"spawnDistances": [
0.0026893801684426334,
0.004853620635976984
],
"rawTriangles": 3932,
"report": "recast-report.json"
},
"assets": [
{
"role": "visual",
"file": "visual.glb",
"bytes": 259116,
"sha256": "5dc8c6662bccf04892b059c819de91b1134cce6011a1f707c5ee9645491e5279"
},
{
"role": "collision",
"file": "collision.glb",
"bytes": 173784,
"sha256": "96bb151cc43fcac887cee1e573878221e14d4690e023bc4cf7b5b40c2788333a"
},
{
"role": "navigation",
"file": "navigation.glb",
"bytes": 23228,
"sha256": "d99822c69df3f6363c9fab1c6c67c70c3afa4e94ed0e66fa992adf8b6724cf2b"
}
]
}
Loaded 100 of 1263 files, more files were not shown because too many files have changed in this diff. Show more