Compare commits

...
5 Commits
Author SHA1 Message Date
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
578 changed files with 178530 additions and 1513 deletions

No files matched your search

+1
View File
@@ -20,5 +20,6 @@ releases/
/content/
dist-android/
.android-public/
.web-public/
__pycache__/
*.pyc
+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
Android APK contains the React/Three.js runtime, native Android bridge, menus,
local profile and save support, UI assets, and the Wailing Caverns starter
pack. Other GLBs, textures, audio, character packs, dungeons, and Manastorm
stages are published by TrueNAS as optional content.
Healer Man separates the installed game client from large game content. Both
the production browser build and Android APK contain a compact required set:
the React/Three.js runtime, menus, local profile and save support, UI assets,
starter equipment, Wailing Caverns starter content, and the basic Human
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
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
will not activate incompatible content.
The browser build remains a full build served by TrueNAS. It receives client
code when the app checkout is pulled, rebuilt, and restarted. The Android build
is deliberately separate and compact so the APK does not inherit the complete
multi-gigabyte browser asset catalog.
Measured on August 14, 2026, the production browser `dist` is 3.88 GiB across
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.
Production builds deliberately stage only required content. `npm run build`
prepares `.web-public` and emits the compact browser `dist`; Android prepares
`.android-public` and emits `dist-android`. The development server continues to
use the source `public` tree so asset-pipeline work remains convenient. The
complete source catalog and published immutable objects stay on TrueNAS, not in
every player's initial browser or Android installation.
## 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
storage. Filenames are therefore not used as version numbers and runtime code
does not need to know the hash.
storage or, in production browsers, to the app-managed content cache through a
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
@@ -68,17 +67,34 @@ Publication order is intentionally atomic:
3. Write the versioned manifest.
4. Replace `manifest.json` only after all referenced objects exist.
On a device, the client fetches the small manifest and compares it with its
installed manifest. Only missing or hash-mismatched objects are downloaded.
Android streams each object to a `.part` file, supports HTTP range resume,
verifies its size and SHA-256, then renames it into the object cache. The active
logical-path map changes only after the complete pack verifies. An interrupted
or corrupt update leaves the previous pack playable.
The client fetches the small manifest and compares it with its bundled and
installed file identities. Only missing or hash-mismatched objects are
downloaded. Browsers download into a temporary Cache Storage staging area,
verify every object's byte count and SHA-256, and promote the pack to the active
cache only after the complete pack succeeds. Android streams each object to a
`.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
app-private files directory, outside the packaged web bundle, and survive an
APK update. Players may remove optional packs through the content manager; save
data is stored separately and is never removed with content.
The Downloads screen uses the same lifecycle in browser and Android. A missing
pack offers **Download**, an installed pack with changed files offers
**Update**, and an installed optional pack offers **Remove**. Required packs are
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
@@ -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.
- A failed update check is silent outside the content manager.
- 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
when connectivity returns.
- 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
```
The Node server exposes the content volume at `/content`. Manifests use
`no-cache`; immutable hashed objects use long-lived cache headers and support
byte ranges for resumed downloads.
The Node server exposes the compact production browser client at `/` and the
complete downloadable-content volume at `/content`. Manifests use `no-cache`;
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:
@@ -121,15 +140,29 @@ discover a manifest whose files have not been published.
## Pack policy
Packs are player-facing groups while files remain individually addressable.
This permits a fast initial pack install and small later patches. Current pack
IDs are derived predictably:
This permits a compact initial install and small later patches. Required pack
IDs include:
```text
core:runtime
core:ui
core:equipment
core:character-basic
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
characters:wow335a-v1
characters:ascension-v1
characters:runewaker-v1
core:combat-media
manastorm:<stage-id>
shared:creatures
```
+24 -18
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
not the game database.
Large runtime assets are published separately under `/app/content`. Android
clients download verified content objects from `/content` and retain them in
Large runtime assets are published separately under `/app/content`. Production
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,
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
with `cp`. The checkout contains several gigabytes of required GLB assets, so
the initial clone and first build will take substantially longer than later
fast-forward updates.
with `cp`. The checkout contains several gigabytes of content-source GLB assets,
so the initial clone and first content publication will take substantially
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
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
`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
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
would hide the checkout's required `/app/data/loot/schema.sql`. The
startup command installs locked dependencies, initializes the schema, publishes
new or changed content objects, builds the full browser bundle, and starts the
combined static/API/content server. Existing content objects are reused.
new or changed content objects, builds the compact required-content browser
bundle, and starts the combined static/API/content server. Existing content
objects are reused.
After startup, test on the LAN:
@@ -220,8 +224,8 @@ git rev-parse HEAD
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,
`content/`, `dist/`, `dist-android/`, or `.android-public/` output. The final
command prints the exact deployed commit ID.
`content/`, `dist/`, `dist-android/`, `.web-public/`, or `.android-public/`
output. The final command prints the exact deployed commit ID.
Next, open the TrueNAS Apps UI and **stop** `healer-man`. Open a TrueNAS shell
and run these exact commands:
@@ -247,11 +251,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
`healer-man` in the TrueNAS Apps UI afterward. Container startup
publishes immutable content objects and replaces `manifest.json` only after all
objects exist, then rebuilds the browser client and starts the server. Android
devices discover the small new manifest and download only missing or changed
files. Asset-only updates do not require a new APK. A failed fast-forward pull
deliberately leaves the running checkout unchanged; resolve diverged history on
the development machine rather than forcing the TrueNAS checkout.
objects exist, then rebuilds the browser client and starts the server. Browser
and Android clients discover the small new manifest and download only missing
or changed files for packs the player installed. Asset-only updates do not
require a new APK. A failed fast-forward pull deliberately leaves the running
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:
@@ -286,9 +291,10 @@ copies; it does not replace dataset-level protection.
## APK releases and Obtainium
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
content rather than the full multi-gigabyte browser catalog. Downloaded packs
survive APK updates.
which contains the game runtime, UI, starter equipment, basic Human character,
and Wailing Caverns starter content. Optional character/skin packs, original
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
`JAVA_HOME` plus `ANDROID_SDK_ROOT`. The build wrapper also recognizes the
+113
View File
@@ -1572,3 +1572,116 @@ Vite's existing large-chunk advisory remains informational.
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.
+48 -12
View File
@@ -41,6 +41,28 @@ npm test
npm run build
```
## 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
All 21 CoA classes use a checked-in live Vol'Jin catalog generated from
@@ -81,12 +103,23 @@ validates the relational data and ships both a browser-safe JSON catalog and
for a future loot-browser screen.
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
looted, and is then saved in that character's inventory. The SQL loot source
contains the original 3.3.5a attributes, ratings, armor, block, weapon damage,
weapon speed, regeneration, and spell-power values for each item. A scaled
drop preserves that original stat distribution instead of replacing it with a
generic item-power budget.
captures its item level at the killing blow, remains on the corpse until
looted, and is then saved in that character's inventory. Drops use character
level through 79; level-80 drops begin the first endgame tier at item level 85.
The SQL loot source contains the original 3.3.5a attributes, ratings, armor,
block, weapon damage, weapon speed, regeneration, and spell-power values for
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
stats. Strength, Agility, Stamina, Intellect, Spirit, Attack Power, Spell
@@ -181,12 +214,13 @@ npm run android:apk
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`.
Android uses a separate compact `dist-android` build. It bundles the client,
interface, equipment, and Wailing Caverns starter content while optional
dungeons, character packs, and Manastorm stages are downloaded into app-private
storage. Installed content and local saves remain playable without a server
connection and survive APK updates. See `CONTENT_UPDATES.md` for the update
contract and `DEPLOYMENT.md` for TrueNAS publishing and signed Gitea releases.
Android uses a compact `dist-android` build with the same required-content
boundary as the production browser build. Optional dungeons, character/skin
packs, Manastorm stages, and original spell media are downloaded into
app-private storage. Installed content and local saves remain playable without
a server connection and survive APK updates. See `CONTENT_UPDATES.md` for the
update contract and `DEPLOYMENT.md` for TrueNAS publishing and signed Gitea
releases.
## Runtime details
@@ -206,6 +240,8 @@ contract and `DEPLOYMENT.md` for TrueNAS publishing and signed Gitea releases.
compressed in GPU memory instead of expanding to uncompressed RGBA textures.
- Missing production GLBs activate a small cave proxy; malformed assets activate
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
face-button diamond, shoulders, and D-pad keep the physical controller layout
visible without showing all 24 bindings over the playfield.
+8 -4
View File
@@ -71,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
release.
Single-player remains offline-capable. A fresh APK includes the runtime and
starter content. Additional content that a player has downloaded is retained
in Android app-private storage and can be used offline after download.
Single-player remains offline-capable. A fresh APK includes the runtime,
interface, starter equipment, Wailing Caverns, and the basic Human character
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
@@ -287,7 +290,8 @@ git diff --cached --check
```
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
deleting the local file.
+18 -1
View File
@@ -73,6 +73,23 @@ attaches native animated client models by display ID. It writes:
- `src/game/generated/dungeonCampaignCatalog.compressed.ts`, the bundled catalog
- `src/game/generated/dungeonAvailability.json`, the generated availability list
Boss specials are compiled as independent mechanic records. AzerothCore
SmartAI timers and health events are imported automatically; C++ encounter
spells are imported from the pinned script checkout. Add or override a boss in
`dungeon-pipeline/boss-mechanics.json` when an encounter needs hand-authored
targeting, summon behavior, timing, or telegraph geometry. Use `mode: "replace"`
to make that list authoritative or `mode: "append"` to layer entries ahead of
the imported mechanics, then run `npm run dungeon:catalog`. The generated
`combat.mechanicIds` list is the stable loadout boundary intended for later
encounter randomization.
The same catalog also stores Runewaker kits under
`rw-<dungeon>-<entity-id>` keys. Run `npm run runewaker:bosses:refresh` to
rebuild those records from preserved RuneWaker spell/Lua evidence, regenerate
the population packages, and run `npm run runewaker:audit:gameplay`. A record
whose preserved source has no recoverable combat ability is explicitly marked
`source.kind: "healer-man-source-gap"` rather than being claimed as authentic.
Stock AzerothCore population is used for the standard dungeons. The three
Ascension-specific instances—Tinkertech Showdown, Frozen Reach, and Forgotten
Mine—keep their client encounter identities and use an explicit procedural
@@ -229,4 +246,4 @@ Kresh is intentionally recorded as a source-faithful melee-only boss: entry
3653 has no spell or SmartAI row in the pinned AzerothCore snapshot. Trial of
the Champion is likewise documented as a boss-arena population rather than a
trash route. These exceptions are asserted by exact dungeon/entity IDs; any
new basic-only boss or mob-less dungeon fails the batch.
new basic-only boss or mob-less dungeon fails the batch.
File diff suppressed because it is too large. Load diff
@@ -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": []
}
@@ -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": []
}
@@ -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": []
}
@@ -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": []
}
+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "healer-man",
"version": "0.1.12",
"version": "0.1.17",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "healer-man",
"version": "0.1.12",
"version": "0.1.17",
"dependencies": {
"@capacitor/android": "8.4.1",
"@capacitor/core": "8.4.1",
+6 -2
View File
@@ -1,7 +1,7 @@
{
"name": "healer-man",
"private": true,
"version": "0.1.12",
"version": "0.1.17",
"type": "module",
"scripts": {
"dev": "vite --host 0.0.0.0",
@@ -10,6 +10,7 @@
"db:backup": "node scripts/backup-game-database.mjs",
"server:test": "node --test server/*.test.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",
"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",
@@ -62,6 +63,8 @@
"dungeon:navmesh": "node scripts/dungeon-pipeline/cli.mjs navmesh",
"dungeon:navmesh:conversion": "node scripts/dungeon-pipeline/cli.mjs navmesh-conversion",
"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",
"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",
@@ -73,6 +76,7 @@
"runewaker:register:all": "node scripts/runewaker-pipeline/cli.mjs register-all",
"runewaker:refresh:all": "node scripts/runewaker-pipeline/cli.mjs refresh-all",
"runewaker:spells:refresh": "node scripts/runewaker-pipeline/export-spell-catalog.mjs",
"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: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",
@@ -96,7 +100,7 @@
"assets:performance:audit": "node scripts/asset-pipeline/audit-environment-performance.mjs",
"balance:benchmark": "vite-node scripts/combat-benchmark/run.ts",
"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 assets:ktx2:audit && npm run assets:performance:audit",
"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",
@@ -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"
}
]
}
@@ -0,0 +1,90 @@
{
"build": {
"attempts": [
{
"failures": [],
"tileCount": 1,
"tileSize": null,
"valid": true
}
],
"gridCells": 529759,
"gridHeight": 713,
"gridWidth": 743,
"ignoredEmptyTilePackingFailures": 0,
"intermediateRetention": null,
"mode": "solo",
"partition": "watershed",
"populatedTileCount": 1,
"tileColumns": 1,
"tileCount": 1,
"tileRows": 1,
"tileSize": null
},
"dungeonId": "dalaran-sewers",
"generator": "@recast-navigation/three@0.43.1",
"geometry": {
"bounds": [
[
-73.60513305664062,
0.30000001192092896,
-69.85077667236328
],
[
73.5948715209961,
79,
70.14923095703125
]
],
"boundsTolerance": 0.4,
"rejectedOutOfBoundsTriangles": 0,
"sourceTriangles": 4054,
"sourceVertices": 12162,
"triangles": 4054,
"vertices": 12162
},
"input": {
"bounds": [
[
-74.20513153076172,
0,
-71.25077819824219
],
[
74.20513153076172,
92.40137481689453,
71.25077819824219
]
],
"degenerateTriangleCount": 0,
"invalidIndexCount": 0,
"meshCount": 2,
"nonFiniteCoordinateCount": 0,
"triangleCount": 15469,
"vertexCount": 13094
},
"inputChunkChecksums": {
"public/assets/game/arenas/dalaran-sewers/collision.glb": "88c889838b76365ee0541dcce567151419b3310a6dc1252934ffb997f31215bd"
},
"inputChunks": [
"public/assets/game/arenas/dalaran-sewers/collision.glb"
],
"output": "public/assets/game/arenas/dalaran-sewers/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/Dalaran/dalaran_sewer_arena.wmo",
"../LadiksMPQEditor/common-2.mpq/World/wmo/PvP/Buildings/Dalaran/dalaran_sewer_arena_000.wmo",
"../LadiksMPQEditor/common-2.mpq/World/wmo/PvP/Buildings/Dalaran/dalaran_sewer_arena_001.wmo"
],
"kind": "direct-wmo-parser"
}
}
@@ -0,0 +1,105 @@
{
"schemaVersion": 1,
"id": "dalaran-sewers",
"title": "Dalaran Sewers",
"status": "generated-review-required",
"source": {
"root": "../LadiksMPQEditor/common-2.mpq/World/wmo/PvP/Buildings/Dalaran/dalaran_sewer_arena.wmo",
"groupCount": 2
},
"coordinateSystem": {
"conversion": "three(x,y,z)=(-wow.x,wow.z,wow.y)",
"rebasedOrigin": [
-9.411468505859375,
-16.876672744750977,
10.746021270751953
]
},
"sourceBounds": {
"min": [
-83.6166000366211,
-16.876672744750977,
-60.5047607421875
],
"max": [
64.79366302490234,
75.52470397949219,
81.9968032836914
]
},
"bounds": {
"min": [
-74.20513153076172,
0,
-71.25077819824219
],
"max": [
74.20513153076172,
92.40137481689453,
71.25077819824219
]
},
"geometry": {
"groups": 2,
"vertices": 13094,
"triangles": 15469,
"collisionTriangles": 15469,
"triangleFlags": [
{
"group": "group-000",
"counts": {
"8": 85,
"32": 545,
"36": 573,
"72": 40,
"96": 2835,
"100": 98
}
},
{
"group": "group-001",
"counts": {
"8": 165,
"10": 480,
"32": 766,
"36": 2362,
"72": 136,
"74": 416,
"96": 2053,
"100": 4915
}
}
]
},
"navigation": {
"triangles": 458,
"vertices": 1374,
"sourceComponents": 104,
"spawnDistances": [
0.004929398584727517,
0.0049300317713031425
],
"rawTriangles": 4054,
"report": "recast-report.json"
},
"assets": [
{
"role": "visual",
"file": "visual.glb",
"bytes": 501848,
"sha256": "91b37f5df3c5c0d2ecad9e1096177abfe8eb36acc384df36a949ce246a0155ba"
},
{
"role": "collision",
"file": "collision.glb",
"bytes": 344140,
"sha256": "88c889838b76365ee0541dcce567151419b3310a6dc1252934ffb997f31215bd"
},
{
"role": "navigation",
"file": "navigation.glb",
"bytes": 22896,
"sha256": "2e1db39fe16bd3d4a747710e1da774d841bc9cd9ada446c666a1d95a4e1aafb2"
}
]
}
Binary file not shown.
@@ -0,0 +1,89 @@
{
"build": {
"attempts": [
{
"failures": [],
"tileCount": 1,
"tileSize": null,
"valid": true
}
],
"gridCells": 605259,
"gridHeight": 783,
"gridWidth": 773,
"ignoredEmptyTilePackingFailures": 0,
"intermediateRetention": null,
"mode": "solo",
"partition": "watershed",
"populatedTileCount": 1,
"tileColumns": 1,
"tileCount": 1,
"tileRows": 1,
"tileSize": null
},
"dungeonId": "nagrand-arena",
"generator": "@recast-navigation/three@0.43.1",
"geometry": {
"bounds": [
[
-75.41183471679688,
1.2000000476837158,
-74.84174346923828
],
[
75.9881591796875,
72.80000305175781,
65.15826416015625
]
],
"boundsTolerance": 0.4,
"rejectedOutOfBoundsTriangles": 0,
"sourceTriangles": 3536,
"sourceVertices": 10608,
"triangles": 3536,
"vertices": 10608
},
"input": {
"bounds": [
[
-77.21183776855469,
0,
-78.24174499511719
],
[
77.21183776855469,
82.11756134033203,
78.24174499511719
]
],
"degenerateTriangleCount": 0,
"invalidIndexCount": 0,
"meshCount": 1,
"nonFiniteCoordinateCount": 0,
"triangleCount": 7727,
"vertexCount": 8197
},
"inputChunkChecksums": {
"public/assets/game/arenas/nagrand-arena/collision.glb": "c5ec36344bc335aad5c63607a93d6cacb535d4055c2626fed7da250855f5fa74"
},
"inputChunks": [
"public/assets/game/arenas/nagrand-arena/collision.glb"
],
"output": "public/assets/game/arenas/nagrand-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/Dungeon/OL_OgreHuts/PVP_Ogre_Arena01.wmo",
"../LadiksMPQEditor/common-2.mpq/World/wmo/Dungeon/OL_OgreHuts/PVP_Ogre_Arena01_000.wmo"
],
"kind": "direct-wmo-parser"
}
}
@@ -0,0 +1,94 @@
{
"schemaVersion": 1,
"id": "nagrand-arena",
"title": "Nagrand Arena",
"status": "generated-review-required",
"source": {
"root": "../LadiksMPQEditor/common-2.mpq/World/wmo/Dungeon/OL_OgreHuts/PVP_Ogre_Arena01.wmo",
"groupCount": 1
},
"coordinateSystem": {
"conversion": "three(x,y,z)=(-wow.x,wow.z,wow.y)",
"rebasedOrigin": [
49.19449806213379,
-10.582855224609375,
30.535707473754883
]
},
"sourceBounds": {
"min": [
-28.017337799072266,
-10.582855224609375,
-47.70603561401367
],
"max": [
126.40633392333984,
71.53470611572266,
108.77745056152344
]
},
"bounds": {
"min": [
-77.21183776855469,
0,
-78.24174499511719
],
"max": [
77.21183776855469,
82.11756134033203,
78.24174499511719
]
},
"geometry": {
"groups": 1,
"vertices": 8197,
"triangles": 7727,
"collisionTriangles": 7727,
"triangleFlags": [
{
"group": "group-000",
"counts": {
"8": 783,
"32": 35,
"36": 831,
"38": 2,
"72": 2230,
"96": 502,
"100": 3291,
"102": 53
}
}
]
},
"navigation": {
"triangles": 1450,
"vertices": 4350,
"sourceComponents": 155,
"spawnDistances": [
0.0025342739142059146,
0.0025336963502397706
],
"rawTriangles": 3536,
"report": "recast-report.json"
},
"assets": [
{
"role": "visual",
"file": "visual.glb",
"bytes": 290580,
"sha256": "6730970440c31df26e4fe90a6eb3913e6402f0027a334d966fb2b57c2e7b3e7c"
},
{
"role": "collision",
"file": "collision.glb",
"bytes": 191916,
"sha256": "c5ec36344bc335aad5c63607a93d6cacb535d4055c2626fed7da250855f5fa74"
},
{
"role": "navigation",
"file": "navigation.glb",
"bytes": 70512,
"sha256": "cd9027c8d3cf175a8879efad1eb51584f3fbce1bc2eb9355959676471e06798a"
}
]
}
Binary file not shown.
@@ -0,0 +1,89 @@
{
"build": {
"attempts": [
{
"failures": [],
"tileCount": 1,
"tileSize": null,
"valid": true
}
],
"gridCells": 2185272,
"gridHeight": 1208,
"gridWidth": 1809,
"ignoredEmptyTilePackingFailures": 0,
"intermediateRetention": null,
"mode": "solo",
"partition": "watershed",
"populatedTileCount": 1,
"tileColumns": 1,
"tileCount": 1,
"tileRows": 1,
"tileSize": null
},
"dungeonId": "ring-of-valor",
"generator": "@recast-navigation/three@0.43.1",
"geometry": {
"bounds": [
[
-180.21835327148438,
0.10000000149011612,
-117.37078094482422
],
[
180.181640625,
100.80000305175781,
120.02922058105469
]
],
"boundsTolerance": 0.4,
"rejectedOutOfBoundsTriangles": 0,
"sourceTriangles": 4405,
"sourceVertices": 13215,
"triangles": 4405,
"vertices": 13215
},
"input": {
"bounds": [
[
-180.818359375,
0,
-120.77078247070312
],
[
180.818359375,
116.26216125488281,
120.77078247070312
]
],
"degenerateTriangleCount": 0,
"invalidIndexCount": 0,
"meshCount": 1,
"nonFiniteCoordinateCount": 0,
"triangleCount": 9713,
"vertexCount": 12167
},
"inputChunkChecksums": {
"public/assets/game/arenas/ring-of-valor/collision.glb": "25162e36ed6fea03d6de939cf4d742bc142fbebb2db1c9fbc6f2fcc9e15cffdf"
},
"inputChunks": [
"public/assets/game/arenas/ring-of-valor/collision.glb"
],
"output": "public/assets/game/arenas/ring-of-valor/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/Orgrimmar/OrgrimmarArena.wmo",
"../LadiksMPQEditor/common-2.mpq/World/wmo/PvP/Buildings/Orgrimmar/OrgrimmarArena_000.wmo"
],
"kind": "direct-wmo-parser"
}
}
@@ -0,0 +1,94 @@
{
"schemaVersion": 1,
"id": "ring-of-valor",
"title": "Ring of Valor",
"status": "generated-review-required",
"source": {
"root": "../LadiksMPQEditor/common-2.mpq/World/wmo/PvP/Buildings/Orgrimmar/OrgrimmarArena.wmo",
"groupCount": 1
},
"coordinateSystem": {
"conversion": "three(x,y,z)=(-wow.x,wow.z,wow.y)",
"rebasedOrigin": [
-0.44493865966796875,
-32.01484298706055,
0
]
},
"sourceBounds": {
"min": [
-181.26329040527344,
-32.01484298706055,
-120.77078247070312
],
"max": [
180.3734130859375,
84.24732208251953,
120.77078247070312
]
},
"bounds": {
"min": [
-180.818359375,
0,
-120.77078247070312
],
"max": [
180.818359375,
116.26216125488281,
120.77078247070312
]
},
"geometry": {
"groups": 1,
"vertices": 12167,
"triangles": 9713,
"collisionTriangles": 9713,
"triangleFlags": [
{
"group": "group-000",
"counts": {
"8": 18,
"32": 1063,
"36": 590,
"38": 586,
"72": 126,
"96": 1307,
"100": 5028,
"102": 995
}
}
]
},
"navigation": {
"triangles": 702,
"vertices": 2106,
"sourceComponents": 61,
"spawnDistances": [
1.1157695927091633,
1.258558140579426
],
"rawTriangles": 4405,
"report": "recast-report.json"
},
"assets": [
{
"role": "visual",
"file": "visual.glb",
"bytes": 409692,
"sha256": "32d3dc93c8f5026d29f3e9bf2efb299145e8e191e358b201a62dc987e0fa3c46"
},
{
"role": "collision",
"file": "collision.glb",
"bytes": 263388,
"sha256": "25162e36ed6fea03d6de939cf4d742bc142fbebb2db1c9fbc6f2fcc9e15cffdf"
},
{
"role": "navigation",
"file": "navigation.glb",
"bytes": 34608,
"sha256": "db986ef21767aecf08edb435f11674a094996213685f83cd7d2172886949374d"
}
]
}
Binary file not shown.
@@ -0,0 +1,93 @@
{
"build": {
"attempts": [
{
"failures": [],
"tileCount": 1,
"tileSize": null,
"valid": true
}
],
"gridCells": 1226343,
"gridHeight": 1213,
"gridWidth": 1011,
"ignoredEmptyTilePackingFailures": 0,
"intermediateRetention": null,
"mode": "solo",
"partition": "watershed",
"populatedTileCount": 1,
"tileColumns": 1,
"tileCount": 1,
"tileRows": 1,
"tileSize": null
},
"dungeonId": "ruins-of-lordaeron",
"generator": "@recast-navigation/three@0.43.1",
"geometry": {
"bounds": [
[
-100.48125457763672,
3.5,
-119.45735168457031
],
[
96.71875,
77.70000457763672,
120.54264831542969
]
],
"boundsTolerance": 0.4,
"rejectedOutOfBoundsTriangles": 0,
"sourceTriangles": 7958,
"sourceVertices": 23874,
"triangles": 7958,
"vertices": 23874
},
"input": {
"bounds": [
[
-101.08125305175781,
0,
-121.25735473632812
],
[
101.08125305175781,
77.79415893554688,
121.25735473632812
]
],
"degenerateTriangleCount": 0,
"invalidIndexCount": 0,
"meshCount": 5,
"nonFiniteCoordinateCount": 0,
"triangleCount": 23642,
"vertexCount": 26192
},
"inputChunkChecksums": {
"public/assets/game/arenas/ruins-of-lordaeron/collision.glb": "a844092b66cbfcc8ae430879de3ce7a1e6441c2cfc69328dc2cb259e4cb6c645"
},
"inputChunks": [
"public/assets/game/arenas/ruins-of-lordaeron/collision.glb"
],
"output": "public/assets/game/arenas/ruins-of-lordaeron/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/Lordaeron/PVP_Lordaeron_Arena.wmo",
"../LadiksMPQEditor/common-2.mpq/World/wmo/PvP/Buildings/Lordaeron/PVP_Lordaeron_Arena_000.wmo",
"../LadiksMPQEditor/common-2.mpq/World/wmo/PvP/Buildings/Lordaeron/PVP_Lordaeron_Arena_001.wmo",
"../LadiksMPQEditor/common-2.mpq/World/wmo/PvP/Buildings/Lordaeron/PVP_Lordaeron_Arena_002.wmo",
"../LadiksMPQEditor/common-2.mpq/World/wmo/PvP/Buildings/Lordaeron/PVP_Lordaeron_Arena_003.wmo",
"../LadiksMPQEditor/common-2.mpq/World/wmo/PvP/Buildings/Lordaeron/PVP_Lordaeron_Arena_004.wmo"
],
"kind": "direct-wmo-parser"
}
}
@@ -0,0 +1,138 @@
{
"schemaVersion": 1,
"id": "ruins-of-lordaeron",
"title": "Ruins of Lordaeron",
"status": "generated-review-required",
"source": {
"root": "../LadiksMPQEditor/common-2.mpq/World/wmo/PvP/Buildings/Lordaeron/PVP_Lordaeron_Arena.wmo",
"groupCount": 5
},
"coordinateSystem": {
"conversion": "three(x,y,z)=(-wow.x,wow.z,wow.y)",
"rebasedOrigin": [
4.71783447265625,
-31.21632957458496,
15.956310272216797
]
},
"sourceBounds": {
"min": [
-96.36341857910156,
-31.21632957458496,
-105.3010482788086
],
"max": [
105.79908752441406,
46.57782745361328,
137.2136688232422
]
},
"bounds": {
"min": [
-101.08125305175781,
0,
-121.25735473632812
],
"max": [
101.08125305175781,
77.79415893554688,
121.25735473632812
]
},
"geometry": {
"groups": 5,
"vertices": 26192,
"triangles": 23642,
"collisionTriangles": 23642,
"triangleFlags": [
{
"group": "group-000",
"counts": {
"8": 1135,
"36": 3730,
"72": 730,
"100": 10270
}
},
{
"group": "group-001",
"counts": {
"8": 1,
"9": 2,
"32": 106,
"33": 22,
"36": 21,
"37": 14,
"72": 275,
"73": 47,
"96": 225,
"97": 236,
"100": 2550,
"101": 117
}
},
{
"group": "group-002",
"counts": {
"32": 21,
"96": 132
}
},
{
"group": "group-003",
"counts": {
"8": 13,
"9": 2,
"32": 185,
"33": 22,
"36": 53,
"37": 14,
"72": 252,
"73": 56,
"96": 276,
"97": 229,
"100": 2579,
"101": 174
}
},
{
"group": "group-004",
"counts": {
"36": 21,
"100": 132
}
}
]
},
"navigation": {
"triangles": 2085,
"vertices": 6255,
"sourceComponents": 157,
"spawnDistances": [
0.00292914523132256,
0.004205306248988376
],
"rawTriangles": 7958,
"report": "recast-report.json"
},
"assets": [
{
"role": "visual",
"file": "visual.glb",
"bytes": 916788,
"sha256": "b00bcd87bd72bbabcf3e7e7edab99e8f7ddbe820b849a40df90510096e9f2f4e"
},
{
"role": "collision",
"file": "collision.glb",
"bytes": 601048,
"sha256": "a844092b66cbfcc8ae430879de3ce7a1e6441c2cfc69328dc2cb259e4cb6c645"
},
{
"role": "navigation",
"file": "navigation.glb",
"bytes": 100996,
"sha256": "be7aa6c4822f0baecafe4eb148a5952d3ce8001c7617f351e7ab257d61e7cb59"
}
]
}
@@ -0,0 +1,39 @@
{
"schemaVersion": 1,
"id": "warnorken-arena",
"title": "Warnorken Arena",
"status": "validated",
"source": {
"kind": "validated-runewaker-package",
"navigationSource": "navigation-source.glb"
},
"navigation": {
"sourceComponents": 96,
"triangles": 365,
"vertices": 1095,
"spawnDistances": [
0.00402499431590021,
0.004012153291366225
]
},
"assets": [
{
"file": "visual.glb",
"bytes": 3752136,
"triangles": 55200,
"sha256": "c452a843c2e4123d4fe0d20da41558f5b5a1906548b3d091dc691ffc42ed19d9"
},
{
"file": "collision.glb",
"bytes": 3005760,
"triangles": 60751,
"sha256": "0b1ce7555da0d2900465e3539e1bf17ac244d23a0f5eb57a2106f29570757c5c"
},
{
"file": "navigation.glb",
"bytes": 18436,
"triangles": 365,
"sha256": "c6085ffc96b40b1f437b8bb7e111604c135a856b02fd9b6ccae20243183cf417"
}
]
}
Binary file not shown.
Loaded 100 of 578 files, more files were not shown because too many files have changed in this diff. Show more