Files
2026-08-14 15:56:39 -04:00

199 lines
10 KiB
Markdown

# RuneWaker dungeon animation audit
Audit date: 2026-08-01
## Authoritative current scope
This file retains the earlier rollout and pre-pilot baselines below for
provenance. The current recipe and runtime inventory is not a flat actor count:
| Inventory layer | Count | Meaning |
| --- | ---: | --- |
| Dungeon packages | 30 | 28 populated packages plus two authoritative empty copy zones |
| Entity templates | 436 | Runtime mob/boss/device definitions; not spawn rows |
| Base actor configurations | 268 | Shared ROS/appearance configurations before dungeon namespacing |
| Runtime-referenced shipping variants | 322 | Exact GLB paths that must be audited and visually reviewed |
| Configured native variants | 321 | Direct actors and exact image-specific paperdoll assemblies |
| Configured pose-only variants | 1 | Mantarick (`102452`, `judgement-light-pose`) |
The 436 templates map to 268 base configurations and then expand to 322
namespaced shipping variants because the same source actor can be packaged in
more than one dungeon and paperdoll containers can have image-specific
appearances. Checking 268 cache entries or unique ROS files therefore does not
prove that every runtime mob/boss asset is correct. The shipping-variant set
from `runtime-clip-coverage.json` is the full pose-audit input.
`demon-stronghold-125` and `zurhidon-stronghold-124` have no authoritative
population rows or actor variants. They must remain explicit zero-row entries,
not be silently populated and not be reported as failed imports.
Mantarick in Hall of Survivors is the only pose-only mapping. Its preserved
`judgement-light-pose.glb` has static posed geometry without an armature or
actions, so its procedural presentation is intentional and must stay visible in
the audit. Sardo Castle's `rune-device-red` (template `105758`, Rune Warning
Device) is different: it is a native animated device with idle, combat, wound,
and death clips, but no source locomotion. Its no-locomotion result is an
approved stationary-device exception, not evidence that the native rig failed.
## v4 repair and v5 acceptance boundary
On 2026-08-01 the native exporter's RuneWaker-to-HealerMan quaternion basis was
corrected from `(x, y, -z, w)` to `(-x, -y, z, w)`, the mapping implied by the
position reflection `S = diag(1, 1, -1)` and `R' = S R S`. That v4 repair fixed
the severe Giant Assassin and Blackhorn Silencer deformation while preserving
quaternion normalization and hemisphere continuity. Package-level Khronos
validation and focused Pasper rendered poses were green, but structural checks
alone cannot detect a wrong, finite rotation basis.
The current build cache identity is
`gr2-native-animation-v5-z-reflection-complete-cast-semantics-30hz`. v5 retains
the v4 quaternion repair and requires complete cast semantics: source-exported
cast-family clips must remain in manifest order and be reachable by the runtime
cast selector. Inventory coverage, selector coverage, numeric Blender sampling,
human contact-sheet review, and browser playtesting are separate required gates.
## Final v5 result
- All 29 generic population recipes rebuilt green. Forsaken Abbey's separate
nine-actor rebuild produced nine Khronos-clean GLBs with zero errors and zero
warnings.
- The regenerated inventory is green: 30 dungeons, 436 entity templates, 268
base actor configurations, 322 runtime-referenced shipping variants, and zero
blockers.
- Runtime semantic near misses are zero. The only remaining required-family
exceptions are Mantarick's documented pose-only presentation and Sardo's
native, stationary Rune Warning Device with no locomotion clip.
- `artifacts/animation-audit/post-v5/summary.json` covers all 322 variants and
44,305 evaluated poses: 282 numeric passes, 40 accepted-warning candidates,
zero errors, zero failures, and 634 flagged samples. The totals exactly match
the visually reviewed v4 batch totals, providing a no-pose-regression check
for the v5 cast-semantics rebuild.
- In the live packaged/offline browser, the catalog showed 30/30 RuneWaker
dungeons Ready. Pasper's Shrine and Hall of Survivors both loaded their
environments. The only console message was an unrelated library deprecation
warning; no model, skeleton, animation, WebGL, or dungeon-load error appeared.
- All 19 focused RuneWaker animation tests pass. The unfinished RoM class
catalog and missing Manastorm fixtures still block unrelated repo-wide
build/test gates; those failures are not animation-pipeline regressions.
## Historical native animation rollout update
At the time of the original rollout, the contract was summarized as 268 base
combat actors: 267 native and one documented pose-only actor, with no configured
dynamic proxies. That base-actor summary included direct meshes plus exact
image-specific paperdoll assemblies. It mapped to 435 native entity templates
and one pose-only entity template. The authoritative present-day audit unit is
the 322 namespaced shipping variants described above.
On 2026-08-01 the native exporter's RuneWaker-to-HealerMan quaternion basis was
corrected from `(x, y, -z, w)` to `(-x, -y, z, w)`, the mapping implied by the
position reflection `S = diag(1, 1, -1)` and `R' = S R S`. All 29 generic
dungeon actor packages and the separate Forsaken Abbey package were rebuilt;
every package-level Khronos validation completed green. Pasper's Shrine's
`fog-ferocity-03` and `fog-loster-03` rigs received an additional rendered-pose
check against their runtime idle, run, and one-handed attack clips. Future
rollouts must include this rendered-pose gate because structural and clip-family
audits cannot detect a wrong but finite coordinate-basis conversion.
The paperdoll snapshot accounts for 81 unique source appearances across 17
container families; cross-dungeon packaging produces 93 namespaced variant
assets. Source composite-color evidence remains flagged on 32 packaged variants
until its mask layers receive a dedicated visual bake. This affects exact color
fidelity, not the recovered skeleton, skin, or animation clips.
Eight former “boss proxies” were also corrected during this pass. Their source
models are six invisible encounter FX controllers and two dungeon doors, not
missing creatures. They are now deferred mechanics objects instead of fake
combat objectives.
Use the live inventory, runtime-selector, readiness, and pose commands instead
of manually updating this historical table. See
[ORIGINAL_ANIMATION_IMPORT.md](./ORIGINAL_ANIMATION_IMPORT.md) and
[POSE_AUDIT.md](./POSE_AUDIT.md).
## Pre-pilot baseline outcome
All 30 packaged RuneWaker dungeon definitions pass the automated animation
audit. The 28 populated packages contain 4,094 spawn placements and 444 entity
definitions. The two copy-zone packages with no authoritative NPC rows are
reported as empty rather than silently populated.
Before the Pasper pilot, the preserved actor ROS conversions were authentic
static meshes: all 239 packaged actor GLBs contained zero skeletal skins and
zero native animation clips. HealerMan supplied procedural idle, locomotion,
attack/cast, wound, and death motion. Dynamic character/paperdoll containers
that export no triangles used explicit procedural proxy bodies.
The audit found and fixed two runtime defects:
1. The generalized population generator omitted the procedural animation mode
for zero-clip models. Those creatures received only reduced wrapper sway and
lacked procedural attack motion.
2. Procedural creatures did not receive woundRevision, so damage changed their
health but produced no hit reaction.
Both defects now have regression coverage in
src/game/runewakerDungeonAnimation.test.ts.
## Per-dungeon coverage
| Dungeon | Spawns | Entities | Actor GLBs | Static procedural | Proxy fallback | Result |
|---|---:|---:|---:|---:|---:|---|
| Aeternal Circle | 124 | 17 | 11 | 13 | 4 | PASS |
| Barren Caves | 48 | 7 | 7 | 7 | 0 | PASS |
| Cave Water Dragon | 97 | 7 | 7 | 7 | 0 | PASS |
| Demon Stronghold | 186 | 19 | 7 | 12 | 7 | PASS |
| Demon Stronghold 125 | 0 | 0 | 0 | 0 | 0 | PASS (empty) |
| Dungeon of Dalanis | 67 | 17 | 11 | 15 | 2 | PASS |
| Forsaken Abbey | 150 | 15 | 9 | 15 | 0 | PASS |
| Grafu Castle | 56 | 11 | 9 | 9 | 2 | PASS |
| Hall of Survivors | 162 | 40 | 29 | 40 | 0 | PASS |
| HOTO | 307 | 26 | 9 | 12 | 14 | PASS |
| Ice Dwarf Kingdom | 599 | 32 | 21 | 32 | 0 | PASS |
| Kalin's Shrine | 165 | 14 | 14 | 14 | 0 | PASS |
| Kal Turok Hive | 1 | 1 | 1 | 1 | 0 | PASS |
| Kawak's Tomb | 117 | 20 | 11 | 13 | 7 | PASS |
| Kulech Bones Nest | 154 | 16 | 13 | 16 | 0 | PASS |
| Lair of the Demon Dragon | 103 | 14 | 5 | 9 | 5 | PASS |
| Mystic Altar | 251 | 12 | 9 | 9 | 3 | PASS |
| Pasper's Shrine | 224 | 12 | 9 | 12 | 0 | PASS |
| Raksha Temple | 123 | 40 | 14 | 21 | 19 | PASS |
| Sand Vortex | 1 | 1 | 1 | 1 | 0 | PASS |
| Sardo Castle | 71 | 16 | 6 | 5 | 11 | PASS |
| The Origin | 188 | 26 | 13 | 22 | 4 | PASS |
| Tomb of the Seven Heroes | 241 | 26 | 8 | 9 | 17 | PASS |
| Treasure Trove | 497 | 21 | 6 | 7 | 14 | PASS |
| Warnorken Arena | 1 | 1 | 1 | 1 | 0 | PASS |
| Ystra Labyrinth Boss 1 | 3 | 3 | 3 | 3 | 0 | PASS |
| Ystra Labyrinth Boss 2 | 1 | 1 | 1 | 1 | 0 | PASS |
| Ystra Labyrinth Boss 3 | 1 | 1 | 1 | 1 | 0 | PASS |
| Zurhidon Stronghold | 156 | 28 | 3 | 5 | 23 | PASS |
| Zurhidon Stronghold 124 | 0 | 0 | 0 | 0 | 0 | PASS (empty) |
| **Total** | **4,094** | **444** | **239** | **312** | **132** | **30/30** |
## Reproduce
Run from `D:\Projects\HealerMan`, in this order after the completed actor
rebuild:
```powershell
npm run runewaker:audit:animation-inventory
npm run runewaker:audit:runtime-clips
npm run runewaker:audit:animation-readiness
npm run runewaker:audit:animation-readiness -- --json
npm run runewaker:audit:animations
npm run build
```
Then run the exact 322-variant pose command and human-review workflow in
[POSE_AUDIT.md](./POSE_AUDIT.md). The inventory and runtime commands write the
authoritative JSON/Markdown under `artifacts/animation-audit/`; retain them with
the pose batches so results cannot be accidentally mixed between cache
generations.
The baseline audit verifies configuration, GLB decoding, animation ownership,
finite transforms, and state coverage. Static procedural motion does not
reconstruct RuneWaker's original skeleton clips. Pasper's Shrine is now covered
by the native-animation tests and validator gate described above; the table is
retained as the pre-pilot rollout baseline.