Compare commits

...
4 Commits
Author SHA1 Message Date
phenom ccc01396cd Release Healer Man 0.1.43 2026-09-14 13:20:20 -04:00
phenom c7e8163790 Release Healer Man 0.1.42 2026-09-13 15:48:12 -04:00
phenom c3f8a69b51 Release Healer Man 0.1.41 2026-09-13 15:09:35 -04:00
phenom 197a64117c Release Healer Man 0.1.40 2026-09-13 13:21:27 -04:00
288 changed files with 9141 additions and 472 deletions

No files matched your search

+433
View File
@@ -4,6 +4,30 @@ 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-14 Ability hover tooltips
- Entered Stormwind Stockade with the existing offline level-17 Priest through
the normal roster, dungeon, and role screens. Hovering Smite on the controller
bar displayed its description, Mana cost, cast time, cooldown, range, and
target. Leaving the button removed the tooltip.
- Opened Ability controls and its ability picker. Hovering Shadow Word: Pain
displayed its own description without assigning it. Flash Heal was readable
by hover and keyboard focus despite its level-20 lock. Switching from keyboard
inspection to another hovered ability left exactly one tooltip visible.
- Checked the picker at the default 650 x 490 viewport and at 1280 x 800.
Tooltip DOM bounds remained inside the viewport. The in-app screenshot
scales unusually with a viewport override; reset the override afterward.
- Enabled desktop bars in an unsaved UI-layout draft. Hovering the leftmost
Smite button showed the tooltip above the bar, clamped to the left edge and
outside the HUD's transformed layout container. Discarded the layout draft.
- A temporary Flash Heal assignment during input testing was restored to the
original Smite assignment. No character or template was created or deleted.
- Screenshot evidence: `playtest-artifacts/ability-tooltips/desktop-bar.png`
and `playtest-artifacts/ability-tooltips/locked-picker.png`.
- Automated verification: all 64 UI tests passed, including nine tooltip
content, unavailable-control, and viewport-placement regression tests.
TypeScript, the production build, and the release candidate check passed.
## 2026-09-10 Personal UI templates and desktop action bars
- Opened Wailing Caverns through the normal offline roster, dungeon, and role
@@ -2879,3 +2903,412 @@ Vite's existing large-chunk advisory remains informational.
tests plus the real-combat integration test passed. The 432-test focused
combat/party/class/health/input regression suite and 18 server tests passed.
Production build, final TypeScript check, and release candidate check passed.
## 2026-09-13 - RoM character nameplate class labels
- RoM overhead nameplates and AI party frames now show the active class alone,
or primary/secondary class names joined with `/`, without race or `Primary`.
- An isolated local fixture using the real scene, party frames, and shared
character preview verified `Warrior`, `Priest`, and `Priest/Warrior` labels.
The two-class dungeon screenshot showed the label above the rendered body
and equipped staff silhouettes. The roster preview also retained its body
and equipment. The fixture used in-memory identities without saving a roster.
- Evidence: `artifacts/rom-nameplates/dungeon-dual-class.png` and
`artifacts/rom-nameplates/roster-preview.png`.
- Validation: 70 avatar, party-store, and mob-nameplate tests passed. Production
build, asset audits, compression/bundle verification, and release check passed.
## 2026-09-13 - Dungeon boss durability and difficulty leaderboards
- Campaign bosses now use a level-scaled health floor above their original
health when needed. Final bosses receive an additional 1.8 multiplier on
that floor. Larger authored health values remain effective.
- The dungeon browser offers a 1-10 boss difficulty slider, native keyboard
adjustment, and controller decrement/increment buttons. Difficulty 1 is
Easy; each step adds 25% health and 15% damage to bosses. The selected source
Normal/Heroic variant also applies to entry. Trash retains its existing stats.
- Boss difficulty is fixed at entry, preserved through saves and renderer
restarts, and passed from the online group leader to followers. Changing
difficulty starts a new run; completed checkpoints also start fresh.
- Device and world leaderboards isolate each difficulty's final/full-clear
records, ranks, and pages. Existing records migrate to a separate legacy
bracket. Migration and repeat submissions were verified against SQLite;
HTTP tests verify difficulty selection and reject invalid values.
- Deterministic Ragefire simulations tested 12 RoM party compositions at levels
1, 8, 20, 40, and 80 against the shared runtime scaling function. All ordinary
boss samples exceeded 25 seconds and final-boss samples exceeded 45 seconds.
Additional damage-role Mage samples passed those bounds; at level 8 the
ordinary boss took 29.8 seconds and the final boss took 55 seconds. Timings
remain dependent on party composition, player actions, and equipment.
- A final-boss fight with enemy attacks and Priest healing verified repeated
attacks, incoming damage, healing, and party survival before the boss died.
Balance evidence: `artifacts/boss-difficulty/ragefire-balance.json`.
- Desktop screenshots at 1280x720 verified the Easy and difficulty-10 layouts,
stat preview, and matching leaderboard labels. Pointer and keyboard changes
were exercised. At 390x844 the slider remained operable and its DOM width
stayed within the viewport, but the in-app browser's viewport-override
screenshots scaled incorrectly, as in the earlier compact playtest. Those
captures do not establish mobile visual quality. The viewport was restored.
- Validation: 169 focused game/client/UI tests and 20 server tests passed.
The production build, asset audits, bundle verification, and release check
passed. Existing RoM nameplate changes were retained.
## 2026-09-13 - Original WoW dungeon atlas
- Added 107 unique original map images across 51 standard WoW dungeons using
the supplied patch-enUS-M archive and existing client archives. A duplicated
Trial of the Champion floor record is deduplicated before packaging. The
source MPQs and Mapster addon were read without modification; no Lua addon
code is installed into HealerMan.
- Coordinate inverses were checked against 10,342 matching source spawns and
the event-driven Trial of the Champion source entrance. Maximum discrepancy
is 0.189 yards in authored Wailing Caverns rounding; other imported maps
have substantially smaller discrepancies. All 107 image checksums match
their local immutable content objects.
- The production preview at localhost:5174 loaded Wailing Caverns and showed
original artwork with the player/camera direction, entrance, numbered
encounters, and a 45.7%, 60.5% entrance-position readout. The map was visually
reviewed at 1280x720, with the rendered dungeon visible behind it. Pressing
M opened it; toggling patrol routes then pressing M closed it despite the
checkbox retaining focus. Reopening restores the clean default overlay.
- Evidence: `artifacts/wow-maps/wailing-caverns-atlas.png`. No production-preview
errors were captured in the bounded console check. Earlier development HMR
errors from concurrent equipment edits were not treated as production errors.
Testing used the existing offline Hudtest QA character, not a live account.
- Multi-floor rendering, floor controls, rebound shortcuts, repeat/capture
guards, PNG dimensions/checksums, axis projection, shifted/rotated scene
transforms, and RuneWaker survey fallback are covered by automated tests.
Every dungeon was not individually traversed in the browser. Auto floor
selection is horizontal best fit, not WMO-group/height detection; overlapping
stacked rooms require manual floor selection. Mobile hardware was not tested.
- Tinkertech Showdown, Frozen Reach, and Forgotten Mine have no matching
artwork records and retain their survey maps. RuneWaker maps are unchanged.
Failed artwork loads also retain a correctly reprojected survey fallback.
- Validation: 50 focused map/UI/input tests and three BLP/tile-layout tests
passed. The production build, texture/performance audits, and compressed
release-bundle verification passed. Local downloadable packs were published;
no online deployment was performed.
## 2026-09-13 - Boss card collection and leveling loot
- Boss deaths roll a guaranteed Normal card plus independent Rare (1/10),
Epic (1/50), and Legendary (1/100) bonuses. The collection catalogue covers
330 distinct WoW/RoM bosses and 1,320 rarity variants using existing models.
Repeated appearances share counts and list every source dungeon.
- Copies and the latest claim per boss spawn persist per character through the
roster/cloud-save path. Shared-world hydration grants the authority's rolls
to followers and ignores duplicate/reconnected and older reward snapshots.
- Equipment drops and bonus equipment are suppressed below player level 80;
existing inventory and authored non-equipment drops are preserved. Level-80
equipment loot remains enabled. Bosses without equipment tables award cards.
- The production browser at 1280x720 verified the main-menu entry, all four
Lady Anacondra model portraits, dungeon location, odds, search, All/Earned,
dungeon/rarity grouping, and in-dungeon pause-menu access. Roster and dungeon
screenshots show player/party bodies and starter weapon/shield silhouettes.
- At 390x844 the collection switched to two columns, with no horizontal page
overflow and dialog bounds within the viewport. The in-app browser again
scaled the viewport-override screenshot incorrectly; that capture does not
establish mobile visual quality. The viewport was restored.
- Deterministic tests cover exact odds boundaries, counts, persistence,
no-loot-table bosses, loot restrictions, and online replay. Live browser QA
did not perform a boss clear; earned-copy display was checked with seeded
render tests. Evidence: `artifacts/boss-cards/collection-desktop.png`,
`collection-mobile.png`, `roster.png`, and `dungeon.png`.
## WoW and CoA default boss difficulty review — September 13, 2026
- Reviewed all 10 WoW and 21 CoA classes: 61 canonical class-role builds at
levels 8, 20, 40, and 80 with three deterministic companion compositions.
The 1,464 durability simulations used live boss scaling, starter heirlooms,
legal level-appropriate talents, live companion AI, and the existing baseline
player rotation. CoA characters currently use WoW companions.
- Fixed Death Pact and other instant-kill effects bypassing boss health in the
player, triggered-spell, and companion paths. Fixed repeated proc activations
across branches, duplicate execution of expanded CoA payloads, invented
damage on proc auras and Waterfall, and critical-damage talent bonuses
affecting ordinary hits. Regenerated the CoA runtime catalog and shards.
- Raised the shared health floor by 40% to cover the remaining CoA burst.
Every class uses the same boss stats at the same level and difficulty.
Fastest sampled kills were 26.2 seconds for an ordinary boss and 48.6 for
the final boss. All duration assertions passed. The refreshed RoM regression
also passed; its level-eight damage-role Mage sample took 41.8/74.9 seconds.
- Durability samples disabled enemy attacks and stopped at 60 seconds to
isolate damage. Most WoW and CoA samples still had a living boss at the cap;
these are lower bounds, not proof of typical 25-30/45-second kill times.
Default class throughput is still uneven, especially for WoW parties.
- An additional 26 final-boss attack samples exercised healer builds at levels
8 and 80. Paladin, Priest, Shaman, and Tinker kept their parties alive in both.
Druid and several CoA samples lost companions; Bloodmage also lost the player
at 80. This basic policy can refresh HoTs too early or choose self-healing
hybrids, so these outcomes need a dedicated healer rotation/playtest pass
before treating them as class throughput limits. No live boss clear was
performed in this numerical review.
- Validation: 122 combat/catalog checks, 91 class-damage/avatar checks, eight
RoM boss regressions, TypeScript, and the production build passed. All six
large-matrix assertions passed, but its progress reporter timed out during
CPU-heavy loops. Added worker yields and reran the affected level-40 test;
it exited cleanly without the reporter error.
- Evidence: `artifacts/boss-difficulty/wow-coa-balance.json` and
`artifacts/boss-difficulty/wow-coa-review.md`. Coverage is a canonical build
per role with starter gear, rather than every specialization or later gear
combination. `npm run release:check` is required for handoff.
## CoA healer rotation pass — September 13, 2026
- Corrected base-mana percentage costs, Tinker's secondary mana maximum,
imported heal power/AP/spirit scaling, self-healing riders, and party heal
recipients. Removed invented instant heals from conditional procs and
invented hostile damage from healing/mitigation tooltip text. Regenerated
the CoA runtime catalog and all class shards.
- Companion support AI maintains existing HoTs, covers other injured allies,
and avoids redundant shields. The benchmark player policy now prefers
effective emergency/area healing, avoids wasteful self-healing, positions
ground heals on the injured ally, and funds rage heals through weapon attacks
and actual resource generators. Normal gameplay still uses player input.
- Tested nine canonical CoA healer builds at levels 8, 20, 40, and 80 against
final-boss attacks for 60 seconds with three deterministic WoW companion
compositions each: 108 samples. Every player survived and every sample
delivered effective ally healing. Entire-party survival was 24/27 at eight,
25/27 at twenty, and 27/27 at both forty and eighty.
- The remaining low-level losses are Primalist companions. Its imported Geode
Barrage lacks the server-scripted stone/rage payload; that mechanic still
needs implementation. Survival at the time cap does not establish a boss
clear, indefinite mana sustainability, or complete CoA mechanic parity.
- Reran the full WoW/CoA durability and healer-attack suite: all six assertions
passed without reporter errors. Fastest sampled ordinary/final kills remain
26.2/48.6 seconds. WoW Druid's comparable eight/eighty attack samples now keep
the party alive with the revised HoT policy.
- Validation: 167 combat/catalog/runtime regressions, four healer matrix
assertions, 47 avatar checks, TypeScript, the production build, and release
bundle validation passed. The final release hygiene check covers untracked
regression tests as well as tracked edits.
- Live production-preview smoke check at 1280x720 used an offline Human Witch
Doctor (Brewing). Roster and Wailing Caverns entrance captures show the
player and companion bodies and starter weapon/shield silhouettes. This
visual check did not perform a live boss clear or validate manual rotations.
Evidence: `artifacts/boss-difficulty/coa-healer-smoke/roster.png` and
`artifacts/boss-difficulty/coa-healer-smoke/dungeon.png`.
- Numerical evidence and remaining limitations:
`artifacts/boss-difficulty/coa-healer-balance.json`,
`artifacts/boss-difficulty/wow-coa-balance.json`, and
`artifacts/boss-difficulty/coa-healer-review.md`.
## Primalist rage generation follow-up — September 13, 2026
- Restored Geode Barrage's three physical stone pulses at cast completion,
+500ms, and +1000ms, using the ranked parent amount, 23% nature/spell power,
and 9% attack power. Each pulse dealing effective damage grants its caster
5 rage, for 15 from a full Barrage. Removed the unscheduled hidden placeholder
proc so another periodic event cannot substitute for or duplicate the stones.
- The 5-rage stone amount is HealerMan's normalization using the related
imported Geode spell 804002 payload. Barrage's imported DBC does not expose
an exact rage amount; this does not establish exact server-script parity.
Dead targets and fully absorbed stones grant no rage. Player and companion
grants cap at the source pool maximum and synchronize the actor's pools.
- Seismic Crash grants 20 rage once per cast and executes its initial damage
pulse. Seismic Spike grants 4 per target actually damaged. Primalist energize
effects retain their power type and convert internal rage units to displayed
points: Primal Rush and passive Protective Roar grant 20 rather than 200.
Protective Roar retains beneficial party recipients when its payload fires.
- Scoped imported power-unit conversion to Primalist. A global conversion
caused a Bloodmage survival regression; other classes retain their existing
script-payload interpretation pending their own power-record review.
- The benchmark policy considers all usable rage generators, including Crash
and Barrage, before rage heals. Normal gameplay still uses player input.
All 108 attacking-final-boss CoA healer samples now keep the entire party
alive, including the five previously failing low-level Primalist samples.
The regression requires zero companion deaths at every tested level.
- Validation: 207 combat/catalog/runtime/avatar checks passed, including eight
focused Primalist checks for timing, coefficients, capped gains, absorbed and
dead targets, companion attribution, passive payloads, and Seismic gains.
All four strict healer matrix assertions passed. All six WoW/CoA boss suite
assertions passed across 1,464 durability runs and 26 attacking-boss samples;
fastest sampled ordinary/final kills remain 26.2/48.6 seconds. TypeScript,
the production build, release bundle validation, and release hygiene passed.
- Live production-preview smoke check at 1280x720 used an offline female
Tauren Primalist (Life). Roster and Wailing Caverns entrance captures show
a character body with a staff and companion bodies with weapon silhouettes.
The Tauren identity rendered a human-looking fallback; the optional content
service was unavailable in this static preview. These captures establish
body/equipment visibility, not correct Tauren appearance. Entrance trash
reached level two with the full party alive. Barrage remained locked until
level six, so pulse/rage behavior was checked by deterministic runtime tests,
rather than a live manual Barrage cast. No live boss clear was performed.
- Evidence: `artifacts/boss-difficulty/primalist-smoke/roster.png`,
`artifacts/boss-difficulty/primalist-smoke/dungeon.png`,
`artifacts/boss-difficulty/coa-healer-balance.json`,
`artifacts/boss-difficulty/wow-coa-balance.json`, and
`artifacts/boss-difficulty/coa-healer-review.md`. Survival at the 60-second
cap does not establish a boss clear or indefinite resource sustainability.
## WoW action bars in Ability controls — September 13, 2026
- Added Controller bars / WoW bars selection to Ability controls. On PC, the
dialog opens on WoW bars when that UI layout is enabled. The existing three
controller layers remain available through the same screen.
- The WoW editor exposes all five bars and twelve buttons per bar, including
inactive bars. Slots show their saved keyboard shortcuts and assigned
abilities. Assigning or leaving a slot empty saves immediately through the
existing profile UI persistence path and updates the gameplay action bar.
- Restore Bar resets that bar's abilities to the current character's class
defaults; Restore all WoW bars resets all sixty ability slots. Both use a
confirmation with cancellation. Keyboard shortcuts, bar geometry, PC/mobile
UI templates, and controller bindings remain independent of these resets.
- Long WoW ability lists scroll inside the picker. Controller navigation keeps
the selected control visible. Future abilities retain their unlock-level
labels and can be assigned ahead of time; passive abilities are excluded.
- Live 1280x720 production-preview QA used an isolated offline Human Priest
profile at port 5192. Verified first-slot assignment, inactive fifth-bar
button-twelve assignment and clearing, canceling a reset, restoring one bar
while retaining the fifth-bar assignment, and restoring all WoW bars.
Controller Cross retained Smite through the WoW edits and resets.
- Enabled the WoW layout through Edit UI & templates, confirmed Ability controls
opened directly on WoW bars, and changed the first button to Lesser Heal.
The gameplay bar updated immediately. After a full page reload and dungeon
reentry, both the gameplay bar and editor retained Lesser Heal and key 1.
The final picker capture shows access to the late-level abilities and Leave
empty while all bar controls stay visible. No browser UI errors were logged.
- Validation: all 55 UI-layout, action-binding, keybind, profile-sync, input,
HUD-layering, and panel-integration tests passed. The production build,
including TypeScript with the project's configured 8 GB heap, prebuild asset
audits, and postbuild release-bundle validation, passed. A separate manual
TypeScript attempt using Node's default heap exhausted memory; the standard
build completed successfully. Final release hygiene covers all changed paths.
- Evidence: `artifacts/ability-controls/wow-bars.png`,
`artifacts/ability-controls/controller-bars.png`,
`artifacts/ability-controls/wow-picker.png`, and
`artifacts/ability-controls/wow-picker-end.png`. Cloud upload and physical
gamepad input were not exercised by this offline browser pass.
## Account-wide boss card collections — 2026-09-14
- Moved boss card counts and reward receipts out of character profiles into one
collection per account owner. Gameplay starts with that account collection;
menu and in-game collection screens show the same account totals.
- Migrates existing character logs by summing their rarity counts, retaining the
newest reward receipts, and removing the old character fields. Reloading or
downloading an old cloud roster again does not repeat the migration.
- Cloud uploads now include the account collection, including accounts with an
empty roster. Migrated cloud logs upload without waiting for another boss kill.
Higher cached counts and newer receipts survive an older cloud download.
- Automated integration checks verified earning on a second character,
switching back, account sign-out isolation, character deletion, and restoration
into a separate device cache. Collection markup identifies the account scope.
- Validation: 164 tests passed across 19 files, with six shelved-mode tests
skipped. This persistence change did not alter character models or equipment.
- TypeScript, prebuild asset audits, and release hygiene passed. The first
shared-output bundle check encountered a missing staged asset; an isolated
production build and complete bundle check passed with all 5,529 objects.
Validation output is under `artifacts/boss-cards/account-build`.
## Main-menu talents and controls — 2026-09-14
- Added Talents, Keybinds, and Button assignments destinations using the existing
editors. RoM characters show their automatically ranked Skills instead of
a talent-point editor. Closing a panel or using Back returns to the main menu.
- A menu-only character subscription initializes the selected character and
saves talent ranks and controller ability assignments without mounting the
dungeon simulation. Level, experience, inventory, and equipment are preserved.
Keyboard bindings and WoW bar assignments retain the existing profile saving
behavior; keybind drafts require Save changes.
- Live offline browser QA at 1280x720 opened all three editors for the level-17
Priest Rolecheck. The talent tree showed eight available points, controls
showed the character's skill names, and the assignment picker showed current
Smite and future unlock levels. Canceling a keybind edit and using Done returned
correctly; Escape first canceled the ability picker and then closed the editor.
This browser pass did not change the character's build or saved controls.
- At a 390x844 viewport, the talent dialog's measured bounds fit the screen,
with no horizontal content overflow and a visible main-menu Back button.
Browser screenshot scaling was unreliable at this override; visual evidence
below covers the default desktop viewport. Physical gamepads and cloud saves
were not exercised.
- Persistence tests cover allocation, reset, assignment, reopening, storage
failure, and owner/selection/phase/close isolation. UI and profile regressions
passed. TypeScript, production bundling, and complete release-bundle validation
passed after retrying a shared-output staging race; release hygiene passed.
- Evidence: `playtest-artifacts/main-menu-editors/main-menu.png`,
`playtest-artifacts/main-menu-editors/talents.png`,
`playtest-artifacts/main-menu-editors/keybinds.png`, and
`playtest-artifacts/main-menu-editors/button-assignments.png`.
## AYN Thor physical-size UI review — 2026-09-14
- Browser profiles use the Thor's 6-inch 1920x1080 upper panel and 3.92-inch
1240x1080 lower panel. Panel sizes come from
[AYN's specifications](https://www.ayntec.com/products/ayn-thor); resolutions
are also documented in the
[Thor manual](https://ae-pic-a1.aliexpress-media.com/kf/S21d979b6c8d840ddaebfeb976094e0cfP.pdf).
Derived physical rectangles are 132.8x74.7 mm and 75.1x65.4 mm. At a common
160 CSS pixels per inch, browser viewports are 837x471 and 473x412, with
independent device scale factors. A 44-pixel control represents about 7 mm
on either panel. The combined preview uses these relative physical sizes.
- Dungeon defaults put party/self health, targets, minimap, and encounter
information upstairs. Controller actions, cast bar, buffs/debuffs, experience,
and DPS meter appear downstairs. Shared HUD components render once on their
assigned panel; the old duplicate tactical party-health panel is replaced.
- Every HUD element has Top / Bottom / Hidden in the mobile UI editor. Touch
dragging from the lower page updates the upper page's authoritative draft.
Selection raises the widget above overlapping controls. Save, cancel,
reset, rapid reopening, and a full reload/dungeon reentry were verified.
Legacy templates without a screen field retain their defaults. Single-screen
play keeps visible elements on its primary display.
- Enlarged text, icons, and touch controls; corrected roster, creator, class
hall, downloads, and dungeon/role layouts for the actual panel dimensions.
Character creation uses the lower model preview. Editor controls scroll with
Save and Cancel kept visible. Buff tooltips and the completion banner use
readable text; a lower-screen completion banner wraps its buttons below it.
- Edge browser QA uses two Android/touch-emulated pages in one isolated offline
context. BroadcastChannel carries actual snapshots and touch commands between
pages. Covered login, empty/populated roster, both creation steps, main menu,
class hall, menu talents/keybinds/button assignments, reports, downloads,
dungeon/role selection, gameplay, pause, map, party, boss guide, spellbook,
talents, ability controls, inventory, boss cards, options, keybinds, issue
reporting, UI editor, defeat/respawn, completion/results, and combined preview.
- Verified lower action casting changes the upper combat cooldown; party frames
can move downstairs, hide, save, reload, and select the player remotely.
Buff inspection opens by touch. Results open automatically and can reopen
from the banner; finishing through the lower banner returns both pages to
the main menu. Completion uses an isolated presentation fixture, rather than
a live boss clear. Dungeon captures include equipped fallback bodies; this
review does not establish authentic race-model loading.
- All 42 layout, keybind, HUD-layering, display, snapshot, and dual-screen
regressions passed. A complete production build with asset audits and release
bundle validation passed; final UI edits also passed production compilation.
Browser captures have no unscrollable controls clipped outside their panel
and no uncaught UI errors. Physical hardware, Android WebView installation,
live online grouping, and shelved game modes were not exercised.
- Reproduce with `node scripts/playtest-thor-ui.cjs` while Vite runs at port
5176, or set `THOR_TEST_URL`. Evidence is in
`playtest-artifacts/thor-ui/results.json` and paired PNGs, including
`14-final-defaults`, `14d-results`, `14e-complete-bottom`, and
`15-combined-preview.png`.
## Boss Testing (2026-09-14)
- Main menu now opens a searchable boss catalog with game and readiness
filters, selected-boss fights, and random fights. Selecting a boss installs
its missing dungeon content pack and dependencies automatically.
- Testing uses an empty procedural room with one initial boss. Existing
combat, encounter phases, summoned adds, and relevant mechanic objects are
retained. Tests grant no experience, loot, or boss cards, and do not persist
changes to the character's progression or inventory.
- Pause and victory review offer Ready, Needs testing, and Not ready labels,
boss-specific reports, retry, and return to the main menu. Labels persist
through the server, with local pending saves retained while offline.
- Regression checks passed: 98 focused client tests, 19 server tests, and a
complete production build with asset audits and release bundle validation.
- Production Edge playtest passed selection, active Lady Anacondra mechanics,
all three readiness labels, report submission, retry, victory review,
persistence, random selection, and a 390-pixel mobile layout without
horizontal overflow. Victory uses deterministic damage through the combat
store; this is not a natural full-fight clear. Experience and saved character
data were unchanged, and no uncaught browser errors occurred.
- Selecting Taragaman the Hungerer from an uninstalled Ragefire Chasm pack
downloaded the pack and dependencies, then loaded the boss model and active
mechanics in the test room. A second browser page received the testing room
snapshot and opened boss review through the lower-display button. Physical
dual-screen hardware was not exercised.
- Reproduce with `node scripts/playtest-boss-testing.cjs`; the script starts
an isolated production server and test database. Evidence is in
`playtest-artifacts/boss-testing/results.json` and screenshots
`01-main-menu.png` through `12-bottom-display-review.png`.
@@ -139,6 +139,8 @@ public class ThorDualScreenPlugin extends Plugin implements DisplayManager.Displ
if (forceEnabled) scheduleEnsurePresentation(300L);
});
presentation.show();
bridge.getWebView().getSettings().setUseWideViewPort(true);
bridge.getWebView().getSettings().setLoadWithOverviewMode(true);
bridge.getWebView().loadUrl(currentUrl);
}
@@ -279,6 +281,8 @@ public class ThorDualScreenPlugin extends Plugin implements DisplayManager.Displ
WebSettings settings = webView.getSettings();
settings.setJavaScriptEnabled(true);
settings.setDomStorageEnabled(true);
settings.setUseWideViewPort(true);
settings.setLoadWithOverviewMode(true);
settings.setDatabaseEnabled(true);
settings.setMediaPlaybackRequiresUserGesture(false);
settings.setAllowFileAccess(true);
+48
View File
@@ -0,0 +1,48 @@
# WoW dungeon atlas
Press **M** in a loaded WoW dungeon to open its original game map. The atlas
shows a white player marker with camera direction, a green entrance, and gold
numbered encounter markers. Patrol routes are optional. The minimap and companion
map use the same artwork and coordinate projection.
Multi-floor dungeons have a floor selector. Auto chooses the smallest containing
map rectangle; it is a horizontal best fit, not the WoW client's WMO-group floor
detection. Select a floor manually when stacked rooms overlap. Coordinates outside
the selected floor are not clamped to a misleading marker at the map edge.
The current import includes 51 standard WoW dungeons and 107 unique map images. The
custom Tinkertech Showdown, Frozen Reach, and Forgotten Mine have no matching map
records in the supplied archives and retain their survey maps. RuneWaker maps are
unchanged. Missing images also fall back to the survey projection.
## Reimporting
Run `npm run dungeon:maps:import` from the HealerMan project root. An optional
archive argument replaces the default `../downloads/patch-enUS-M.MPQ`.
`WOW_CLIENT_ROOT` supplies the client archives for original Wrath map tiles;
`WOW_DUNGEON_WORK_ROOT` supplies runtime drafts for alignment checks. Defaults
are `../wow335a` and `../HealerMan-Storage/pipeline-work/dungeons`.
The importer reads the patch and client archives without modifying them. It
decodes BLP2 tiles into cropped 1002x668 PNGs, reads WorldMapArea/DungeonMap bounds,
and inverts the reviewed scene coordinate mapper, including shifted ADT packages
and rotated global WMOs. It verifies alignment against imported creature spawns
or the source entrance for an event-driven arena without static actors.
Wailing Caverns retains its authored coordinate convention.
Images live in `public/assets/game/dungeons/<id>/maps/`, so existing dungeon
content-pack rules include them. Runtime metadata is generated in
`src/game/generated/wowDungeonMaps.generated.json`; provenance and coverage are in
`dungeon-pipeline/WOW_DUNGEON_MAP_REPORT.json`. Changes to environment checksums or
coordinate conventions require reimporting. Mapster is a Lua WoW-client addon;
HealerMan does not execute or install it.
After reimporting, run `npm run content:publish` to update the local downloadable
content catalog and `npm run build` to refresh the bundled Wailing Caverns atlas.
Those commands prepare local artifacts; they do not deploy the online game.
## Verification
Run `npm test -- --run src/game/wowDungeonMap.test.ts src/ui/DungeonMapGraphic.test.ts src/ui/MapPanel.test.ts`
and `node --test scripts/lib/wow-map-image.test.mjs`. Visual evidence and observed
limitations are recorded in `PLAYTEST_NOTES.md`.
@@ -0,0 +1,388 @@
{
"source": "patch-enUS-M.MPQ",
"sourceSha256": "b69713077e19498d20efa5eeaefdba98850764db6bdc99e292bfbdf7b1c858d6",
"imported": [
{
"id": "shadowfang-keep",
"floors": 7,
"checkedSpawns": 109,
"checkedEntrances": 0,
"maxAlignmentError": 0
},
{
"id": "stormwind-stockade",
"floors": 1,
"checkedSpawns": 93,
"checkedEntrances": 0,
"maxAlignmentError": 0.00004000000000026205
},
{
"id": "deadmines",
"floors": 2,
"checkedSpawns": 179,
"checkedEntrances": 0,
"maxAlignmentError": 0.00005830951894693099
},
{
"id": "wailing-caverns",
"floors": 1,
"checkedSpawns": 251,
"checkedEntrances": 0,
"maxAlignmentError": 0.188595526192965
},
{
"id": "razorfen-kraul",
"floors": 1,
"checkedSpawns": 179,
"checkedEntrances": 0,
"maxAlignmentError": 0.00006573939954203296
},
{
"id": "blackfathom-deeps",
"floors": 3,
"checkedSpawns": 201,
"checkedEntrances": 0,
"maxAlignmentError": 0.00004999999999988347
},
{
"id": "uldaman",
"floors": 2,
"checkedSpawns": 302,
"checkedEntrances": 0,
"maxAlignmentError": 0.00004999999999988347
},
{
"id": "gnomeregan",
"floors": 4,
"checkedSpawns": 371,
"checkedEntrances": 0,
"maxAlignmentError": 0
},
{
"id": "sunken-temple",
"floors": 3,
"checkedSpawns": 244,
"checkedEntrances": 0,
"maxAlignmentError": 0.00004999999999988347
},
{
"id": "razorfen-downs",
"floors": 1,
"checkedSpawns": 192,
"checkedEntrances": 0,
"maxAlignmentError": 5.084354071042896e-13
},
{
"id": "scarlet-monastery",
"floors": 4,
"checkedSpawns": 310,
"checkedEntrances": 0,
"maxAlignmentError": 0.00004999999999988347
},
{
"id": "zulfarrak",
"floors": 1,
"checkedSpawns": 251,
"checkedEntrances": 0,
"maxAlignmentError": 0.00004999999999988347
},
{
"id": "blackrock-spire",
"floors": 7,
"checkedSpawns": 565,
"checkedEntrances": 0,
"maxAlignmentError": 0.00004999999999988347
},
{
"id": "blackrock-depths",
"floors": 2,
"checkedSpawns": 1040,
"checkedEntrances": 0,
"maxAlignmentError": 0.00004999999999988347
},
{
"id": "scholomance",
"floors": 4,
"checkedSpawns": 327,
"checkedEntrances": 0,
"maxAlignmentError": 0.00009095950916596921
},
{
"id": "stratholme",
"floors": 2,
"checkedSpawns": 430,
"checkedEntrances": 0,
"maxAlignmentError": 9.096057172999542e-13
},
{
"id": "maraudon",
"floors": 2,
"checkedSpawns": 525,
"checkedEntrances": 0,
"maxAlignmentError": 0.00004999999999988347
},
{
"id": "ragefire-chasm",
"floors": 1,
"checkedSpawns": 127,
"checkedEntrances": 0,
"maxAlignmentError": 0.00004999999999988347
},
{
"id": "dire-maul",
"floors": 6,
"checkedSpawns": 755,
"checkedEntrances": 0,
"maxAlignmentError": 0.00006403124240144967
},
{
"id": "shattered-halls",
"floors": 1,
"checkedSpawns": 198,
"checkedEntrances": 0,
"maxAlignmentError": 0.00006403124237426248
},
{
"id": "blood-furnace",
"floors": 1,
"checkedSpawns": 139,
"checkedEntrances": 0,
"maxAlignmentError": 0.00006403124237384636
},
{
"id": "hellfire-ramparts",
"floors": 1,
"checkedSpawns": 85,
"checkedEntrances": 0,
"maxAlignmentError": 0.00006753673068807912
},
{
"id": "steamvault",
"floors": 2,
"checkedSpawns": 127,
"checkedEntrances": 0,
"maxAlignmentError": 0.00004999999999988347
},
{
"id": "underbog",
"floors": 1,
"checkedSpawns": 161,
"checkedEntrances": 0,
"maxAlignmentError": 0.0000617170964964256
},
{
"id": "slave-pens",
"floors": 1,
"checkedSpawns": 122,
"checkedEntrances": 0,
"maxAlignmentError": 0.0000640312423744012
},
{
"id": "arcatraz",
"floors": 3,
"checkedSpawns": 84,
"checkedEntrances": 0,
"maxAlignmentError": 0.00004999999999988347
},
{
"id": "botanica",
"floors": 1,
"checkedSpawns": 171,
"checkedEntrances": 0,
"maxAlignmentError": 0.00006403124237384636
},
{
"id": "mechanar",
"floors": 2,
"checkedSpawns": 84,
"checkedEntrances": 0,
"maxAlignmentError": 0.000046699999999996744
},
{
"id": "shadow-labyrinth",
"floors": 1,
"checkedSpawns": 189,
"checkedEntrances": 0,
"maxAlignmentError": 0.00006403124237426248
},
{
"id": "sethekk-halls",
"floors": 2,
"checkedSpawns": 104,
"checkedEntrances": 0,
"maxAlignmentError": 0.00005324368507145524
},
{
"id": "mana-tombs",
"floors": 1,
"checkedSpawns": 119,
"checkedEntrances": 0,
"maxAlignmentError": 0.000056568542495137386
},
{
"id": "auchenai-crypts",
"floors": 2,
"checkedSpawns": 93,
"checkedEntrances": 0,
"maxAlignmentError": 0.00005415025392387915
},
{
"id": "magisters-terrace",
"floors": 2,
"checkedSpawns": 147,
"checkedEntrances": 0,
"maxAlignmentError": 0.00007071067811848996
},
{
"id": "black-morass",
"floors": 1,
"checkedSpawns": 134,
"checkedEntrances": 0,
"maxAlignmentError": 0
},
{
"id": "escape-from-durnholde",
"floors": 1,
"checkedSpawns": 380,
"checkedEntrances": 0,
"maxAlignmentError": 0.00004999999999988347
},
{
"id": "utgarde-keep",
"floors": 3,
"checkedSpawns": 112,
"checkedEntrances": 0,
"maxAlignmentError": 0.00004700000000001925
},
{
"id": "utgarde-pinnacle",
"floors": 2,
"checkedSpawns": 83,
"checkedEntrances": 0,
"maxAlignmentError": 0
},
{
"id": "the-nexus",
"floors": 1,
"checkedSpawns": 234,
"checkedEntrances": 0,
"maxAlignmentError": 0.00004999999999988347
},
{
"id": "the-oculus",
"floors": 5,
"checkedSpawns": 112,
"checkedEntrances": 0,
"maxAlignmentError": 0
},
{
"id": "culling-of-stratholme",
"floors": 2,
"checkedSpawns": 209,
"checkedEntrances": 0,
"maxAlignmentError": 0
},
{
"id": "halls-of-stone",
"floors": 1,
"checkedSpawns": 76,
"checkedEntrances": 0,
"maxAlignmentError": 0
},
{
"id": "draktharon-keep",
"floors": 2,
"checkedSpawns": 99,
"checkedEntrances": 0,
"maxAlignmentError": 0.00004999999999988347
},
{
"id": "azjol-nerub",
"floors": 3,
"checkedSpawns": 70,
"checkedEntrances": 0,
"maxAlignmentError": 0
},
{
"id": "halls-of-lightning",
"floors": 2,
"checkedSpawns": 112,
"checkedEntrances": 0,
"maxAlignmentError": 0
},
{
"id": "gundrak",
"floors": 2,
"checkedSpawns": 85,
"checkedEntrances": 0,
"maxAlignmentError": 0
},
{
"id": "violet-hold",
"floors": 2,
"checkedSpawns": 8,
"checkedEntrances": 0,
"maxAlignmentError": 0
},
{
"id": "ahnkahet-old-kingdom",
"floors": 1,
"checkedSpawns": 133,
"checkedEntrances": 0,
"maxAlignmentError": 0.00004999999999988347
},
{
"id": "forge-of-souls",
"floors": 1,
"checkedSpawns": 41,
"checkedEntrances": 0,
"maxAlignmentError": 0
},
{
"id": "trial-of-the-champion",
"floors": 1,
"checkedSpawns": 0,
"checkedEntrances": 1,
"maxAlignmentError": 0
},
{
"id": "pit-of-saron",
"floors": 1,
"checkedSpawns": 167,
"checkedEntrances": 0,
"maxAlignmentError": 0.00004000000000026205
},
{
"id": "halls-of-reflection",
"floors": 1,
"checkedSpawns": 13,
"checkedEntrances": 0,
"maxAlignmentError": 0
}
],
"skipped": [
{
"id": "tinkertech-showdown",
"reason": "No matching WorldMapArea record"
},
{
"id": "frozen-reach",
"reason": "No matching WorldMapArea record"
},
{
"id": "forgotten-mine",
"reason": "No matching WorldMapArea record"
}
],
"coordinateSources": [
"WorldMapArea.dbc",
"DungeonMap.dbc"
],
"layoutSource": "https://github.com/wowgaming/3.3.5-interface-files/blob/main/WorldMapFrame.xml",
"archives": [
"patch-enUS-M.MPQ",
"patch-enUS-3.MPQ",
"patch-enUS.MPQ",
"patch-enUS-2.MPQ"
]
}
+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "healer-man",
"version": "0.1.39",
"version": "0.1.43",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "healer-man",
"version": "0.1.39",
"version": "0.1.43",
"dependencies": {
"@capacitor/android": "8.4.1",
"@capacitor/core": "8.4.1",
+2 -1
View File
@@ -1,7 +1,7 @@
{
"name": "healer-man",
"private": true,
"version": "0.1.39",
"version": "0.1.43",
"type": "module",
"scripts": {
"dev": "vite --host 0.0.0.0",
@@ -45,6 +45,7 @@
"dungeon:epoch:sync": "node scripts/dungeon-pipeline/sync-epoch-dungeons.mjs",
"dungeon:source:azerothcore": "node scripts/dungeon-pipeline/import-azerothcore-world.mjs",
"dungeon:catalog": "node scripts/dungeon-pipeline/compile-campaign-catalog.mjs",
"dungeon:maps:import": "node scripts/dungeon-pipeline/import-wow-maps.mjs",
"dungeon:canonicalize-environments": "node scripts/dungeon-pipeline/relink-canonical-environments.mjs",
"dungeon:dedupe-creatures": "node scripts/dungeon-pipeline/dedupe-shared-creatures.mjs",
"dungeon:test-creature-animation-policy": "node --test scripts/dungeon-pipeline/runtime-creature-animations.test.mjs",
Binary file not shown.

After

Width:  |  Height:  |  Size: 772 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 768 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 762 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 769 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 766 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 769 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 747 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 764 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 759 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 788 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 764 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 753 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 746 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 750 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 756 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 735 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 729 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 730 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 735 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 735 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 734 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 739 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 766 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 769 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 773 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 782 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 751 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 772 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 751 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 737 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 741 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 743 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 736 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 745 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 776 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 754 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 798 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 794 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 747 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 751 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 747 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 757 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 778 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 781 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 749 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 759 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 780 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 764 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 765 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 773 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 783 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 773 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 756 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 756 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 761 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 747 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 781 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 756 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 751 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 746 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 748 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 750 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 751 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 752 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 724 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 740 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 746 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 745 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 774 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 767 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 765 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 761 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 755 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 750 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 749 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 746 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 757 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 749 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 766 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 777 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 771 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 754 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 751 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 764 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 769 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 758 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 797 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 804 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 820 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 835 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 815 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 820 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 814 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 811 KiB

Loaded 100 of 288 files, more files were not shown because too many files have changed in this diff. Show more