2161 lines
135 KiB
Markdown
2161 lines
135 KiB
Markdown
# Healer Man playtest notes
|
||
|
||
This file is the durable record of runtime behavior, regressions, and the
|
||
evidence required before calling a visual bug fixed. Update it whenever scene,
|
||
camera, input, physics, mob-rendering, or asset-loading code changes.
|
||
|
||
## 2026-09-10 Personal UI templates and desktop action bars
|
||
|
||
- Opened Wailing Caverns through the normal offline roster, dungeon, and role
|
||
selection screens, then opened Pause > Edit UI & templates.
|
||
- Verified five bars containing 12 buttons each, including 2 x 6 and 3 x 4
|
||
arrangements. Default stacking accounts for each bar's height. The editor
|
||
can collapse or dock on either side so drag handles remain reachable.
|
||
- Clicked Renew and pressed Shift+Q in keybind edit mode. Reassigned Shift+Q
|
||
to bar 5/button 12 and verified the previous keybind cleared. Assigned Renew
|
||
to that button through the ability picker; after saving, Shift+Q cast it and
|
||
displayed its cooldown. No spell fired during key capture.
|
||
- Dragged the minimap, hid party frames, saved/renamed/overwrote PC slot 1,
|
||
loaded it, and round-tripped all layouts through export text and import.
|
||
The imported JSON retained the minimap position, hidden party, bar geometry,
|
||
ability assignment, key chord, and template name. Restoring a hidden widget
|
||
works, and Cancel discards that visibility edit.
|
||
- At a 390 x 844 viewport, the editor remained within the viewport and the
|
||
Save UI button was visible and 36 CSS pixels high. The in-app browser's
|
||
screenshot preview scales the page unusually at this override; DOM bounds
|
||
confirmed the editor was 310 CSS pixels wide. This was responsive browser
|
||
verification, not an Android hardware playtest.
|
||
- Evidence: `playtest-artifacts/ui-layout-desktop.png` and
|
||
`playtest-artifacts/ui-layout-phone-viewport.png`. Restored the offline UI
|
||
to defaults and removed the temporary template via import after testing.
|
||
- Automated coverage includes migration to six slots, owner isolation,
|
||
cloud upload/hydration into a separate device cache with a mocked endpoint,
|
||
malformed imports, key conflicts, and input precedence. No production
|
||
account credentials were used for the cloud round-trip test.
|
||
- `npm run build` and the focused 67-test suite passed. The development server
|
||
was restarted after an existing watcher hit EBUSY on generated web-bootstrap
|
||
assets during a concurrent build; no runtime UI error was logged in the
|
||
subsequent playtest.
|
||
|
||
## 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
|
||
|
||
- Added the grounded single-jump path for Space and controller L3, including a
|
||
`7.2 m/s` launch, `100 ms` coyote time, `120 ms` input buffering, landing
|
||
lockout, upward-normal ground filtering, and blocked-input cancellation.
|
||
Player physics and the latest grounded navigation anchor are now reported
|
||
separately, so party breadcrumbs and recalls do not follow an airborne
|
||
player position.
|
||
- Player locomotion now presents rising, falling, and landing phases. The live
|
||
WoW human used its native jump pose while preserving the visible body and
|
||
equipped weapon; RuneWaker and fallback clip selection is covered by the
|
||
focused animation suite.
|
||
- Party members now derive stable movement personalities from member ID and
|
||
living-party rank. The runtime applies personalized trail distance, lateral
|
||
offset, comfort slack, speed, slow sway, stop/start hysteresis, combat
|
||
bearing, preferred range, and ally separation only when the candidate path
|
||
passes collision and floor-continuity checks. Breadcrumb centerline routing,
|
||
Stop, stuck recovery, role decisions, and blocked-route reporting remain the
|
||
fallback behavior.
|
||
- Focused verification passed 17 files / 117 tests:
|
||
`playerJump`, `inputManager`, `inputMath`, `store`, `combatAnimation`,
|
||
`partyMovement`, `partyNavigation`, `partyPathing`, `partyRuntime`, and the
|
||
complete `src/avatar` suite. The first full-suite attempts exposed a
|
||
pre-existing load-sensitive `30 s` timeout in the heavyweight RuneWaker
|
||
animation audit; the isolated test passed in `6.5 s`. Its two asset-audit
|
||
cases now use `60 s`, matching their actual full-suite workload more closely.
|
||
- Final `npm test`: **114 files / 656 tests passed**. Final `npm run build`:
|
||
**passed**, including TypeScript, 954 transformed Vite modules, and the KTX2
|
||
audit of 11,839 compressed textures with zero fallbacks.
|
||
- Production preview was exercised at `http://127.0.0.1:4174/`. At desktop
|
||
`1440 x 900`, Space produced a visible jump from rest and while moving; the
|
||
running capture shows the native raised-arm jump pose. Space pressed while
|
||
paused did not launch on resume. Five rapid Space presses during one airborne
|
||
cycle returned to a normal grounded pose rather than producing a double jump.
|
||
The entrance smoke route covered its sloped floor and low cavern roof without
|
||
visible clipping or a hidden avatar.
|
||
- In Defend, the companions settled at visibly different longitudinal and
|
||
lateral offsets. In Attack, tank, ranged, and melee actors held distinct
|
||
bearings; Brynn peeled to the right while the other roles retained separate
|
||
safe positions. Party health and combat activity continued updating. Stop and
|
||
Recall were then issued from the Thor companion display and the authoritative
|
||
command state updated correctly.
|
||
- The browser Thor preview displayed both the `960 x 540` main surface and
|
||
`620 x 540` companion surface. Entering as healer from the companion display,
|
||
Attack/Stop/Recall dispatch, Space jumping on the main display, and
|
||
right-mouse input with no pointer lock all worked. Runtime inspection found
|
||
one visible canvas, no loading screen, and no scene-error overlay.
|
||
- Console capture contains no errors. It contains two occurrences of the
|
||
project's existing third-party initialization deprecation warning, one per
|
||
desktop/Thor runtime load. The Vite preview host separately logged the known
|
||
optional `/content/manifest.json` proxy refusal because the auxiliary content
|
||
server on port 4173 was not running; the packaged dungeon still loaded and
|
||
played normally.
|
||
- Evidence is under `playtest-artifacts/2026-08-16-jump-party/`:
|
||
`desktop-running-jump-preview.png`, `desktop-varied-follow-preview.png`,
|
||
`desktop-varied-combat-preview.png`, `desktop-pause-jump-blocked-preview.png`,
|
||
`thor-jump-preview.png`, `thor-varied-combat-preview.png`,
|
||
`thor-repeated-jump-landing-preview.png`, and `preview-console.txt`.
|
||
- Coverage limits: no physical controller was connected, so L3 edge behavior
|
||
and removal of L3 clear-target are automated-test verified rather than
|
||
hardware verified. The entrance smoke route did not provide a deterministic
|
||
walk-off ledge or narrow doorway fixture; exact coyote timing and lateral
|
||
centerline fallback remain covered by their pure/navigation tests rather than
|
||
claimed as live edge-case evidence.
|
||
|
||
## 2026-08-01 all-dungeon v5 animation acceptance pass - COMPLETE
|
||
|
||
- The Blackhorn Silencer and Giant Assassin failures demonstrated that valid
|
||
files, finite tracks, expected clip names, and green Khronos validation do not
|
||
prove a correct skeleton pose. The v4 exporter repair changed the reflected-Z
|
||
quaternion conversion from `(x, y, -z, w)` to `(-x, -y, z, w)`. The v5 cache
|
||
identity retains that repair and invalidates the actor cache for complete cast
|
||
semantics: all exported cast-family clips must be preserved and reachable by
|
||
the runtime selector.
|
||
- The authoritative scope is 30 dungeon packages, 436 entity templates, 268
|
||
base actor configurations, and 322 runtime-referenced namespaced shipping
|
||
variants. The audit and visual-review unit is the 322 variant paths, not the
|
||
268 base configurations. Expected configuration is 321 native variants plus
|
||
one pose-only Mantarick mapping (Hall of Survivors template `102452`, asset
|
||
`judgement-light-pose`).
|
||
- `demon-stronghold-125` and `zurhidon-stronghold-124` are authoritative empty
|
||
copy zones and require explicit zero-row review entries. Sardo Castle's Rune
|
||
Warning Device (template `105758`, asset `rune-device-red`) is a native,
|
||
stationary actor whose missing locomotion clip is an approved source-faithful
|
||
exception; its other native animation families still require review.
|
||
- Required machine checks, run from `D:\Projects\HealerMan`, start with:
|
||
|
||
```powershell
|
||
npm run runewaker:audit:animation-inventory
|
||
npm run runewaker:audit:runtime-clips
|
||
npm run runewaker:audit:animation-readiness
|
||
npm run runewaker:audit:animations
|
||
```
|
||
|
||
The exact PowerShell that derives all 322 GLB inputs from
|
||
`runtime-clip-coverage.json`, runs Blender, generates contact sheets and review
|
||
pages, and compiles the human disposition is documented in
|
||
`scripts/runewaker-pipeline/POSE_AUDIT.md`.
|
||
- Blender numerically samples the bind pose plus the first, middle, and final
|
||
frame of every action. This can miss a defect between samples and cannot prove
|
||
semantics, timing, impact alignment, particles, audio, or encounter mechanics.
|
||
Every variant contact sheet therefore requires human review; suspicious
|
||
actors require `--render-mode all`, and every dungeon still requires an
|
||
in-browser combat pass covering idle, applicable locomotion, configured
|
||
attacks/casts, wound, death, transitions, and console/WebGL errors.
|
||
- **Rebuild result:** All 29 generic population recipes rebuilt green. Forsaken
|
||
Abbey's separate nine-actor package completed Khronos validation with zero
|
||
errors and zero warnings across all nine GLBs.
|
||
- **Inventory/runtime result:** The final inventory is green at 30 dungeons, 436
|
||
entity templates, 268 base actor configurations, and 322 runtime-referenced
|
||
variants with zero blockers. Runtime semantic near misses are zero. The only
|
||
required-family exceptions are the documented pose-only Mantarick and the
|
||
native stationary Rune Warning Device with no locomotion.
|
||
- **Pose result:** `artifacts/animation-audit/post-v5/summary.json` evaluated
|
||
44,305 poses for all 322 variants: 282 numeric passes, 40 accepted-warning
|
||
candidates, zero errors, zero failures, and 634 flagged samples. Those values
|
||
exactly match the visually reviewed v4 batch totals, so the v5 cast-semantics
|
||
rebuild introduced no aggregate numeric pose regression.
|
||
- **Offline browser result:** The packaged/offline catalog displayed all 30
|
||
RuneWaker dungeons as Ready. Pasper's Shrine and Hall of Survivors both loaded
|
||
their environments. The console contained only an unrelated library
|
||
deprecation warning; no asset, skeleton, animation, WebGL, or dungeon-load
|
||
error was observed.
|
||
- **Test boundary:** All 19 focused RuneWaker animation tests pass. Repo-wide
|
||
build/test gates remain blocked by the unrelated unfinished RoM class catalog
|
||
and missing Manastorm fixtures; those failures are not attributed to the v5
|
||
animation work.
|
||
|
||
## 2026-08-01 Pasper goatman quaternion-basis repair
|
||
|
||
- Reproduced the severe animated-pose deformation on Giant Assassin (template
|
||
`101039`), Giant Assassin Captain (`101045`), and Blackhorn Silencer
|
||
(`101053`). The first two use
|
||
`model/character/creature/goatman/act_fog_ferocity_03.ros`; the Silencer uses
|
||
`model/character/creature/goatman/act_fog_loster_03.ros`.
|
||
- The source-to-HealerMan position conversion reflects Z. The exporter had
|
||
incorrectly mapped rotations as `(x, y, -z, w)`. Applying the basis transform
|
||
`R' = S R S`, with `S = diag(1, 1, -1)`, requires
|
||
`(-x, -y, z, w)`. The corrected conversion is shared by skeleton bind
|
||
transforms and every sampled animation frame.
|
||
- Rebuilt Pasper's nine actors and validated all nine shipping GLBs with zero
|
||
Khronos errors and zero warnings. Then rebuilt all 29 generic dungeon actor
|
||
packages plus the separately handled Forsaken Abbey package; every package
|
||
completed its actor and Khronos validation stage green.
|
||
- Blender pose evidence is under
|
||
`artifacts/animation-diagnostics/fog-ferocity-03-runtime-clips` and
|
||
`artifacts/animation-diagnostics/fog-loster-03-runtime-clips`. The exact
|
||
runtime-selected one-handed idle, run, `1h_attack01`, and `1h_attack02` clips
|
||
retain coherent bodies, limbs, armor, and weapons at their first, middle, and
|
||
final samples. The corresponding pre-fix directories preserve the malformed
|
||
poses for comparison.
|
||
- Pasper's Shrine loaded in the local browser and the party entered combat. The
|
||
browser console contained no model-load, skeleton, or animation exceptions.
|
||
The automated camera remained at the entrance while the ordered party moved
|
||
ahead, so no browser screenshot of these specific goatmen is claimed; the
|
||
actor-specific Blender renders are the visual regression evidence.
|
||
- Added `blender/render-animated-actor.py` and documented the required visual
|
||
pose gate. Clip presence, semantic-family coverage, finite tracks, and
|
||
Khronos-clean files are not sufficient evidence of correct skeletal motion.
|
||
|
||
## 2026-07-31 Pasper's Shrine original skeletal-animation pilot
|
||
|
||
- Replaced the nine static Pasper combat packages with skinned GLBs generated
|
||
from their original GR2 skeletons and ACT-referenced RAS controls.
|
||
- The actors expose 20-24 clips each. Generated entity data marks all 12 Pasper
|
||
templates as native; combat selection covers attack variations, cast, wound,
|
||
and death in addition to stand/idle, walk, and run.
|
||
- Khronos validation passed all nine shipping GLBs with zero errors and zero
|
||
warnings. The focused animation/runtime/pipeline suites passed 19 tests. The
|
||
final full run passed 513 of 518 tests; its five unrelated failing assertions
|
||
cover missing Manastorm conversion inputs plus established Forsaken/Kalin
|
||
availability state, and the unrelated Manastorm compound-import suite still
|
||
has its pre-existing parser error. The production TypeScript/Vite build passed.
|
||
- The local Vite entry started at http://127.0.0.1:5173/. The in-app browser
|
||
controller timed out during connection and after a clean reset, before a tab
|
||
or screenshot could be obtained. No live visual result is claimed in this
|
||
entry; an interactive Pasper combat pass remains the final visual gate.
|
||
- Reproduction and remaining-dungeon rollout instructions:
|
||
scripts/runewaker-pipeline/ORIGINAL_ANIMATION_IMPORT.md.
|
||
|
||
## 2026-07-31 RuneWaker all-dungeon animation audit
|
||
|
||
- Three parallel read-only audits covered all 30 packaged RuneWaker instances.
|
||
- All 239 actor GLBs parsed successfully and contain zero native clips/skins.
|
||
- All 312 static-model entity definitions now select full procedural animation;
|
||
132 dynamic-display entities use explicit procedural proxy bodies.
|
||
- Automated coverage opens every referenced GLB, resolves all 4,094 spawn
|
||
references, and exercises finite idle, movement, attack/cast, wound, and
|
||
terminal death transforms.
|
||
- The audit exposed and fixed the generalized generator's missing procedural
|
||
mode and the runtime wrapper's missing wound-revision handoff.
|
||
- Focused command: npm run runewaker:audit:animations.
|
||
- Live Vite boot succeeded at http://127.0.0.1:4173/. The Codex in-app browser
|
||
connection timed out twice before a tab could be selected, so no new WebGL
|
||
screenshots were captured in this pass. Do not treat the automated results
|
||
as screenshot evidence.
|
||
- Detailed matrix:
|
||
scripts/runewaker-pipeline/RUNEWAKER_ANIMATION_AUDIT.md.
|
||
|
||
## Evidence rules
|
||
|
||
- `npm test`, `npm run build`, Android compilation, and APK signing prove logic
|
||
or packaging only. They do **not** prove that the Three.js Canvas renders a
|
||
dungeon before or after pointer lock.
|
||
- A pointer-lock fix is not verified without matching screenshots from the
|
||
running game plus browser console/runtime checks.
|
||
- `assetStatus === "ready"` is not enough. `ProductionDungeon` latches that
|
||
status after an initial frame; a later camera or frame-loop failure can still
|
||
leave the HUD over the Canvas clear color.
|
||
- The Canvas clear color is `#07110d`. A nearly uniform dark-green playfield
|
||
with a normal DOM HUD means the app shell is alive but the 3D view is not
|
||
producing visible geometry.
|
||
- Record what was actually observed. Mark unavailable platforms and missing
|
||
screenshots as unverified rather than inferring success from another test.
|
||
|
||
## Source and staging safety
|
||
|
||
- Installed game root: `C:\Users\phenom\Documents\Healer-Man`
|
||
- Current writable mirror:
|
||
`C:\Users\phenom\Documents\wow335a\dungeon-export-work\HealerMan\gameplay-ui-staging`
|
||
- Treat `.healer-man-staging` and
|
||
`dungeon-export-work\HealerMan\runtime-staging` as stale historical mirrors.
|
||
They contain older pointer-input/camera files and must not be bulk-copied over
|
||
the game.
|
||
- Before the pointer-lock transition patch on 2026-07-21, installed
|
||
`PlayerRig.tsx` matched the gameplay UI mirror at
|
||
SHA-256 `B918B24031DD7031F1EEBA75879E8291EABDE9AAB8A08223B9B392A105B4692A`.
|
||
Installed `inputManager.ts` matched the pre-patch mirror at SHA-256
|
||
`16D77BF075BD1355A23F81D019B8D34C7427026B113DBD257B4A7BE6FE53BF1F`.
|
||
- After the transition patch, the installed and staged hashes match:
|
||
`PlayerRig.tsx` is
|
||
`A2CD3D3951D99ECE05D99ACB3CAE53C412B075B01106DBAC0E37EC48B8AFC843` and
|
||
`inputManager.ts` is
|
||
`355A4AD7DE12AF777B4829428B32181F9511A8DF021102932036DAA643C3C716`.
|
||
- Compare source and destination hashes before and after every elevated copy.
|
||
Copy only the files intentionally changed. The installed root currently has
|
||
no Git history to rescue an accidental stale overwrite.
|
||
|
||
## Pointer-lock invariants that must remain intact
|
||
|
||
1. `GameScene.tsx` requests pointer lock on the Canvas itself.
|
||
2. `inputManager.ts` rejects non-finite mouse movement, clamps each event and
|
||
frame, clears the buffer on focus changes, and suppresses the complete
|
||
180 ms cursor-recentering burst after pointer lock begins.
|
||
3. `PlayerRig.tsx` repairs non-finite yaw, pitch, player translation, cast
|
||
distance, and camera boom state before they reach Three.js or Rapier.
|
||
4. `ThirdPersonCamera` uses the default `useFrame` priority. A positive priority
|
||
takes ownership of React Three Fiber's render loop; without an explicit
|
||
`gl.render(scene, camera)` call it produces the exact clear-color-plus-HUD
|
||
failure.
|
||
5. Errors thrown from a `useFrame` callback are not reliably surfaced by the
|
||
DOM `SceneErrorBoundary`. Browser `pageerror` and console capture are part of
|
||
the playtest, especially after adding new frame callbacks.
|
||
|
||
## Deterministic PC setup
|
||
|
||
Run the latest source, not an old Vite process or stale `dist` directory:
|
||
|
||
```powershell
|
||
npm run dev -- --host 127.0.0.1 --port 4173 --strictPort
|
||
```
|
||
|
||
Open `http://127.0.0.1:4173/` at `1440 x 900`. For a repeatable offline
|
||
character, run this in DevTools before reloading:
|
||
|
||
```js
|
||
const now = Date.now();
|
||
localStorage.setItem("healer-man.profile-database.v1", JSON.stringify({
|
||
version: 1,
|
||
accounts: [],
|
||
rosters: {
|
||
"offline-roster": [{
|
||
id: "character-playtest",
|
||
ownerId: "offline-roster",
|
||
name: "Remedy",
|
||
raceId: "human",
|
||
classId: "priest",
|
||
gender: "female",
|
||
appearance: { skinColor: 0, face: 0, hairStyle: 0, hairColor: 0, feature: 0 },
|
||
level: 10,
|
||
experience: 0,
|
||
talentRanks: {},
|
||
location: "Wailing Caverns Entrance",
|
||
createdAt: now,
|
||
lastPlayedAt: now,
|
||
}],
|
||
},
|
||
}));
|
||
sessionStorage.setItem("healer-man.session.v1", JSON.stringify({
|
||
kind: "offline",
|
||
ownerId: "offline-roster",
|
||
displayName: "Offline",
|
||
}));
|
||
location.reload();
|
||
```
|
||
|
||
## Required pointer-lock visual checklist
|
||
|
||
Store evidence under `playtest-artifacts/2026-07-21/` for this regression.
|
||
|
||
1. Select Remedy, click **Enter world**, and wait until `.loading-screen` is
|
||
gone and `.scene-shell canvas` is visible.
|
||
2. Confirm textured dungeon geometry is visible, not only `#07110d`.
|
||
3. Record pre-lock state: `assetStatus` is `ready`, `pointerLocked` is `false`,
|
||
and `playerPosition` plus `cameraYaw` are finite.
|
||
4. Capture the full window as `pointer-lock-before.png` and the Canvas crop as
|
||
`pointer-lock-before-canvas.png`.
|
||
5. Click the center of `.scene-shell`. Confirm
|
||
`document.pointerLockElement === document.querySelector(".scene-shell canvas")`.
|
||
6. Wait two animation frames and at least 500 ms. Confirm `pointerLocked` is
|
||
`true`, player/camera values remain finite, the WebGL context exists, and
|
||
`gl.isContextLost()` is `false`.
|
||
7. Capture the same views as `pointer-lock-after.png` and
|
||
`pointer-lock-after-canvas.png`.
|
||
8. Move the mouse, then hold `W` for about 250 ms. Capture
|
||
`pointer-lock-after-input.png`. This is required because a bad recenter event
|
||
can fail on the first post-lock input rather than on the click itself.
|
||
9. Press Escape, open and close a menu, reacquire pointer lock, and confirm the
|
||
dungeon remains visible.
|
||
10. Save console output as `pointer-lock-console.txt`. The pass condition is no
|
||
`console.error`, `pageerror`, `pointerlockerror`, or `webglcontextlost`
|
||
during the transition.
|
||
|
||
Visual pass criteria: all three full-window images show textured dungeon
|
||
geometry behind the HUD; the two post-lock images show a reticle; no loading or
|
||
scene-error overlay is present; the view changes after input without becoming
|
||
uniform dark green.
|
||
|
||
After the development-server pass, repeat against a fresh production build:
|
||
|
||
```powershell
|
||
npm run build
|
||
npm run preview -- --host 127.0.0.1 --port 4174 --strictPort
|
||
```
|
||
|
||
Use filenames ending in `-preview` for the production screenshots.
|
||
|
||
## Known evidence as of 2026-07-21
|
||
|
||
### Working or previously observed working
|
||
|
||
- Login/offline roster, character selection, and entering Wailing Caverns have
|
||
been observed working by the user.
|
||
- Before this regression, the user could see and navigate the dungeon and give
|
||
camera-clipping, pop-in, wall-material, mob, and performance feedback. This
|
||
proves that the extracted dungeon and runtime can render on this PC.
|
||
- The current source contains pointer-delta sanitization tests and finite camera
|
||
recovery guards.
|
||
- After the transition patch, `npm test` reported 109/109 tests passing and
|
||
`npm run build` completed successfully. An Android APK had been produced by
|
||
the preceding build, but has not yet been rebuilt from this patch.
|
||
- `scripts/probe-entrance.mjs` reported finite entrance camera geometry and a
|
||
visible shell hit. That static probe does not exercise React, pointer lock, or
|
||
the live frame loop.
|
||
|
||
### Not working or not yet verified
|
||
|
||
- User report: after entering Wailing Caverns, clicking the game to take focus
|
||
changes the 3D view to dark green while the HUD remains visible.
|
||
- No current before/after screenshots have yet demonstrated that the latest
|
||
source survives pointer lock. Until the required screenshots exist, this
|
||
regression remains open regardless of tests/build status.
|
||
- Browser console and WebGL context-loss evidence for the failing transition
|
||
has not yet been captured.
|
||
- The production preview answered HTTP 200 at `http://127.0.0.1:4174/`, but the
|
||
visual-test browser was not attached to this session. No screenshot was
|
||
captured, so the patch must not be called visually verified yet.
|
||
- The pointer-lock regression has not been visually rechecked in production
|
||
preview, the Android WebView, or the AYN Thor top display.
|
||
|
||
## Regression log
|
||
|
||
### HM-2026-07-21-POINTERLOCK-CLEARCOLOR - PATCHED, VISUAL VERIFICATION REQUIRED
|
||
|
||
**Reported:** 2026-07-21
|
||
|
||
**Symptom:** The dungeon is visible after character selection. Clicking the game
|
||
window to take focus leaves a dark-green Canvas with the UI still visible.
|
||
|
||
**Expected:** Pointer lock activates mouse look and the textured dungeon remains
|
||
visible and navigable.
|
||
|
||
**Important history:** Two earlier failure classes can create this symptom:
|
||
|
||
- A positive `useFrame` render priority can disable React Three Fiber's
|
||
automatic render call.
|
||
- A stale or malformed pointer-lock movement event can poison orbit/camera
|
||
state with non-finite values.
|
||
|
||
The prior input guard discarded only one transition event. Browsers can emit a
|
||
burst of recentering events, so later stale deltas could still rotate the camera
|
||
away from the rendered cavern. The patch discards the full 180 ms transition
|
||
burst and reads `pointerLocked` imperatively in the player frame, avoiding a
|
||
Rapier subtree reconciliation at lock acquisition. This is the leading cause,
|
||
but it remains a hypothesis until the required screenshots and runtime evidence
|
||
are captured. Recent mob/combat work also added more high-frequency `useFrame`
|
||
paths; an exception or WebGL context loss can create the same visible symptom.
|
||
|
||
**Patch files:** `src/game/inputManager.ts`,
|
||
`src/game/inputManager.test.ts`, `src/scene/PlayerRig.tsx`.
|
||
|
||
**Automated evidence:** 17 test files and 109 tests passed. The TypeScript/Vite
|
||
production build completed with 655 modules transformed. These results validate
|
||
the patch logic and bundle, not the rendered pointer-lock transition.
|
||
|
||
**Visual evidence status:** blocked on an attached visual-test browser. The
|
||
local production preview is running and ready for the checklist above; no
|
||
screenshots exist yet.
|
||
|
||
**Fix evidence required:** `pointer-lock-before.png`,
|
||
`pointer-lock-after.png`, `pointer-lock-after-input.png`, their Canvas crops,
|
||
`pointer-lock-console.txt`, finite runtime state, and a live WebGL context. Add
|
||
the exact root cause, changed files, commands, and screenshot hashes here once
|
||
verified.
|
||
|
||
### HM-2026-07-22-CAVERN-WHITE-CONTEXT - PATCHED, PC DEV/PRODUCTION VISUAL PASS
|
||
|
||
**Reported:** 2026-07-22, PC development runtime
|
||
|
||
**Symptom:** Wailing Caverns renders correctly, then the screen turns white.
|
||
|
||
**Expected:** The textured cavern, player, mobs, and HUD remain visible after
|
||
the first rendered frame and while pointer lock is active.
|
||
|
||
**Source diagnosis:** No application DOM layer, loading state, error state, or
|
||
Canvas clear color is white. The development root was wrapped in React
|
||
`StrictMode`; the installed R3F Canvas teardown schedules a forced WebGL
|
||
context loss after 500 ms, making the development-only effect replay a strong
|
||
timing match. No live context-loss event was captured, so this remains the
|
||
leading code-path diagnosis rather than visual proof. Two independent scene
|
||
lifecycle gaps were also confirmed: player physics could start while the
|
||
dungeon collider was still suspended, and the prior ready signal used the
|
||
renderer-global frame count rather than a post-mount dungeon frame.
|
||
|
||
**Patch:** The game root now mounts once in development. `GameScene` listens
|
||
for WebGL context loss/restoration, releases pointer lock, pauses simulation,
|
||
and displays a dark DOM recovery surface instead of leaving a blank Canvas.
|
||
Three's automatic restoration preserves the current Rapier world. If automatic
|
||
recovery fails, the explicit restart returns to the entrance and remounts at
|
||
DPR 1 with antialiasing and shadows disabled. The player and mob assets continue
|
||
preloading behind the loading surface, but the entire physics world and mob
|
||
simulation remain paused until the current dungeon/collider instance has
|
||
completed a rendered frame. This prevents a fall-through race without causing
|
||
a late GPU-upload burst at the first visible cavern frame.
|
||
|
||
**Files changed:** `src/main.tsx`, `src/scene/GameScene.tsx`,
|
||
`src/scene/DungeonEnvironment.tsx`, `src/scene/ProductionDungeon.tsx`, and
|
||
`src/styles.css`.
|
||
|
||
**Automated evidence:** 23 test files and 136 tests passed. The TypeScript/Vite
|
||
production build completed with 662 modules transformed. The entrance probe
|
||
reported finite camera geometry, a 6.099 m camera-to-target distance, and no
|
||
camera-to-target collision. The creature audit validated all 16 GLBs. The live
|
||
development server returned HTTP 200 for the page and updated scene module and
|
||
served both the recovery UI and readiness gate.
|
||
|
||
**Visual evidence status (updated 2026-07-22):** Edge/Chromium was attached at
|
||
1440x900 through Playwright. A fresh offline character entered the development
|
||
runtime and the rebuilt production preview; both showed textured Wailing
|
||
Caverns after a 12-second load/stability wait and remained rendered throughout
|
||
party-command and pause-menu checks. The post-entry captures had no `pageerror`
|
||
or console error. The original post-load white frame was not reproduced.
|
||
Native pointer lock, Android WebView, and the AYN Thor displays remain separate
|
||
unverified surfaces and must not be inferred from this pass.
|
||
|
||
### HM-2026-07-26-AVATAR-EQUIPMENT-RIGHT-DRAG - FIXED, PC VISUAL PASS
|
||
|
||
**Reported:** Playable character models and weapon/gear presentation had
|
||
stopped appearing as expected. Desktop right-mouse camera look also triggered
|
||
the browser's jarring Pointer Lock capture transition.
|
||
|
||
**Root cause:** The July 25 authentic-equipment integration left
|
||
`starterWeapons.tsx` and its tests in place but disconnected
|
||
`StarterWeaponAttachments` and `ApproximateStarterEquipment` from the shared
|
||
`CharacterModel`. As a result, valid character rigs rendered bare in the roster
|
||
and dungeon. Authentic item GLBs were also loaded inside the character's
|
||
top-level Suspense/error boundary, so one slow or broken optional gear model
|
||
could temporarily replace its entire wearer. Character-manifest loading used
|
||
one all-or-nothing `Promise.all`, allowing one optional race pack failure to
|
||
prevent every otherwise-valid race from resolving.
|
||
|
||
The camera transition was intentional browser behavior caused by
|
||
`GameScene.tsx` calling `requestPointerLock()` on every right-button press. The
|
||
browser controls that transition; it cannot be styled away.
|
||
|
||
**Fix:** The shared character renderer once again portals class-appropriate
|
||
starter weapons into the animated hand bones and supplies approximate gear on
|
||
loading/error fallbacks. Authentic client item models replace starter gear only
|
||
for their occupied hand. Each optional item model now owns an independent
|
||
Suspense and `AvatarErrorBoundary`, with the matching starter item as its local
|
||
fallback, so it cannot hide the body or unrelated gear. Character packs load
|
||
independently and merge whichever valid manifests are available.
|
||
|
||
Desktop camera look now uses bounded ordinary cursor deltas only while the
|
||
right button is held. It ends on release, lost pointer capture, blur, overlay
|
||
opening, or teardown. The normal gameplay path contains no
|
||
`requestPointerLock()` call, so no browser mouse-capture transition is invoked.
|
||
Without Pointer Lock, camera rotation naturally stops at the physical browser
|
||
window edge; the player can release, reposition the cursor, and continue.
|
||
|
||
**Regression protection:** Root `AGENTS.md` now makes the character/equipment
|
||
boundaries and popup-free right-drag behavior mandatory. New tests pin the
|
||
shared renderer integration, independent manifest failure behavior, occupied
|
||
hand replacement, per-item loading/error isolation, and unlocked right-drag
|
||
deltas. Existing asset audits still verify every playable rig, hand bone,
|
||
native equipment GLB, and texture.
|
||
|
||
**Automated evidence:** Focused avatar/input/store/respawn coverage passed 11
|
||
files and 53 tests. The complete suite passed 81 files and 504 tests. TypeScript
|
||
and Vite production build passed with 750 modules transformed. Because this
|
||
workspace is iCloud-synced, Vite now retains old hashed output instead of
|
||
recursively emptying `dist`; this avoids iCloud restoring an asset during
|
||
cleanup and causing `ENOTEMPTY`.
|
||
|
||
**Visual evidence:** The live 1440x720 PC development runtime showed the female
|
||
Human Priest body and staff in the roster, then the player plus four distinct
|
||
party character bodies and equipped silhouettes in textured Wailing Caverns.
|
||
An ordinary right-click produced no Pointer Lock prompt or scene transition,
|
||
and no application console error, avatar warning, or WebGL context loss was
|
||
captured. The one console warning was the existing third-party initialization
|
||
deprecation. Evidence:
|
||
|
||
- `playtest-artifacts/2026-07-26-model-input/roster-character-staff.png`
|
||
- `playtest-artifacts/2026-07-26-model-input/dungeon-equipped-party.png`
|
||
- `playtest-artifacts/2026-07-26-model-input/right-click-no-popup.png`
|
||
|
||
The browser-control surface can issue an atomic right-click but cannot hold the
|
||
right button while moving. Continuous drag rotation is therefore covered by
|
||
the input integration test; final feel across long drags remains a short manual
|
||
PC check.
|
||
|
||
## Entry template
|
||
|
||
```text
|
||
ID / status:
|
||
Date and platform:
|
||
Source/build identifier:
|
||
Observed symptom:
|
||
Root cause:
|
||
Files changed:
|
||
Commands and results:
|
||
Screenshots and hashes:
|
||
Console/runtime evidence:
|
||
Remaining unverified platforms:
|
||
```
|
||
|
||
## Gameplay implementation log
|
||
|
||
### HM-2026-07-21-COMBAT-PARTY-TALENTS - IN PROGRESS
|
||
|
||
**Requested:** Replace generic talent text with the local 3.3.5 talent text and
|
||
make learned talents affect gameplay; make Psychic Scream fear nearby enemies
|
||
for eight seconds; respawn a defeated player at the dungeon entrance; link
|
||
pack aggro; add one tank and three DPS companions; and play attack/death
|
||
animations for creatures.
|
||
|
||
**Authoritative local-data finding:** The extracted `Spell.dbc` contains the
|
||
talent names and descriptions. The generator was reading the standard string
|
||
field offsets, but this client uses a custom 239-field schema with six fields
|
||
inserted before the localized string blocks. The missing names were a parser
|
||
bug, not missing client assets.
|
||
|
||
**Combat-pool finding:** The current health, mana, XP, and combat-power curves
|
||
are explicitly prototype curves. Mana classes currently use a 100-point
|
||
percentage-style pool; these numbers are not exact 3.3.5 character-sheet
|
||
values. The client export was checked for base HP/MP tables, but those
|
||
server-side character-stat tables are not present in the resolved MPQ view.
|
||
Replacing the prototype pools accurately will require the matching 3.3.5
|
||
server database (class-level and race/class-level stats), plus the eventual
|
||
gear/stat model; they must not be presented as authentic yet.
|
||
|
||
**Staged and focused-tested so far:** Psychic Scream uses an eight-yard radius
|
||
and eight-second fear; hostile control starts combat; pulling any authored
|
||
`pack:member` wakes its surviving packmates; and death exits pointer lock and
|
||
resets the encounter/player position to the entrance. Full installed-project
|
||
tests, build, screenshots, and animation/party verification remain required
|
||
before this entry can be marked complete.
|
||
|
||
**Creature-animation finding:** All 16 browser creature GLBs had previously
|
||
been reduced to Stand and Walk by `prepareAnimatedCreatures.mjs`; the source
|
||
files were not generally missing. Eleven source creature exports also contain
|
||
exact `AttackUnarmed (ID 16 variation 0)` and `Death (ID 1 variation 0)` clips,
|
||
which are now restored in the staged browser assets. The five composite
|
||
humanoids (`druid-of-the-fang`, `lady-anacondra`, `lord-cobrahn`, `lord-pythas`,
|
||
and `lord-serpentis`) were themselves exported with animation IDs 0 and 4 only,
|
||
so they use bounded procedural attack and one-shot terminal death poses.
|
||
|
||
**Animation/fear staged behavior:** Attack clips resolve while an engaged mob is
|
||
in its attacking phase. Death has priority, plays once, clamps on its last
|
||
frame, preserves the corpse's combat position, and stops both mixer and proxy
|
||
root updates once settled. Active fear suppresses attack visuals and steers the
|
||
mob away from the player on the dungeon plane; stun/root still lock movement,
|
||
slows still apply, and the flee position is clamped to the mob's home leash.
|
||
The existing 95-unit population activation gate remains in place.
|
||
|
||
**Animation automated evidence:** The Three.js GLTF loader audit parsed all 16
|
||
staged GLBs and found 11 exact combat-clip models plus five explicit fallbacks.
|
||
The staging TypeScript app/node configurations passed `--noEmit`; the complete
|
||
Vitest suite passed 22 files and 131 tests using the staging-safe config loader.
|
||
This is logic/asset evidence only. Installed-project build, combat screenshots,
|
||
and live attack/death/fear observation remain required.
|
||
|
||
**Talent-data result:** The corrected custom-schema parser regenerated all 829
|
||
talent nodes and 2,243 rank spells from this client's DBC files. Visible names
|
||
and rank descriptions contain no generic fallbacks or unresolved tooltip
|
||
tokens. The talent panel shows both the learned rank and the next rank; the
|
||
SpellRadius table resolves values such as Circle of Healing's 15-yard radius.
|
||
All exact raw rank-effect metadata remains available to runtime systems.
|
||
|
||
**Talent-runtime coverage boundary:** 460 of 829 nodes currently yield at least
|
||
one common scalar modifier (damage, healing, mitigation, pools, regeneration,
|
||
cost, crit/haste, cast/cooldown, attributes, armor, range, duration, or threat).
|
||
This is partial coverage, not proof that every conditional clause or proc is
|
||
simulated. The other 369 nodes require triggered-spell, aura/proc, summon,
|
||
weapon-event, form, or active-ability systems. There are 151 one-rank
|
||
active/spell-granting rows. Faithful generic activation also needs DBC cost,
|
||
cast-time, range, and trigger payload generation plus friendly/party/dual
|
||
targeting metadata; the baseline action set now distinguishes hostile, friendly,
|
||
and self targets.
|
||
|
||
**Implemented scalar behavior:** Learned scalar modifiers are cached and now
|
||
feed max health/resource (including Stamina/Intellect), regeneration, costs,
|
||
direct and periodic damage/healing, shields, incoming mitigation, cast time,
|
||
cooldowns/groups, haste/GCD, range/AoE, and status/shield duration. Focused
|
||
tests prove concrete rank changes for Improved Frostbolt, Improved Fire Blast,
|
||
Twin Disciplines, Divinity, Convection, and Fel Vitality (21/21 passed).
|
||
Conditional/proc/stance clauses are not statefully triggered yet; crit uses a
|
||
deterministic expected-value benefit; armor is approximated; threat, flat-point
|
||
cost reductions, added periodic ticks, and learned active spells remain outside
|
||
this scalar layer.
|
||
|
||
**Party staged behavior:** A stable character-seeded roster now creates exactly
|
||
four AI companions: one Protection Warrior, Blood Death Knight, or Protection
|
||
Paladin tank and three unique non-tank DPS specs. All four attack an engaged
|
||
enemy. While alive, the tank redirects 70% of incoming health damage and can be
|
||
downed. PC frames are clickable; Thor frames are touch-selectable; D-pad
|
||
Up/Down cycles living allies. Baseline direct heals and healing-over-time spells
|
||
now route to a selected living ally, with the player as the no-selection fallback.
|
||
|
||
**Screenshot status (superseded 2026-07-22):** The first browser query exposed
|
||
no in-app backend, but an installed Edge executable was later attached through
|
||
Playwright. Current party/world evidence is recorded in the entry below. Native
|
||
pointer-lock, Android, and Thor checks remain outstanding.
|
||
|
||
**Installed-project verification:** The integrated project passed 23 test files
|
||
and 136 tests. The creature audit loaded all 16 GLBs (11 real combat-clip sets,
|
||
five procedural fallbacks). TypeScript and Vite production build passed with
|
||
662 modules transformed, and the live preview returned HTTP 200 for the new
|
||
bundle. Vite reports existing large-chunk warnings; this is a startup/bundle
|
||
optimization item, not a failed build.
|
||
|
||
**Thor/Android artifact from the preceding combat build:** `npm run android:apk`
|
||
completed after a fresh Capacitor sync and 98 Gradle tasks. Artifact:
|
||
`android/app/build/outputs/apk/debug/healer-man-0.1.0-debug.apk`, 108,315,663
|
||
bytes, SHA-256
|
||
`77B2BB53BD21FAA799F5BE15FE722399FB03B33983512BE8647694C9B5C5845B`.
|
||
This artifact predates the party-world command changes below.
|
||
|
||
### HM-2026-07-22-PARTY-WORLD-COMMANDS - IMPLEMENTED, PC VISUAL PASS
|
||
|
||
**Requested:** Make the four roster allies visible in the world; add Attack,
|
||
Defend, and Stop orders; make Attack advance toward the next boss while clearing
|
||
adds, Defend respond only to engaged enemies, and Stop hold the current world
|
||
positions; add pause-menu party management with current and future talents;
|
||
keep every ally at the player's level.
|
||
|
||
**Implementation:** Party command and boss-objective state now lives in the
|
||
low-frequency party store. Four procedural world actors keep their positions in
|
||
a render-loop registry, follow formation in Defend, freeze in Stop, approach
|
||
active targets at melee/ranged distance, and use the shipped Wailing Caverns
|
||
navigation GLB plus deterministic A* routing in Attack. A soft player tether
|
||
keeps the existing player-centric mob activation/leash system coherent; Stop is
|
||
exempt so it remains a literal hold order. Navigation loading is isolated behind
|
||
its own Suspense and error boundary, so an optional route-helper failure cannot
|
||
blank or suspend the dungeon Canvas.
|
||
|
||
**Interface:** The PC HUD exposes Attack/Defend/Stop with F1/F2/F3 shortcuts and
|
||
pressed state. The pause hub opens Party Management, where the four allies,
|
||
roles, live health/status, current legal talent ranks, and next three automatic
|
||
level choices are visible. The Thor companion snapshot and tactical panel expose
|
||
the same commands and named boss objective. World nameplates are hidden while a
|
||
menu is open, fixed at a small screen size, and stacked beneath the HUD.
|
||
|
||
**Automated evidence:** The full suite passed 28 files and 155 tests. New focused
|
||
coverage includes command acquisition/holding/range, deterministic roster level
|
||
sync, world-position registry and movement helpers, navigation welding/A*, all
|
||
22 supported specialization plans at every level 1-80, F-key mapping, and
|
||
dual-screen command dispatch. The final TypeScript/Vite build transformed 669
|
||
modules and emitted the 1,329.06 kB navigation GLB. The existing large-chunk
|
||
warning remains informational.
|
||
|
||
**Visual evidence:** At 1440x900 in the live development runtime, all four
|
||
companions and the command bar were visible over textured Wailing Caverns.
|
||
Attack moved the group into the entrance encounter and party/player health plus
|
||
mob health changed without `pageerror` or console errors. Stop appeared as the
|
||
selected HUD order, and all four members showed `HOLDING` in Party Management.
|
||
The level-1 panel showed future level-10/11/12 choices; the seeded level-10
|
||
production panel showed the current rank and level-11/12/13 choices. A first
|
||
capture exposed oversized nameplates leaking over the modal; the nameplates were
|
||
then reduced, placed below the HUD, hidden while paused, and the corrected dev
|
||
and production panels were recaptured cleanly. Fresh production entry remained
|
||
textured after 12 seconds with a Canvas present and zero post-entry console or
|
||
page errors.
|
||
|
||
**Remaining verification boundary:** The entrance encounter and menu flow were
|
||
visually exercised, but a complete manual walk through every boss route was not.
|
||
Late-dungeon navigation islands, native pointer lock, Android/Thor rendering,
|
||
and the full boss-by-boss Attack traversal remain manual follow-up coverage.
|
||
|
||
### HM-2026-07-22-FRIENDLY-TARGETING - IMPLEMENTED, PC INTERACTION PASS
|
||
|
||
**Requested:** Let the player mouse-click party members in the world or party
|
||
frames and use healing/support abilities on the selected teammate.
|
||
|
||
**Implementation:** Living world companions now have generous transparent
|
||
capsule hit targets. Their click handler stops both R3F and native DOM bubbling,
|
||
so selecting an ally does not also capture the mouse. Hostile and friendly
|
||
selection are mutually exclusive across world clicks, keyboard/controller
|
||
cycling, clear-target input, and the Thor companion channel. Party selection is
|
||
idempotent and clears automatically if the member is downed or removed.
|
||
|
||
Holy Light, Flash Heal, Healing Wave, and Rejuvenation now use 40-yard friendly
|
||
targeting. With no ally selected they intentionally target the player. Casts
|
||
snapshot the chosen recipient, revalidate that member's life, runtime presence,
|
||
and range on completion, and never put party IDs into hostile-target state.
|
||
Direct heals and per-recipient HoTs update party health without changing the
|
||
self-healing behavior of hostile hybrid attacks such as Death Strike.
|
||
|
||
**Interface:** A selected teammate gets the existing gold world/party-frame
|
||
selection treatment plus a green target frame with live health. Friendly action
|
||
slots carry an `ALLY` badge and accessible target wording.
|
||
|
||
**Evidence:** At 1440x900 in Edge/Playwright, clicking Garrick's party frame
|
||
selected him and left pointer lock off. Flash Heal displayed its cast bar,
|
||
restored Garrick from 157/217 to 217/217, and spent mana. Clicking Ash's actual
|
||
3D body switched both the target frame and selected party frame to Ash while
|
||
pointer lock remained off. The textured dungeon Canvas and all four companions
|
||
remained visible; no page error or white-screen regression occurred. The full
|
||
suite passed 28 files and 169 tests with a 15-second allowance for the existing
|
||
performance-heavy talent-plan audit. TypeScript and the production Vite build
|
||
passed with 669 modules transformed.
|
||
|
||
### HM-2026-07-22-PARTY-AVATARS - IMPLEMENTED, PC VISUAL PASS
|
||
|
||
**Requested:** Replace the four lightweight companion pawns with actual
|
||
characters that have races, genders, and randomized appearances.
|
||
|
||
**Implementation:** Every generated party member now owns a flat, serializable
|
||
`raceId`, `gender`, and five-value appearance record. Identity uses a dedicated
|
||
per-member PRNG stream keyed by the persistent player-character ID, party slot,
|
||
class, and specialization. It is varied between player characters but stable
|
||
across rerenders, level synchronization, combat resets, and re-entry. The race
|
||
selection respects the project's packed race/class catalog.
|
||
|
||
Party actors now use the same `CharacterModel` pipeline as the player: shipped
|
||
race/gender GLBs, skeleton-safe clones, composed skin/face/hair/feature textures,
|
||
Death Knight eye treatment, and Stand/Run animation. Each ally retains its own
|
||
Suspense/error boundary and procedural fallback, so one bad avatar cannot blank
|
||
the dungeon Canvas. Measured metrics for all 20 race/gender rigs drive each
|
||
nameplate, target ring, and transparent click capsule; this covers the 1.17 m
|
||
female Gnome through the 3.19 m male Troll. Party frames, target UI, pause-menu
|
||
management, and the Thor snapshot now expose race/gender identity.
|
||
|
||
**Asset evidence:** A direct loader audit covered all 20 character GLBs and
|
||
5,072 referenced model/texture URLs with zero missing files. Every rig had
|
||
finite geometry and animation tracks, matching appearance counts, required
|
||
material tokens, and valid Stand/Walk/Run clips.
|
||
|
||
**Visual evidence:** At 1440x900 in Edge/Playwright, the initial seeded party
|
||
rendered distinct Draenei, Night Elf, and Dwarf characters with visible body,
|
||
skin, hair, and feature differences. A second deterministic extreme party
|
||
rendered a male Troll, male Draenei, male Human, and female Gnome together.
|
||
There were no avatar loader warnings, page errors, WebGL context-loss reports,
|
||
or white-screen recurrence. Clicking the real Troll mesh selected Seraphin,
|
||
updated the green friendly target frame, and left pointer lock off. Party
|
||
Management displayed all four race/gender identities and preserved talent data.
|
||
|
||
**Automated evidence:** TypeScript passed. The full suite passed 28 files and
|
||
171 tests, including deterministic identity, valid appearance ranges, reset
|
||
stability, combat routing, and dual-screen propagation.
|
||
|
||
**Remaining boundary:** The shipped playable rigs currently provide the base
|
||
body/underwear, facial customization, and locomotion clips, but not equipped
|
||
armor/weapons or skeletal attack/death clips. The existing transform-based
|
||
attack/down motion remains. Android/Thor GPU performance with five animated
|
||
character rigs remains a separate native-device verification pass.
|
||
|
||
### HM-2026-07-22-CONTROLLER-ACTION-BINDINGS - IMPLEMENTED, AUTOMATED/NATIVE PASS
|
||
|
||
**Requested:** Replace the four-slot action bar with a complete controller
|
||
layout: Triangle/Circle/Cross/Square in their physical diamond, R1/R2, D-pad
|
||
Left/Right, L1 and L2 modifier layers, and a player-configurable binding menu.
|
||
|
||
**Implementation:** The combat runtime now owns 24 stable action bindings:
|
||
eight physical controls across Base, L1, and L2. Browser gamepads, the Android
|
||
controller bridge, and keyboard 1-8 with Shift/Alt all resolve through the same
|
||
semantic binding model. Modifier press/release ordering prevents a fast
|
||
L1/L2 transition from casting on a stale layer; native triggers use fallback
|
||
axes plus press/release hysteresis. Android system Back is distinct from Circle,
|
||
so it pauses gameplay or backs out of menus without firing a Circle ability.
|
||
|
||
**Interface:** Only the active eight-slot layer is shown over the playfield.
|
||
The four face buttons form the controller diamond, with separate shoulder and
|
||
horizontal D-pad groups. The pause menu's Ability Controls panel exposes the
|
||
same diagram, spatial D-pad navigation, current-assignment focus, empty or
|
||
duplicate bindings, safe reset confirmations, and immediate per-character
|
||
persistence. Friendly abilities continue to target the selected ally or self;
|
||
D-pad Up/Down cycles living party members plus the player. The PC and Thor
|
||
companion surfaces share the active layer and semantic binding commands.
|
||
|
||
**Automated/native evidence:** The full suite passed 33 files and 212 tests.
|
||
Coverage includes all 24 defaults, partial/corrupt save normalization,
|
||
per-character isolation, custom chord casting, modifier transition ordering,
|
||
native duplicate suppression, system/menu Back routing, self targeting, and
|
||
dual-screen dispatch. TypeScript and the production Vite build passed with 672
|
||
modules transformed. Android `:app:compileDebugJavaWithJavac --no-daemon`
|
||
completed all 43 tasks successfully; only the existing SDK XML/flatDir warnings
|
||
remained. A fresh production preview on an isolated local port returned HTTP
|
||
200 for both `/` and `/?layout=thor-preview`, then the preview process was
|
||
stopped.
|
||
|
||
**Current content boundary:** Every class currently exposes four runtime
|
||
abilities. Defaults therefore fill Cross, Square, Triangle, and Circle while
|
||
R1, R2, D-pad Left/Right, L1, and L2 slots begin empty. Players can reuse those
|
||
four abilities anywhere now; distinct assignments for all 24 slots require the
|
||
separate future expansion of the class ability catalogs and unlock progression.
|
||
No screenshot-based visual pass was possible in this session because no
|
||
connected in-app browser backend was available; responsive and accessibility
|
||
layout received static review, and fresh production entry was HTTP-smoke-tested.
|
||
|
||
### HM-2026-07-22-INPUT-HANDEDNESS - FIXED, AUTOMATED PASS
|
||
|
||
**Reported:** Keyboard A/D strafing and horizontal pointer-lock mouse look moved
|
||
in the opposite direction from the rendered third-person camera.
|
||
|
||
**Cause and fix:** Raw keyboard, mouse, and gamepad inputs already used standard
|
||
positive-right values. The shared +Z camera-relative transform supplied the
|
||
opposite screen-right vector, and positive horizontal look was added to yaw
|
||
even though this camera convention turns right by decreasing yaw. The movement
|
||
basis now uses the rendered camera's actual right vector, and a shared yaw
|
||
helper applies positive mouse/right-stick look in the matching direction.
|
||
Vertical look is unchanged. The correction also fixes left-stick strafing and
|
||
right-stick horizontal look.
|
||
|
||
**Evidence:** Focused input coverage passed 15 tests. New regressions verify
|
||
A/D at zero and nonzero camera yaw plus both horizontal look directions. The
|
||
full suite passed 33 files and 214 tests, and the production build passed with
|
||
672 modules transformed. A manual pointer-lock feel check remains device-side
|
||
because no connected browser backend was available in this session.
|
||
|
||
### HM-2026-07-22-SPELL-ICONS-STARTER-WEAPONS - IMPLEMENTED, PC VISUAL PASS
|
||
|
||
**Requested:** Use each spell's real client icon, equip the player and every
|
||
party member with a starting weapon, and replace the companions' repeated
|
||
whole-body thrusting with an attack that reads as an actual strike.
|
||
|
||
**Spell-icon result:** All 40 runtime abilities were joined through their
|
||
`dbcSpellId` to the local 3.3.5.12340 `Spell.dbc` and `SpellIcon.dbc` data. The
|
||
existing basenames were exact, including several non-obvious stock mappings,
|
||
but every URL pointed at a nonexistent `/assets/ui/spells/*.webp` directory.
|
||
The 39 distinct authoritative BLPs are now decoded into shipped 64x64 PNGs,
|
||
and the catalog serves those files. `scripts/export-spell-icons.mjs` provides a
|
||
dependency-free reproducible exporter for DXT1, DXT3, and DXT5 BLP2 sources.
|
||
The catalog audit pins all 40 DBC-id mappings and fails when an icon is absent
|
||
or empty.
|
||
|
||
**Equipment result:** No standalone weapon models or playable-character attack
|
||
clips were present in the browser asset pack; every race/gender rig contains
|
||
only Stand, Walk, and Run. A shared procedural equipment layer now supplies
|
||
swords, maces, staves, daggers, bows, and shields. Warriors use sword/shield,
|
||
Paladins and Shamans use mace/shield, Rogues dual-wield daggers, Hunters use a
|
||
bow, Death Knights use a runeblade, and cloth/Druid classes use staves. Weapon
|
||
scale is estimated in avatar-local space. Attachment discovers hands from the
|
||
named finger pivots instead of numeric bone IDs, which differ by skeleton; the
|
||
same class loadout is also rendered on the procedural loading/error fallback.
|
||
|
||
**Attack-motion result:** Party `nextActionAt` changes now create one stable
|
||
presentation pulse per real hit. Tanks no longer animate continuously merely
|
||
because their status is `guarding`, and the party wrapper no longer pitches or
|
||
bobs during attacks. Each pulse layers a short windup/strike/recovery onto the
|
||
right shoulder after the locomotion mixer, while the equipped weapon layer
|
||
adds bounded main-hand/off-hand or bow motion and returns exactly to rest. The
|
||
player receives the same one-shot presentation after a successful completed
|
||
ability. Combat simulation timing remains outside the render components.
|
||
|
||
**Automated evidence:** The focused icon/equipment/attack/party suites passed
|
||
4 files and 25 tests. The equipment audit reconstructs every one of the 20
|
||
shipped playable GLBs and resolves both hands. The complete suite passed 35
|
||
files and 224 tests with the established 15-second allowance for the heavy
|
||
level-1-through-80 party-talent audit. TypeScript passed. A clean Vite
|
||
production build transformed 674 modules; the existing large-chunk warnings
|
||
remain informational.
|
||
|
||
**Visual evidence:** At 1440x900 in Edge/Chromium, the roster preview showed
|
||
the Priest's staff attached to her hand. Fresh dungeon entry showed textured
|
||
Wailing Caverns, equipped player/party silhouettes, and the real Smite, Shadow
|
||
Word: Pain, Flash Heal, and Psychic Scream art on the controller action bar.
|
||
The successful captures are
|
||
`playtest-artifacts/2026-07-22-weapons/roster-staff.png` and
|
||
`playtest-artifacts/2026-07-22-weapons/dungeon-equipped-party.png`; neither
|
||
shows a loading/error surface or the prior white-screen failure.
|
||
|
||
The follow-up 1280x720 Edge/Playwright pass issued the real F1 Attack shortcut
|
||
and captured 25 frames from the pre-command state through two defeated entrance
|
||
adds. The sequence shows discrete arm/weapon actions on damage events, upright
|
||
rest poses between pulses, and no repeated pelvis pitch. Weapons remain bound
|
||
to moving hands throughout the advance. Evidence is in
|
||
`playtest-artifacts/2026-07-22-weapons/attack-contact-sheet.jpg` and the
|
||
individual `attack-frame-*.jpg` files. No page error, scene-error overlay,
|
||
white-screen recurrence, or WebGL context loss appeared. The log contains one
|
||
generic 404 plus software-WebGL and initialization deprecation warnings; none
|
||
prevented the dungeon, party, spell art, equipment, or combat from rendering.
|
||
|
||
**Remaining visual boundary:** A tank can briefly cross very close to the
|
||
player camera while the party leaves formation, making its shield dominate the
|
||
view for several frames. That is a companion separation/formation issue, not a
|
||
return of the old attack thrust. Native pointer lock, Android/Thor scale and
|
||
performance, and every race/class equipment silhouette remain separate
|
||
device-side checks. Re-exported authentic item models and native attack/cast
|
||
clips would be a future visual-quality upgrade over the current procedural
|
||
starter gear.
|
||
|
||
### HM-2026-07-22-MAIN-MENU-DUNGEON-BROWSER - IMPLEMENTED, AUTOMATED PASS
|
||
|
||
**Requested:** Add a main menu after character selection with Dungeons,
|
||
Manastorms, Roguelike RPG, Trials, Options, and Player Profile. Only Dungeons
|
||
needs to work initially and must open a dungeon list.
|
||
|
||
**Result:** Confirming a roster character now opens a dedicated mode hub
|
||
without initializing or resetting gameplay. Dungeons opens a separate browser
|
||
backed by a manifest-derived catalog. Wailing Caverns is the sole available
|
||
entry because it is the only complete runtime currently shipped; selecting it
|
||
activates the character, resets at the entrance, and mounts the 3D game. The
|
||
other five requested mode cards are visible, disabled, and marked Coming soon.
|
||
Back navigation follows dungeon browser to main menu to character roster, and
|
||
the in-game pause exit now returns to the main menu. Narrow PC layouts retain a
|
||
visible Continue button instead of hiding the only pointer-accessible action.
|
||
|
||
**Controller and companion behavior:** A/Enter confirms, directional input
|
||
navigates, and B/Escape backs out on both new top-screen views. The companion
|
||
display has explicit main-menu and dungeon states, so these shell phases never
|
||
fall through to a stale tactical HUD. Its roster Continue, dungeon launch,
|
||
change-character, and return-to-main-menu commands mirror the authoritative
|
||
top-screen transitions.
|
||
|
||
**Evidence:** Focused shell/catalog/dual-display coverage passed 3 files and 16
|
||
tests. The complete suite passed 36 files and 232 tests. TypeScript and the
|
||
production Vite build passed with 677 modules transformed; existing large
|
||
chunk warnings remain informational. The local development entry returned HTTP
|
||
200. Screenshot automation could not connect to the in-app browser backend in
|
||
this Windows sandbox, so responsive desktop/compact layouts received static
|
||
review rather than a claimed visual pass.
|
||
|
||
### HM-2026-08-01-RUNEWAKER-ALL-DUNGEONS - ACTIVE FIDELITY PASS
|
||
|
||
**Reported:** Every RuneWaker dungeon unexpectedly displayed Coming Soon, and
|
||
the imported actors did not consistently retain their original skeletons,
|
||
animations, appearances, or attacks.
|
||
|
||
**Catalog result:** The generated WoW availability refresh had replaced the
|
||
whole availability document and removed every RuneWaker key. Availability
|
||
generation now preserves non-campaign keys, and packaged RuneWaker definitions
|
||
fall back to their validated offline metadata when a key is absent. The live
|
||
dungeon browser showed all 30 RuneWaker packages as Ready. Evidence:
|
||
`artifacts/playtests/rom-dungeon-catalog-ready.png`.
|
||
|
||
**Native animation result:** The RuneWaker exporter now selects the largest
|
||
body GR2 hierarchy instead of a one-bone effects hierarchy, samples the ACT/RAS
|
||
motion set at 30 Hz, and maps skin weights from original OBJ positions to the
|
||
vertices Blender reordered or duplicated at seams. A complete audit accounts
|
||
for every recipe-referenced actor and rejects invalid GLBs or missing required
|
||
animation families. Dynamic paperdoll appearances are exported as exact
|
||
image-specific assembled actors instead of generic proxy bodies; the portable
|
||
appearance snapshot is checked into the build inputs so normal/offline builds
|
||
never connect to SQL.
|
||
|
||
For this historical rollout, the contract was expressed at the base-actor level
|
||
as 267 native actors, one documented pose-only actor, and no combat proxy actors.
|
||
The newer authoritative acceptance scope is the 322 namespaced shipping
|
||
variants recorded in the in-progress entry above.
|
||
Runtime population bindings were 435 native,
|
||
one pose-only, and zero proxy. The former eight actorless “bosses” were source
|
||
FX/door controllers (six invisible soul-ball effects and two dungeon doors),
|
||
not missing creature models; they are now deferred mechanics objects rather
|
||
than fake combat objectives.
|
||
|
||
**Combat-data result:** The portable RuneWaker spell catalog contains the
|
||
source assignments used by all dungeon population recipes. The generator only
|
||
executes positively classified direct-HP-damage families; buffs, summons,
|
||
heals, hooks, and unknown effects remain evidence rather than guessed gameplay.
|
||
The current cross-dungeon audit counts 388 source-backed executable attacks and
|
||
zero evidence-only spells entering runtime combat. Every entity still retains
|
||
a HealerMan basic fallback, so this is not yet a claim of formula-exact boss
|
||
state machines.
|
||
|
||
**Browser result:** Forsaken Abbey loaded from packaged files, rendered its
|
||
native population, and entered party combat with damage and XP progression;
|
||
captures are `artifacts/playtests/forsaken-abbey-native-population.png` and
|
||
`artifacts/playtests/forsaken-abbey-combat.png`. Pasper's Shrine initially
|
||
stopped at Blackhorn Nisorn because the source position was 5.25 meters outside
|
||
the retained navigation surface. Objective routing now projects a combat
|
||
approach point within the same six-meter rule used by the audit. The party
|
||
advanced, fought, took damage, and gained XP without console errors. Evidence:
|
||
`artifacts/playtests/paspers-shrine-route-fixed-combat.png`; the original
|
||
failure is retained as `artifacts/playtests/paspers-shrine-route-blocked.png`.
|
||
|
||
**Open fidelity boundary:** The source audit still reports disconnected ordered
|
||
boss routes in several packages and evidence for doors, phases, summons,
|
||
patrols, timers, interactions, and loot that has not been translated into
|
||
tested encounter state machines. Those items must remain explicit blockers or
|
||
review work; they must not be represented as a complete original game until
|
||
implemented and playtested instance by instance.
|
||
|
||
**Final production/offline verification:** The production build completed with
|
||
all 93 packaged paperdoll actor copies present in `dist`. The temporary
|
||
`HealerMan_RW_Objects_Paperdoll` forensic database was dropped and the manual
|
||
`MSSQL$HEALERMAN_RW` service was stopped before the browser check. From the
|
||
packaged production preview, offline login opened the RoM catalog with 30
|
||
available, 30 Ready, and zero Coming Soon entries; Forsaken Abbey then launched
|
||
into the 3D runtime with its population present. Evidence:
|
||
`artifacts/playtests/rom-dungeon-catalog-production-final.png` and
|
||
`artifacts/playtests/forsaken-abbey-production-final.png`. No browser error was
|
||
reported during dungeon launch. The log retained two earlier WebGL context-lost
|
||
messages from page transitions and one non-blocking initialization deprecation
|
||
warning.
|
||
|
||
**Historical automated scope:** TypeScript and the production build passed for
|
||
that rollout. Its RuneWaker animation audit reported 267 native base actors, one
|
||
pose-only base actor, and no configured combat proxies; required idle, movement,
|
||
attack, wound, and death animation-family gates were satisfied under the earlier
|
||
gate. It is superseded by the completed v5 all-variant verdict above. The
|
||
gameplay audit covered 30
|
||
dungeons, 8,199 source placement rows, 4,086 runtime static spawns, 436 runtime
|
||
entities, 61 boss objectives, and 824 executable attacks (436 basic fallbacks
|
||
plus 388 source-backed attacks). The full test run passed 87 files and 522
|
||
tests; its remaining three failures are pre-existing Manastorm fixture/parser
|
||
failures outside this RuneWaker work. The previously stale Forsaken Abbey test
|
||
was fixed and passes separately.
|
||
|
||
**Remaining source-fidelity work:** Thirty-one paperdoll appearances still need
|
||
their original dye-mask colors composited, although their geometry, base
|
||
textures, skeletons, skinning, and clips are authentic. Twenty-one optional
|
||
source RAS references are absent or non-GR2, while every required combat family
|
||
still passes. The navigation audit records 19 unreachable distance-derived
|
||
objective legs across eight packages; there are no preserved source-authored
|
||
orders, so unsafe permanent off-mesh links were not invented. Original
|
||
coefficient formulas and the evidenced door, phase, summon, patrol, timer,
|
||
interaction, loot, and modular-room state machines remain the next per-instance
|
||
implementation pass.
|
||
|
||
### HM-2026-08-01-ARROW-CAMERA-LOOK - PC KEYBOARD CAMERA PASS
|
||
|
||
**Requested:** On PC in the browser, make the arrow keys turn the camera when
|
||
playing with mouse and keyboard instead of a controller.
|
||
|
||
**Result:** WASD remains the keyboard movement cluster. Left/right arrows now
|
||
apply continuous camera yaw, and up/down arrows apply continuous camera pitch.
|
||
The pause controls and live HUD hint now describe arrows as camera input rather
|
||
than movement input. Controller left-stick movement and right-stick camera look
|
||
remain unchanged.
|
||
|
||
**Live browser evidence:** Wailing Caverns was launched from the offline roster.
|
||
Repeated right-arrow input changed the minimap heading from 244 degrees to 242
|
||
degrees; repeated left-arrow input then changed it to 247 degrees. Up/down arrow
|
||
passes visibly changed the vertical camera angle. The exploration counter stayed
|
||
at 0 m throughout, confirming arrow input did not move the player, and the
|
||
heading stayed at 247 degrees after a 600 ms release check. The updated camera
|
||
hint rendered in the dungeon and the browser console contained no errors.
|
||
|
||
**Pointer-lock boundary:** The in-app playtest browser does not expose the
|
||
Pointer Lock API, so `document.pointerLockElement` is undefined there and a
|
||
live null assertion or held-right-button automation is not possible on that
|
||
surface. No capture prompt appeared. The unchanged right-drag path remains
|
||
covered by `inputManager.test.ts`, including ordinary drag deltas and a null
|
||
pointer-lock assertion.
|
||
|
||
**Automated evidence:** `src/game/inputManager.test.ts` and
|
||
`src/game/inputMath.test.ts` pass 19 tests. TypeScript and the production Vite
|
||
build pass with 914 modules transformed; the existing large-chunk warnings
|
||
remain informational.
|
||
|
||
### HM-2026-08-01-RUNEWAKER-PLAYERS - RACES, CLASSES, AND DUAL CLASS
|
||
|
||
**Result:** The WoW/RoM content split is live across character creation,
|
||
persistence, roster summaries, party generation, Class Hall, the spellbook,
|
||
and combat. RoM ships Human, Elf, and male-only Dwarf plus the ten released
|
||
classes. Level 10 permanently fixes a race-eligible secondary; Class Hall swaps
|
||
the ordered primary/secondary orientation and its independent action bar.
|
||
Shared XP, automatic ranks, primary stats plus 10% secondary stats, role and
|
||
resource changes, equipment compatibility, and directional elite unlocks are
|
||
covered by the application tests. Existing WoW profiles migrate to storage v2
|
||
without losing their progression or bindings.
|
||
|
||
**Generator/audit:** `npm run runewaker:players:refresh` completed from the
|
||
RuneWaker source tables, strings, elite Lua, image metadata, and `interface.fdb`.
|
||
The portable catalog records source SHA-256 hashes and contains 269 ordinary
|
||
skill families plus 660 elite milestones across all 66 valid ordered pairs.
|
||
All 929 visible skills have an executable or explicit non-combat contract;
|
||
zero are unresolved. All 929 icon references resolve to 918 unique native PNGs.
|
||
The independently loadable `runewaker-v1` manifest contains five native rigs
|
||
(Human male/female, Elf male/female, Dwarf male), starter attachments, and
|
||
native idle/walk/run/attack/cast clip families. Khronos validation reported
|
||
zero errors and zero warnings for all five GLBs.
|
||
|
||
**Live controller/browser QA:** From the production preview, keyboard/controller
|
||
menu navigation moved from the default WoW Human race to the RoM category and
|
||
confirmed it with Enter. The draft reset to Taborean Human and exposed the
|
||
correct six-class pool. Dwarf creation enforced male gender and exposed
|
||
Warrior, Rogue, Mage, Priest, Warlock, and Champion. A native Dwarf Champion
|
||
rendered in creator and roster. The level-1 Class Hall showed its level-10 lock;
|
||
level-10 selection, irreversible confirmation, swapping, and both orientations
|
||
are covered by automated controller/persistence tests.
|
||
|
||
The same RoM character could select both the 54-dungeon WoW category and the
|
||
30-dungeon RoM category. Wailing Caverns and Forsaken Abbey both launched with
|
||
the native character, a rage pool, RuneWaker spell icons, and a same-category
|
||
RoM party. The tactical menu now says **Skills**, and its RoM view reported
|
||
Primary `2 / 18`, Secondary General `0 / 0`, Elite `0 / 0`, and automatic
|
||
rank progression for the pre-secondary level-1 Champion. Browser diagnostics
|
||
contained no errors. Expected renderer teardown messages and one non-blocking
|
||
initialization deprecation warning remain.
|
||
|
||
**Evidence:**
|
||
|
||
- `playtest-artifacts/2026-08-01-rom-dual-class/rom-roster-preview.png`
|
||
- `playtest-artifacts/2026-08-01-rom-dual-class/rom-character-wow-dungeon-preview.png`
|
||
- `playtest-artifacts/2026-08-01-rom-dual-class/rom-character-rom-dungeon-preview.png`
|
||
- `scripts/runewaker-pipeline/snapshots/runewaker-player-skill-audit.json`
|
||
|
||
**Final verification:** `npx tsc -b --pretty false` passed; Vitest passed all
|
||
95 files and all 549 tests; `npm run build` passed with 921 modules transformed.
|
||
Vite's existing large-chunk advisory remains informational.
|
||
|
||
### HM-2026-08-01-DUNGEON-ASSET-EVICTION - GLTF AND GPU LIFECYCLE
|
||
|
||
**Result:** Regular dungeon sessions now own their environment, collision,
|
||
navigation, and creature GLB URLs. Switching dungeons or leaving the gameplay
|
||
runtime clears those URLs from Drei's global `useGLTF` cache. Scene teardown
|
||
also deterministically disposes dungeon-owned geometries, cloned materials,
|
||
textures, creature skeletons, and bone textures, with identity-based
|
||
deduplication so shared resources are released once. Playable-character and
|
||
equipment assets remain cached because they are reused across every dungeon.
|
||
|
||
**Live browser evidence:** A fresh production-preview renderer loaded Auchenai
|
||
Crypts at 797.7 MB private / 856.6 MB working set. Returning to the main menu
|
||
released the outgoing scene and settled at 555.8 MB / 615.1 MB. Blackrock
|
||
Depths then loaded at 1,033.2 MB / 1,098.6 MB. Chromium initially retained that
|
||
allocator reservation after the Blackrock teardown, but loading Auchenai again
|
||
settled at 800.0 MB / 855.6 MB, effectively matching the first Auchenai load
|
||
instead of stacking both dungeon footprints. Leaving Auchenai a second time
|
||
settled at 592.5 MB / 651.5 MB. The environment, five-character party, HUD, and
|
||
minimap rendered correctly throughout. Browser diagnostics contained no GLB,
|
||
WebGL, or runtime errors; only the existing non-blocking initialization
|
||
deprecation warning remained.
|
||
|
||
**Verification:** The focused dungeon ownership, session-switch, invalid-switch,
|
||
and shared-resource disposal tests passed all 11 cases. The full Vitest run
|
||
passed 98 files and 556 tests. TypeScript, the 54-dungeon campaign audit, the
|
||
five-player import verifier, and `npm run build` all passed; the production
|
||
build transformed 923 modules. Vite's existing large-chunk advisory remains
|
||
informational.
|
||
|
||
### HM-2026-08-01-ROM-ABILITY-PRESENTATION - NATIVE ICONS AND CLIPS
|
||
|
||
**Result:** Runtime RoM abilities now consume the native icon path already
|
||
recorded in `romPlayerCatalog.generated.json` instead of replacing every skill
|
||
icon with its class emblem. RoM combat animation events now select native
|
||
RuneWaker character clips for casting/continuous casting, friendly buffs, bow
|
||
channel/release, melee weapon variations and specials, wounds, and death. WoW
|
||
characters retain the existing AnimationData-ID selector.
|
||
|
||
**Live browser evidence:** The saved Dwarf Champion rendered in the roster and
|
||
entered Forsaken Abbey with its body and starter weapon silhouette visible. All
|
||
eight live action slots resolved to distinct `/assets/ui/rom-spells/<id>.png`
|
||
assets (including Heavy Bash `589471.png` and Electrocution `589472.png`). The
|
||
ability control was exercised against a selected Ooze; the game correctly
|
||
reported that the target was out of melee range. Browser diagnostics contained
|
||
no errors. Native clip reachability for release/cast/bow/melee/wound/death is
|
||
therefore recorded by the focused automated selector test rather than claimed
|
||
from the out-of-range screenshot.
|
||
|
||
**Evidence:**
|
||
|
||
- `artifacts/playtest/rom-roster-preview-2026-08-01.png`
|
||
- `artifacts/playtest/rom-dungeon-heavy-bash-2026-08-01.png`
|
||
|
||
**Verification:** `src/game/combatAnimation.test.ts` and
|
||
`src/game/romPlayerCatalog.test.ts` passed all 11 tests; `npm test -- --run
|
||
src/avatar` passed all 28 avatar tests; `npm run build` passed with 921 modules
|
||
transformed. Vite's existing large-chunk advisory remains informational.
|
||
|
||
### HM-2026-08-01-WOW-CREATURE-ANIMATION-MEMORY - RUNTIME CLIP POLICY
|
||
|
||
**Result:** Shipped WoW dungeon creature GLBs now contain only animation
|
||
families requested by `MobPopulation`: stand, walk, run, and the highest-priority
|
||
available attack, cast, wound, and death families. Every variation in each
|
||
selected combat family is retained. The complete source GLBs remain untouched
|
||
under `HealerMan-Storage/pipeline-work/dungeons`, and all five-player, Epoch,
|
||
and Wailing Caverns packaging paths now apply the same policy to future exports.
|
||
|
||
The migration optimized 1,111 current dungeon creature GLBs. Source inventory
|
||
fell from 73,191 clips to 8,102 runtime clips. Runtime payload fell from
|
||
4,855,010,592 bytes to 2,963,934,636 bytes, saving 1,891,075,956 bytes (39%).
|
||
The 146-clip Auchenai reference model retained nine gameplay clips and fell
|
||
from 13,824,072 bytes to 7,650,004 bytes. Generated manifests record the source
|
||
clip count, runtime count, policy version, checksum, and post-policy semantics.
|
||
|
||
**Live browser evidence:** A fresh production-preview session opened the saved
|
||
Human Priest and entered Auchenai Crypts as healer. The environment and all five
|
||
character rigs rendered correctly. After moving inside the 95 m population
|
||
activation radius, the browser resource inventory confirmed optimized creature
|
||
displays 17932, 17924, and 17942 were loaded. Browser diagnostics contained no
|
||
errors; the existing initialization deprecation warning remains non-blocking.
|
||
After creature activation, the renderer settled at about 930 MB private / 989
|
||
MB working set and peaked at about 1.03 GB private / 1.09 GB working set. The
|
||
earlier pre-change two-dungeon pass peaked around 1.15 GB private / 1.2 GB
|
||
working set, so these measurements are directional rather than an identical
|
||
scene sequence.
|
||
|
||
**Verification:** The policy's four focused Node tests passed. The campaign-wide
|
||
WoW content test passed all 54 dungeons, the five-player verifier remained green
|
||
with only its three documented source blockers, mob/combat animation tests
|
||
passed all 18 cases, and `npm run build` passed with 921 modules transformed.
|
||
Vite's existing large-chunk advisory remains informational.
|
||
# 2026-08-14 — local-first content delivery and compact Android client
|
||
|
||
- Build under test: fresh full production `dist` served by `server/server.mjs`
|
||
at `http://127.0.0.1:4173`.
|
||
- Booted to the login screen and entered through **Play offline** without an
|
||
account-server request.
|
||
- Roster preview: the saved level 8 human female priest rendered her complete
|
||
body, hair, and starter staff silhouette. The procedural/error fallback did
|
||
not replace or hide the character.
|
||
- Downloads screen: the two-column local-first layout rendered without
|
||
clipping at the test viewport. Its local catalog request returned the
|
||
expected 404 because no generated `content/` volume was mounted for this
|
||
local smoke test; the screen retained the offline starter-content message.
|
||
- Dungeon smoke: entered Wailing Caverns as healer. The production cavern,
|
||
player body/equipment silhouette, four companion bodies, HUD, minimap, and
|
||
action bar were visible. No missing-GLB proxy or scene error appeared.
|
||
- Evidence reviewed during the browser run: login, roster-preview, Downloads,
|
||
and in-dungeon screenshots. Browser console contained no errors; one existing
|
||
third-party initialization deprecation warning was present.
|
||
|
||
# 2026-08-16 — CoA character-creation category
|
||
|
||
- Opened the offline roster and entered character creation in the live Vite
|
||
client. The header rendered distinct **WoW**, **RoM**, and **CoA** tabs without
|
||
clipping.
|
||
- The WoW tab showed only the eight standard WoW classes available to Human;
|
||
no custom CoA class appeared.
|
||
- The CoA tab reused the Azeroth race roster and showed the 16 custom CoA
|
||
classes available to Human, defaulting to Barbarian. The character body and
|
||
starter weapon silhouette remained visible while switching categories.
|
||
- In the production preview, the saved Human Priest rendered in the roster with
|
||
her full body and starter staff silhouette, then entered Wailing Caverns with
|
||
her body, staff, party, dungeon environment, and HUD visible.
|
||
- Browser diagnostics contained no errors.
|
||
- Evidence: `playtest-artifacts/character-create-wow-category-2026-08-16.png`
|
||
`playtest-artifacts/character-create-coa-category-2026-08-16.png`,
|
||
`playtest-artifacts/character-category-roster-2026-08-16.png`, and
|
||
`playtest-artifacts/character-category-dungeon-2026-08-16.png`.
|
||
- Verification: 71 focused catalog/store/repository/dungeon/ability/party tests
|
||
passed, all 28 avatar tests passed, and `npm run build` completed
|
||
successfully.
|
||
|
||
# 2026-08-16 — Deadmines party terrain following and vertical animation tolerance
|
||
|
||
- Entered The Deadmines as the saved Human Priest and selected **Attack**.
|
||
The player crossed 43 m of uneven mine-floor and rail terrain; the tank and
|
||
a damage companion remained visibly beside the player instead of waiting for
|
||
the 12 m stuck-recall threshold. All four companion world labels remained in
|
||
the live scene, and no automatic party recall was observed.
|
||
- The character maintained ordinary ground locomotion over small collision
|
||
height changes. Focused timing coverage confirms that terrain gaps shorter
|
||
than 100 ms neither enter the falling state nor trigger a landing animation,
|
||
while intentional jumps and sustained falls still present immediately/after
|
||
the grace period and land once.
|
||
- The saved roster preview rendered the complete Human body and starter staff;
|
||
the in-dungeon view rendered the player silhouette, nearby companions, the
|
||
Deadmines environment, and HUD.
|
||
- Browser diagnostics contained no errors. The existing third-party
|
||
initialization deprecation warning remained non-blocking.
|
||
- Evidence: `playtest-artifacts/party-terrain-roster-2026-08-16.png`,
|
||
`playtest-artifacts/deadmines-party-terrain-2026-08-16.png`, and
|
||
`playtest-artifacts/deadmines-party-follow-view-2026-08-16.png`.
|
||
- Verification: 38 focused party/pathing/jump/animation tests passed, all 28
|
||
avatar tests passed, and `npm run build` completed successfully with 954
|
||
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.
|
||
|
||
# 2026-09-09 — fixed per-rank classic mana costs
|
||
|
||
- Imported WoW mana percentages are now converted into fixed costs at each
|
||
spell rank's source level. Player level, Intellect, equipment, and maximum-mana
|
||
modifiers no longer increase the cost of an already learned rank; legitimate
|
||
talent and aura cost reductions are still applied afterward.
|
||
- Shadow Word: Pain rank 4 now costs 133 mana at every level from 26 through 33,
|
||
including level 32. Learning rank 5 at level 34 raises the cost to 188 mana.
|
||
- AI companions now use real character-scale mana pools so fixed spell costs do
|
||
not prevent healing or resurrection. The companion display also resolves the
|
||
active spell rank and the same final affordability result as the primary HUD.
|
||
- Verification passed all 1,133 Vitest cases across 208 files. The production
|
||
build completed with 974 modules transformed; arena, KTX2, and environment-
|
||
performance audits remained green, and the release-candidate check passed.
|
||
|
||
# 2026-09-09 — dungeon wall and nameplate performance regressions
|
||
|
||
- The 0.1.24 material fallback honored BLEND tags on legacy WoW WMO walls,
|
||
floors, and ceilings, disabling their depth writes. WoW environments now use
|
||
their authored material roles again; RuneWaker environments retain their
|
||
source MASK/BLEND semantics. Shipped Wailing Caverns wall materials, vines,
|
||
and water are covered by regression tests.
|
||
- The 0.1.25 boss-name occlusion scanned the complete rendered scene with
|
||
Three.js raycasts. A live Kalin's Shrine CPU profile was dominated by triangle
|
||
intersection and vertex decoding. Boss names and nearby NPC prompts now use
|
||
bounded camera-to-label queries against Rapier's existing physical spatial
|
||
index, at most ten times per second, skipping offscreen labels. Walls, floors,
|
||
and ceilings occlude labels; actors and trigger sensors do not.
|
||
- In an isolated offline Edge playtest at 1440 x 900 on an AMD RX 9070 XT,
|
||
Kalin's Shrine improved from about 10 FPS (98.5 ms/frame, 167 draw calls,
|
||
DPR 1.125) to 55.5-56.1 FPS (17.8-18.0 ms/frame, 168-170 draw calls,
|
||
DPR 1.5). This is a representative entrance/combat comparison, not an audit
|
||
of all thirty RoM dungeons. The environment alone took about 0.8 ms CPU and
|
||
0.5 ms GPU with 14 draw calls.
|
||
- Wailing Caverns screenshots show continuous opaque cavern walls and ceilings.
|
||
A controlled toggle of the old material flags reproduced the missing wall
|
||
sections at the same camera position; restoring depth-writing materials fixed
|
||
them. Its full scene ran at about 57 FPS. No uncaught client errors appeared.
|
||
- Evidence and repeatable local benchmark helpers are under
|
||
`playtest-artifacts/2026-09-09-dungeon-rendering/`: `kalin-before.cpuprofile`,
|
||
`kalin-after.cpuprofile`, `kalin-after-metrics.json`, `kalin-before.png`,
|
||
`kalin-after.png`, `wailing-regression.png`, and `wailing-restored.png`.
|
||
- All 26 focused material, label occlusion, combat sight, aggro visibility,
|
||
instancing, and NPC-prompt tests passed. Physical-occlusion tests exercise
|
||
actual Rapier worlds rather than just source-code assertions.
|
||
|
||
# 2026-09-09 — campaign rendering audit and Thor performance preparation
|
||
|
||
- Audited the actual visual GLB headers for all 54 WoW campaign dungeons:
|
||
9,402 materials, including 3,586 legacy BLEND materials restored to opaque
|
||
rendering by the shared policy. Every WoW package contained affected
|
||
materials. A permanent shipped-asset test covers all 54 definitions and
|
||
retains explicit cutout, blend, and additive roles. This is material-policy
|
||
coverage, not a claim that every room has been visually traversed.
|
||
- Live screenshots checked Wailing Caverns, Shadowfang Keep, Utgarde Pinnacle,
|
||
the Nexus, and Tinkertech Showdown. The sampled walls, floors, stairs, and
|
||
ceilings remain solid; authored lighting effects remain transparent. Kalin's
|
||
Shrine and Forsaken Abbey provided RoM rendering checks. Roster and in-dungeon
|
||
screenshots show character bodies and equipped weapon silhouettes after the
|
||
shared character animation change.
|
||
- A controlled Utgarde Pinnacle entrance test found about 1,739 draw calls,
|
||
1.95 million triangles, and 30.5 FPS on the desktop GPU. Clipping at the
|
||
existing full-fog distance reduced this to about 209 calls, 567,000 triangles,
|
||
and 60 FPS at the same viewpoint. The camera now follows each dungeon's fog
|
||
distance, including transitions that retain the existing Canvas/camera.
|
||
The background uses the fog color to avoid a clipping seam at the horizon.
|
||
All 84 dungeon definitions have render-distance coverage.
|
||
- Static dungeon visual transforms are cached until the root or its parent's
|
||
world transform changes. Tests verify imported matrices, repeated unchanged
|
||
frames, root movement, and parent movement. Characters, moving world objects,
|
||
and physics remain outside this immutable visual cache.
|
||
The final 63-second Utgarde sample held 60 FPS with 213 draw calls:
|
||
main-thread work averaged 9.2 ms/frame, renderer CPU averaged 7.5 ms
|
||
(p95 8.3 ms), and GPU averaged 2.7 ms (p95 4.1 ms). Movement and jump input
|
||
continued to animate the player while the environment remained stationary.
|
||
- Character locomotion and jump clip selections are cached by animation
|
||
library and weapon stance. The final Kalin CPU profile contains no sampled
|
||
per-frame base-clip selection/name parsing. Frame-cap deadlines now tolerate
|
||
sub-millisecond timestamp rounding without drifting or emitting catch-up
|
||
frames; tests cover 60 FPS on rounded 60 Hz and 120 Hz callbacks.
|
||
- A 31.5-second Kalin sample with a connected browser companion display held
|
||
60 FPS: main-thread work averaged 8.7 ms/frame, renderer CPU averaged 5.4 ms
|
||
(p95 5.9 ms), and GPU averaged 2.4 ms (p95 3.4 ms). The companion used about
|
||
5.1 ms of main-thread time per second. Recent ability-cost snapshot work was
|
||
not a dominant hotspot in this sample. Startup warmup is bounded to loading;
|
||
companion snapshots are already limited to ten per second during gameplay.
|
||
- These are isolated offline Edge desktop samples on an AMD RX 9070 XT at
|
||
1920 x 1080 CSS pixels, DPR 1.5 (2880 x 1620 renderbuffer). Party composition
|
||
can change between dungeon entries. They do not certify Android performance
|
||
or sustained busy-combat headroom. ADB listed no connected Android device.
|
||
- Thor acceptance should use the actual model, both native displays, target
|
||
resolution, and a sustained 20-minute traversal/combat run after warmup.
|
||
Provisional headroom target: p95 main-thread and GPU work each at or below
|
||
12 ms, with p99 presented frame intervals within the 16.7 ms 60-FPS budget.
|
||
Test large pulls, boss effects, menus, and repeated dungeon transitions;
|
||
record thermal behavior and frame-time spikes, not only average FPS.
|
||
The environment asset audit still has 60 grandfathered budget exceptions;
|
||
its green result means no new asset regression, not a Thor FPS guarantee.
|
||
- Evidence is in `playtest-artifacts/2026-09-09-thor-audit/`, including roster,
|
||
dungeon, and companion screenshots, CPU profiles, and CPU/GPU JSON samples.
|
||
The full material report is
|
||
`playtest-artifacts/2026-09-09-dungeon-rendering/wow-material-audit.json`.
|
||
- Validation passed 227 focused tests covering avatar rendering and animation,
|
||
camera distances, material policies, frame pacing, static transforms, label
|
||
visibility, and companion snapshots. The final static-cache change also
|
||
passed the 105-test scene subset. The production build and release-candidate
|
||
check passed; the existing large-bundle advisory remains.
|
||
|
||
# 2026-09-09 — additional CPU headroom from culling and shared skeletons
|
||
|
||
- Prepared dungeon visuals now group static siblings into conservative spatial
|
||
bounds. One scene hook checks these bounds after the current camera and world
|
||
matrices update, before Three.js traverses individual meshes. Bounds include
|
||
complete wall geometry and all instances; lights, animated meshes, and meshes
|
||
explicitly disabling frustum culling remain outside these groups. The hook
|
||
supports streamed chunks and restores its predecessor after cleanup.
|
||
- At the same Utgarde Pinnacle entrance, only 16 of 1,383 spatial groups were
|
||
visible. The renderer examined 108 static meshes instead of 7,002, retaining
|
||
the same 206 draw calls and 566,913 rendered triangles. Controlled culling
|
||
toggles produced byte-identical canvas PNGs across eight camera headings.
|
||
- In the same running scene, spatial grouping reduced average main-thread work
|
||
from 9.45 to 6.83 ms/frame, and renderer CPU from 7.81 to 5.31 ms/frame.
|
||
Removing containers emptied by static instancing reduced the final fresh-run
|
||
averages further to 6.49 ms main-thread and 4.85 ms renderer CPU (p95 5.2 ms).
|
||
The final sample lasted 87.8 seconds and held 60 FPS. Authored empty scene
|
||
nodes are preserved; only containers emptied by our batching are removed.
|
||
- The shared character renderer still uses SkeletonUtils.clone, then reuses
|
||
equivalent skeleton palettes within that owned clone. Bone identities, order,
|
||
and inverse bind matrices must all match; per-mesh bind transforms remain
|
||
unchanged. Different characters retain independent bones and animations.
|
||
Owned bone textures are now explicitly disposed during character teardown.
|
||
- A live character audit found 66 skeleton objects for one player palette and
|
||
256 objects for four party palettes. A Wailing Caverns toggle removed 309
|
||
duplicate skeletons and produced an identical rendered image. Tests verify
|
||
posed vertices, differing bind transforms, incompatible palettes, independent
|
||
cloned characters, and redundant texture disposal.
|
||
In the same Wailing scene, main-thread work fell from 7.40 to 6.70 ms/frame;
|
||
renderer CPU fell from 5.51 to 4.86 ms/frame, and allocated GPU textures fell
|
||
from 292 to 217. This measures palette sharing after spatial culling was
|
||
already enabled. Both samples held 60 FPS.
|
||
- The final built runtime showed a complete roster body and staff with one
|
||
skeleton for 66 skinned meshes. Kalin's Shrine showed one player palette and
|
||
four independent party palettes; walking retained the player body and weapon
|
||
silhouette. Wailing Caverns and Utgarde screenshots retained solid dungeon
|
||
surfaces. There were no uncaught client errors during these playtests.
|
||
- All 210 targeted avatar, visibility, instancing, material, camera-distance,
|
||
and label tests passed. The production build and release-candidate check
|
||
passed. The existing large-bundle advisory remains.
|
||
- Evidence is under `playtest-artifacts/2026-09-09-static-culling/`: paired PNGs,
|
||
eight-heading pixel comparisons, profiles, before/after timing JSON, and
|
||
screenshots. Measurements use the same desktop Edge/RX 9070 XT setup as the
|
||
preceding audit. These CPU improvements do not certify Thor performance.
|
||
|
||
# 2026-09-09 — bundled arena assets blocked by the browser content worker
|
||
|
||
- Reproduced the reported collision-matched fallback in the production build
|
||
with the content worker active. Warnorken's `visual.glb?arena-runtime=1`
|
||
returned 404 even though the file was bundled and directly served with 200.
|
||
The worker omitted `/assets/game/arenas/` from its bundled asset prefixes and
|
||
incorrectly rejected these files as uninstalled optional content.
|
||
- Added the arena prefix to the worker. Installed updates still take priority;
|
||
missing optional dungeon content still returns 404. Behavioral worker tests
|
||
failed for all eight arenas before the fix and now cover visual, collision,
|
||
and navigation requests with the runtime query parameter.
|
||
- The production build passed. Reloading the same browser session activated
|
||
the fixed worker without clearing storage or downloading content. Warnorken
|
||
rendered textured stone geometry and Nagrand rendered its authored arena
|
||
geometry; neither showed the loading/fallback banner after loading, and no
|
||
new console errors were recorded. Checks used offline practice in the Codex
|
||
browser at `http://127.0.0.1:4174/`, backed by a local test server on port 4173.
|
||
- All 22 content tests and the eight-arena asset validator passed. Screenshots,
|
||
before/after error logs, asset validation, and build output are saved under
|
||
`playtest-artifacts/2026-09-09-arena-loading/`. The existing large-bundle
|
||
advisory remains. This verifies the local browser build, not a deployment
|
||
or an Android package.
|
||
|
||
# 2026-09-10 - arena character and gameplay integration
|
||
|
||
- Replaced the limited arena spell interpreter with a private bundle of the
|
||
existing character combat engine. Offline practice and server matches share
|
||
casting, channels, resources, auras, pets, talents and equipment mechanics.
|
||
Each actor/match keeps its own state; opening panels does not run a second
|
||
client simulation or overwrite dungeon state.
|
||
- The controlled character uses CharacterModel with saved appearance, gear,
|
||
class, specialization, talents and bindings. Other participants also use
|
||
character models. The HUD displays actual resources, runes, combo points,
|
||
cast/channel status, cooldowns, buffs, pet commands and PC/controller labels.
|
||
Spellbook, character, talents, bindings, keybinds, map and options work in
|
||
arena. Equipment and talents remain locked to the entered match loadout.
|
||
- Fixed Keybinds opening with a shortened custom PC bar: missing slots now
|
||
display as empty instead of crashing the React tree. Live checks opened
|
||
Keybinds, Character, Talents and Options; the four-slot Q/E/R/T bar cast
|
||
Flash Heal and Power Word: Shield with resource/cast/aura feedback.
|
||
- Fixed NaN facing, spectator-camera elevation, obstructed starting positions
|
||
and camera collision. Shared right-button drag ends on release, blur, lost
|
||
capture, menus and teardown without pointer lock. Movement, jump, targeting,
|
||
ground placement, feedback, animation and combat effects use arena state.
|
||
- Authority uses all collision chunks and navigation triangles. Removed
|
||
invisible static proxy walls. All 3v3 starts are grounded, and bots follow
|
||
connected routes around walls/ramps. Shortcuts stay on level ground to avoid
|
||
falling below waypoints. Detailed scenes use a shaped support surface; the
|
||
loading/error fallback now matches collision instead of using a flat box.
|
||
- Black Rook's old navigation/anchors were on terrain above the arena. Rebuilt
|
||
against restored collision, selected its connected interior component (783
|
||
triangles), and placed both starts on the floor near Y=-28.3. Updated the
|
||
asset metadata and generator to stop restoring the old terrain navigation.
|
||
- Added PvP defender stats, shields, resource drains, pushback, school locks
|
||
and control diminishing returns. Fixed duplicate control entries counting
|
||
twice, aligned aura/control duration, and made dispels remove movement
|
||
restrictions. Dispel Magic supports friends and enemies. Healers can heal
|
||
allied pets; melee bots start weapon attacks to generate rage.
|
||
- Automated checks: 38 server arena tests and 160 distinct avatar, input,
|
||
camera, arena character/rules, combat store and ability catalog tests.
|
||
Coverage includes channels/cancellation, runes, combos, pet orders/damage/
|
||
healing, interrupts, absorbs, dispels, DR, ground spells, mana burns, RoM
|
||
secondary resources, dampening, isolation, matchmaking and match results.
|
||
Both-direction walks between team starts pass across all eight arenas.
|
||
- Live checks use an isolated in-memory level-80 priest, ArenaPriest, without
|
||
changing the user's roster. Warnorken showed its interior, the selected
|
||
character and saved spell labels. Movement changed both actor and camera.
|
||
Bots traversed, cast spells, reduced health and settled a defeat when idle.
|
||
No detailed-asset warning appeared. Evidence uses the arena-complete prefix
|
||
under playtest-artifacts; earlier Nagrand/custom-bar evidence retains the
|
||
arena-player prefix. The drag probe uses installed input code with scripted
|
||
right-button events; rotation changes while held, stops after release, and
|
||
pointerLockElement remains null. This is not a physical-device test.
|
||
- Final screenshots show the Warnorken interior and character/action bar,
|
||
Black Rook's corrected interior floor, the roster body/staff, and the
|
||
character/party after returning to Wailing Caverns. Files:
|
||
arena-complete-warnorken.png, arena-complete-black-rook.png,
|
||
arena-complete-roster.png, arena-complete-dungeon.png and
|
||
arena-complete-keybinds.png in playtest-artifacts.
|
||
- Production build and release checks passed, with the existing bundle-size
|
||
advisory. Run npm run arena:abilities:build after catalog/asset changes;
|
||
prebuild also regenerates the engine and geometry. Verification is local
|
||
offline practice plus authoritative server tests. Hosted online PvP,
|
||
deployment and Android hardware were not exercised.
|
||
|
||
# 2026-09-10 — profile keybinds and movement-conflict recovery
|
||
|
||
- Added Pause / Options → Keybinds with 133 actions, PC and Controller tabs,
|
||
search/categories, capture and touch selectors, explicit conflict replacement,
|
||
clear/reset controls, and Restore movement. Desktop defaults to PC; mobile
|
||
and native Android default to Controller. Both tabs remain available.
|
||
- Live offline browser check: assigning W to bar 1/button 1 named Move forward
|
||
in the conflict prompt; cancelling preserved W. Rebinding forward to T,
|
||
saving, closing, and reopening retained T. Restore movement returned it to W.
|
||
- At 390 × 844, controller selectors assigned L1 + Triangle to Jump, prompted
|
||
before clearing the old layer-2 ability binding, and retained the saved chord
|
||
after reopening. Restored the test bindings afterward. The final phone panel
|
||
starts at (0, 0), has a 443px scrolling action list, and keeps the footer within
|
||
the viewport. Desktop layout checked at 1280 × 900.
|
||
- Fixed the inherited 610px panel-height cap, mobile backdrop padding, action
|
||
button accessible names, and companion-toggle overlap found during QA.
|
||
- 89 targeted tests passed across input dispatch, mouse-drag lifecycle, analog
|
||
remapping, conflict recovery, menus, account isolation, cloud transfer, UI
|
||
imports, and dual-display synchronization. The full production build and
|
||
release candidate check passed; the existing bundle-size advisory remains.
|
||
- Controller chord conflicts also cover a modifier button’s standalone action,
|
||
preventing combinations such as View + A from opening the companion first.
|
||
- Hardware controller / Android APK validation and a physical right-button
|
||
drag were unavailable through this browser session. Drag lifecycle and null
|
||
pointer-lock assertions passed in the input tests. Browser viewport screenshots
|
||
are scaled by the in-app compositor; DOM geometry supplied the viewport checks.
|
||
|
||
## 2026-09-10 - Original spell media defaults and visual fallback
|
||
|
||
- Original spell visuals and authentic sounds are enabled by default. The original media pack is prepared before gameplay; download failure leaves generated visuals available and missing sounds silent.
|
||
- Saves using the previous generated-only default migrate once to original media while retaining quality, group visibility, mute, and volume settings. Explicit later preferences remain saved.
|
||
- Removed synthesized combat audio. Original mode now uses generated visuals when no original phase is mapped or when all original graphs/textures for that phase fail to load; usable original layers remain preferred.
|
||
- Validation: 64 targeted tests passed, covering defaults, persistence migration, media installation/retry, rendering selection, original audio playback, silence on missing/invalid audio, and existing effect lifecycles. Production TypeScript and Vite build passed after correcting the installer test mock type; prebuild content/asset checks also passed.
|
||
- Browser verification used the production CombatEffects and OriginalCombatEffect components with isolated store/media fixtures and the actual packaged Flash Heal graph/textures. The original case rendered one original emitter and zero generated emitters. Unmapped spell, graph HTTP 404, and texture HTTP 404 cases each rendered zero original emitters and one visible generated effect. Combat reset removed the fallback.
|
||
- Evidence: playtest-artifacts/spell-media-20260910/original.png, bad-graph.png, bad-texture.png, and missing.png. The first Vite preview timed out; the bundled isolated preview completed successfully. This was an effect-focused browser check, not a full dungeon or device audio audition.
|
||
- Final release check: blocked by existing trailing whitespace in server/generated/arena-combat-runtime.mjs. The files changed for spell media pass the whitespace check; the unrelated generated arena file was left intact.
|
||
|
||
## 2026-09-10 - All regular dungeons bundled with lossless shared storage
|
||
|
||
- Web and Android packaging include all 84 regular dungeons and their asset dependencies. Shared Manastorm maps are stored once while every Manastorm pack keeps its optional install flag. Manastorm-only maps remain outside the initial package.
|
||
- Packaged assets fell from 3,440,440,928 logical bytes to 1,600,690,686 stored bytes, including 179,063,519 bytes saved by sharing exact duplicate files. No source models, texture resolutions, animations, or audio were changed or generated.
|
||
- Gzip representations retain both compressed and original SHA-256/size metadata. Publishing keeps original remote objects for older clients. Browser installs verify both representations, retain compressed shared objects with small aliases, and preserve shared objects until their final pack is removed. Native optional downloads remain resumable and verify their expanded originals before activation.
|
||
- Android's packager automatically expanded and renamed .gz files; final objects use .gzip with noCompress instead. Added an APK verifier to the normal Android build workflow, checking every object, every original hash, exact object inventory, and the 84-dungeon/optional-Manastorm boundary.
|
||
- Final debug APK: 1,622,100,512 bytes. All 9,106 unique objects (9,194 logical asset references) passed verification from inside the actual APK. Verification report and test APK: artifacts/dungeon-texture-audit-20260910/apk-verification.json and healer-man-0.1.28-debug.apk.
|
||
- Validation: production TypeScript/Vite build and asset checks passed; 80 targeted content, Downloads, and avatar tests passed across the final runs, plus nine publisher/server tests. Android Java compilation and assembleDebug passed. Existing bundle-size/import advisories remain.
|
||
- Live production browser check used an isolated offline Gziphealer character. Roster and Deadmines rendered the player body, party bodies, equipped weapon silhouettes, and textured dungeon geometry using the bundled compressed objects. Downloads showed all regular dungeon packs included and 75 Manastorm rows not installed. Evidence: artifacts/dungeon-texture-audit-20260910/roster-final.png, deadmines-final.png, and downloads-dom.txt. No new console errors appeared in the final-format dungeon run.
|
||
- A concurrent build replaced the shared dist directory during the first preview, causing temporary asset 404s. Repeated visual validation against an isolated build completed successfully. Deadmines displayed a route-blocked party status at its entrance; this was a loading/rendering check, not a full dungeon traversal. Physical Android hardware was not exercised.
|