fix(hud): restore authentic 1.13c monster hover nameplate, species/desc subtext, elite modifiers & immunities #559

Closed
opened 2026-10-02 10:08:02 +00:00 by troytt · 0 comments
Owner

Symptom

In play.html (screenshot https://screenshot-v2.corp.google.com/0ipug71f0k37o), hovering over a monster (e.g. Fallen, hcIdx = 19) displays raw MON_19 in white in the top-center lifebar, with no subtext below the bar (missing Demon / Undead, DescStr, elite modifiers, and immunities), and Elite/Champion/Unique/SuperUnique/Boss/Minion monsters do not display their authentic 1.13c names or colors.

Root Causes (1.13c Ground Truth)

  1. clientUnitToMonsterTargetInfo in src/client/ui-model/hud-model.ts is an unimplemented stub:
    • Calls monsterDisplayName(\mon_${unit.classId}`, 'ENG')which misses in.tbltables and returns'mon_19'(drawn asMON_19`).
    • Does not look up unit.classId (hcIdx 0..733) via MONSTER_HCIDX_TO_ID in MonStats.txt (readMonsterKinds for difficulty 0..2) or unit.superUniqueId in SuperUniques.txt (RAW_SUPERUNIQUES).
    • Leaves nameKey, descKey, isDemon, isUndead, isBoss, rank: 'minion' | 'boss', and resistances (base difficulty resistances ResDm..ResPo per D2Client.dll 0x6fafd223..0x6fafd290 + MonUMod bonuses) unset.
    • Formats unit.bossMods as 'Mod #5' instead of passing numeric MonUMod IDs ('5'..'39') expected by MONSTER_UMOD_TBL_KEYS in WorldPanelsHud.
  2. decode0xACAssignNpc in src/netproto/d2gs/s2c/units.ts aborts bitstream decoding when hasAnimComp === 1:
    • Per D2Game.dll (0x6fcaca40, 0x6fccf610) and D2Client.dll (0x6fb5e420), when hasAnimComp === 1, 16 component variant indices (MonStats2.txt HDv..S8v, bit width count < 3 ? 1 : bsr(count - 1) + 1 per 0x6fb50f10) precede the hasMonsterFlags bit and the boss/champion/superunique/minion block (flags 0x04/0x08/0x02/0x10/0x40, superUniqueId, up to 9 bossMods, nameSeed, ownerId).
  3. ClientUnit (src/client/world/client-unit.ts):
    • Needs to synchronize isChampion, isUnique, isSuperUnique, superUniqueId, bossMods, nameSeed, and ownerId from UnitSnapshot.

Fix

  • Complete D2GS 0xAC bitstream decoding for all 16 component variant indices (MonStats2.txt HDv..S8v) and the full monster flags/boss block (flags, superUniqueId, bossMods, nameSeed, ownerId).
  • Propagate elite/boss/superUnique/minion state on UnitSnapshot and ClientUnit.
  • Implement full 1.13c monster metadata, difficulty-specific resistance/immunity calculation, random Unique/Champion boss name generation (0x6fb55d90), SuperUnique name/mod lookup, and Uber boss subtext suppression (hcIdx 704..709, 0x6fb6fca0) in HudModel.clientUnitToMonsterTargetInfo.
## Symptom In `play.html` (screenshot `https://screenshot-v2.corp.google.com/0ipug71f0k37o`), hovering over a monster (e.g. Fallen, `hcIdx = 19`) displays raw `MON_19` in white in the top-center lifebar, with no subtext below the bar (missing `Demon` / `Undead`, `DescStr`, elite modifiers, and immunities), and Elite/Champion/Unique/SuperUnique/Boss/Minion monsters do not display their authentic 1.13c names or colors. ## Root Causes (1.13c Ground Truth) 1. **`clientUnitToMonsterTargetInfo` in `src/client/ui-model/hud-model.ts` is an unimplemented stub**: - Calls `monsterDisplayName(\`mon_${unit.classId}\`, 'ENG')` which misses in `.tbl` tables and returns `'mon_19'` (drawn as `MON_19`). - Does not look up `unit.classId` (`hcIdx` `0..733`) via `MONSTER_HCIDX_TO_ID` in `MonStats.txt` (`readMonsterKinds` for difficulty `0..2`) or `unit.superUniqueId` in `SuperUniques.txt` (`RAW_SUPERUNIQUES`). - Leaves `nameKey`, `descKey`, `isDemon`, `isUndead`, `isBoss`, `rank: 'minion' | 'boss'`, and `resistances` (base difficulty resistances `ResDm..ResPo` per `D2Client.dll` `0x6fafd223..0x6fafd290` + `MonUMod` bonuses) unset. - Formats `unit.bossMods` as `'Mod #5'` instead of passing numeric `MonUMod` IDs (`'5'..'39'`) expected by `MONSTER_UMOD_TBL_KEYS` in `WorldPanelsHud`. 2. **`decode0xACAssignNpc` in `src/netproto/d2gs/s2c/units.ts` aborts bitstream decoding when `hasAnimComp === 1`**: - Per `D2Game.dll` (`0x6fcaca40`, `0x6fccf610`) and `D2Client.dll` (`0x6fb5e420`), when `hasAnimComp === 1`, 16 component variant indices (`MonStats2.txt` `HDv..S8v`, bit width `count < 3 ? 1 : bsr(count - 1) + 1` per `0x6fb50f10`) precede the `hasMonsterFlags` bit and the boss/champion/superunique/minion block (`flags` `0x04/0x08/0x02/0x10/0x40`, `superUniqueId`, up to 9 `bossMods`, `nameSeed`, `ownerId`). 3. **`ClientUnit` (`src/client/world/client-unit.ts`)**: - Needs to synchronize `isChampion`, `isUnique`, `isSuperUnique`, `superUniqueId`, `bossMods`, `nameSeed`, and `ownerId` from `UnitSnapshot`. ## Fix - Complete `D2GS 0xAC` bitstream decoding for all 16 component variant indices (`MonStats2.txt` `HDv..S8v`) and the full monster flags/boss block (`flags`, `superUniqueId`, `bossMods`, `nameSeed`, `ownerId`). - Propagate elite/boss/superUnique/minion state on `UnitSnapshot` and `ClientUnit`. - Implement full 1.13c monster metadata, difficulty-specific resistance/immunity calculation, random Unique/Champion boss name generation (`0x6fb55d90`), SuperUnique name/mod lookup, and Uber boss subtext suppression (`hcIdx` `704..709`, `0x6fb6fca0`) in `HudModel.clientUnitToMonsterTargetInfo`.
Sign in to join this conversation.
No Label
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: troytt/diablo2-web#559
No description provided.