Commit Graph

628 Commits

Author SHA1 Message Date
troytt ca197e8e1d Merge branch 'feat/netproto' into main
TAG=agy
CONV=a30b2fd5-74b7-4c2f-8d0b-f09c1d751495
2026-09-30 04:45:19 +00:00
troytt be6158826e feat(netproto,client): implement pure-browser D2 1.13c online client (N0-N10)
- Add isolated zero-dependency protocol engine in src/netproto/ (BNCS OLS xsha1,
  CheckRevision, CD-Key hash, MCP realm session, Fog.dll Huffman codec, 167-opcode
  D2GS S2C/C2S codecs, 0x9C/0x9D item bitstreams, D2OnlineFlow, and TS server
  adapter stub) enforced by tsconfig.netproto.json and boundary.test.ts.
- Add deterministic 1.13c binary table extractor (scripts/extract-d2net-tables.ts),
  live headless bot (scripts/d2-bot.ts), .d2s save unlocker (scripts/d2s-unlock.ts),
  tile atlas packer (scripts/pack-tiles.ts), and strict .d2cap offline replay
  verifier (scripts/netproto-replay.ts) with 4 live server capture fixtures.
- Add runtime seed-driven DRLG MapService, TileAtlas, A* sub-tile pathfinder,
  LocalMovementPredictor, and RemoteEntityInterpolator verified across all 136
  levels and 5-Act live waypoint tours.
- Build play.html and src/client/ online session, WebGL2 TileAtlasGpuCache +
  renderSceneSourceFrame, dual 800x600 / 1024x768 viewports, top DOM Toolbar
  (host validation, live ZH/EN toggle, 7 lighting presets, automap reveal,
  Packet Inspector), SoundService, OpfsMpqManager, and 5-tier E2E test suite.

TAG=agy
CONV=a30b2fd5-74b7-4c2f-8d0b-f09c1d751495
2026-09-30 04:41:08 +00:00
troytt 5de27f8177 test(e2e): add umbrella P0 #516 end-to-end and 136-level verification suite (#516)
Add full-spectrum E2E verification covering all 10 P0 issues and 136-level DRLG
parity invariants.

TAG=agy
CONV=4e31689c-063a-4965-968b-59c0f5795f97
2026-09-29 21:01:51 +00:00
troytt 3465c8052b fix(render): fail fast on missing missile sprite atlases without fallback art (#530)
Remove silent catch handlers, procedural drawSolid blocks, and borrowed
fireexplode fallbacks when loading or rendering missile sprite atlases.

TAG=agy
CONV=4e31689c-063a-4965-968b-59c0f5795f97
2026-09-29 21:01:50 +00:00
troytt 97abcb3bf7 fix(scene): guard async scene transitions with generation tokens and dispose WebGL textures (#529)
Cancel stale async continuations across switchArea, changeHeroClass, and
respawnMonsters via monotonic generation tokens and call gl.deleteTexture on eviction.

TAG=agy
CONV=4e31689c-063a-4965-968b-59c0f5795f97
2026-09-29 21:01:50 +00:00
troytt 58cbc88e7c fix(audio): reuse shared singleton AudioContext in SoundManager (#528)
Maintain a single lazy-initialized AudioContext instance across playSound calls
with automatic suspended-context resume and clean close/recreation support.

TAG=agy
CONV=4e31689c-063a-4965-968b-59c0f5795f97
2026-09-29 21:01:49 +00:00
troytt 462fdc7516 fix(parity): enforce 1.13c table-driven stats and fail-fast invariants (#524)
Use canonical CharStats.txt, MonStats.txt, and MonLvl.txt tables, record actual
loaded Level.dt1Mask, and replace silent fallbacks with fail-fast checks.

TAG=agy
CONV=4e31689c-063a-4965-968b-59c0f5795f97
2026-09-29 21:01:49 +00:00
troytt 112c12808b fix(sim): enforce deterministic seeded RNG and tick-aligned simulation (#523)
Eliminate Math.random and wall-clock timers in simulation paths, queue DOM/UI
actions into tick-aligned engine commands, and roll monster death drops synchronously.

TAG=agy
CONV=4e31689c-063a-4965-968b-59c0f5795f97
2026-09-29 21:01:49 +00:00
troytt 231d375e62 fix(ground): unify authoritative ground-item store with exact instance IDs (#522)
Key ground items by unique instance ID, remove 32px proximity deletion,
deduplicate ground-item serialization on save, and reconstruct ground items on load.

TAG=agy
CONV=4e31689c-063a-4965-968b-59c0f5795f97
2026-09-29 21:01:48 +00:00
troytt 206b59e72d fix(gold): prevent HUD drop-gold and world pickup gold duplication (#521)
Route HUD gold drops and world gold pickups through the single authoritative
engine gold balance and clamp vendor gold by character level.

TAG=agy
CONV=4e31689c-063a-4965-968b-59c0f5795f97
2026-09-29 21:01:48 +00:00
troytt 7367f2a36a fix(state): unify player HP/MP/gold/inventory single source of truth in GameEngine (#520)
Delegate HUD player state reads and mutations to GameEngine as the single
authoritative owner of HP, MP, gold, inventory, belt, and equipment state.

TAG=agy
CONV=4e31689c-063a-4965-968b-59c0f5795f97
2026-09-29 21:01:47 +00:00
troytt 995f594fe7 fix(net): enforce lockstep peerId authentication, bounds checks, and future-tick window (#518)
Bind peerId at the relay session layer, reject out-of-range peerIds and
out-of-window future ticks without leaking memory, and store N-peer inputs per tick.

TAG=agy
CONV=4e31689c-063a-4965-968b-59c0f5795f97
2026-09-29 21:01:47 +00:00
troytt 7bc21df07c fix(net): harden WebSocket relay frame validation and crash isolation (#517)
Enforce RFC 6455 framing checks, connection/room/rate limits, and per-socket
error isolation so malformed or truncated frames never crash the relay.

TAG=agy
CONV=4e31689c-063a-4965-968b-59c0f5795f97
2026-09-29 21:01:47 +00:00
troytt c2c1d280d5 fix(drlg): resolve M1 iteration 2 audit findings (animSpeed, crossActObjOf, strip-types, __d2Scene, D2Rng.int) 2026-09-29 10:29:42 +00:00
troytt 8ddfbd318a feat(drlg,rng): unify 64-bit D2Rng and 136-level 1:1 DRLG port (DRLG_ACT_VARIANTS=1, seed 0x5eed0100) 2026-09-29 09:24:58 +00:00
troytt 9077b5889d Merge branch 'feat/drlg-496-499' into main (Fixes #496, #497, #498, #499, #500, #501, #502) 2026-09-28 17:44:56 +00:00
troytt a241763f7c feat(drlg): integrate Acts 2-5 outdoor DRLG, remove legacy wilderness, and verify all 136 levels (#496, #497, #498, #499, #500, #501, #502) 2026-09-28 16:57:18 +00:00
troytt a05c97c438 fix(ui,tests): cover multi-color ÿc tooltip alignment, High-DPI HUD/label scaling, and socket/pack test parity (Fixes #504) 2026-09-28 14:20:23 +00:00
troytt fc1085418c feat(runeword): implement authentic 1.13c Runeword, socketing & Horadric Cube transmutation system 2026-09-28 13:40:16 +00:00
troytt 1d7445a64e fix(ui): align CharacterSheet stone recess centers, bilingual CJK+space wrapping, bnet.html @font-face & pack:ui font parity (Fixes #504) 2026-09-28 12:56:17 +00:00
troytt 9d0138f69b fix(ui,fonts): hybrid DC6+CJK rendering, middle-dot atlas mask, TTF contour refinement, and recess centering (Issue #504 R2 review) 2026-09-28 12:53:32 +00:00
troytt f488ac8743 fix(ui,fonts): fix Formal 436 quest/dialog prose, TTF glyph contours, and char-sheet spacing (Issue #504 R1 review) 2026-09-28 12:53:32 +00:00
troytt 3ced5b08b9 feat(ui): integrate authentic 1.13c Exocet & Formal 436 DC6 bitmap & TrueType fonts (#504) 2026-09-28 12:53:32 +00:00
troytt 768a2cc920 feat(socket): implement 1.13c jewel, gem & rune socketing system (Closes #507)
- Jewels ('jew' / 'jewl') can be socketed into any socketed equipment (weapon, helm, armor, shield) and apply their rolled modifiers identically regardless of slot.
- Un-socketed Jewels display 'Can be Inserted into Socketed Items' / '可镶嵌进有凹槽的装备'.
- Gems (35 codes) and Runes (r01..r33, 33 codes) dispatch slot-dependent modifiers (weaponMods vs helmMods/armor vs shieldMods) per 1.13c Gems.txt.
- Recalculate host item defense, weapon damage, reqStr, reqDex, reqLevel, indestructibility, rune letter sequences, and Runeword completion.
- Support left-click interactive socketing and visual socket overlay rendering across Inventory (10x4), Equipped paperdoll slots, Private Stash (6x8), and Horadric Cube (3x4).
- Add unit & parity test suite in tests/socket-system.test.ts.
2026-09-28 12:47:24 +00:00
troytt 6601dcde82 feat(char,items): dynamic Sorceress equipment paperdoll appearance, weapon classes, and 1.13c palette dye shifts 2026-09-28 12:42:21 +00:00
troytt 4e461e1fdb feat(ui,items): implement 1.13c character equipment restrictions and red requirement display (#506) 2026-09-28 12:13:26 +00:00
troytt e1a58631d1 Merge branch 'feat/fixes-500-502' into feat/drlg-496-499 2026-09-28 11:27:46 +00:00
troytt d887b39485 feat(drlg): port 1:1 D2MOO outdoor DRLG for Acts 2, 3, 4, and 5 (#496, #497, #498, #499) 2026-09-28 11:22:08 +00:00
troytt 909c50eb48 fix(drlg,pack): pack XX minion art, fix L123 var3 waypoint, and pin exact DRLG tile variants (#500, #501, #502) 2026-09-28 09:23:12 +00:00
troytt a100885552 chore: remove standalone simulator pages (arena, loot, boss, skills) and related entry code 2026-09-28 08:09:37 +00:00
troytt 792578e566 test(ui): update vendor-panel-ui NPC menu header expectation to localized CHI name (Fixes #503) 2026-09-28 07:35:38 +00:00
troytt ef8a7ffff6 fix(i18n): resolve all Iteration 1 bilingual parity findings for Issue #503
- Prefer item.damageEn in ENG item tooltips and normalize 2H, versatile 1H/2H, and throwing weapon damage labels in localizeStarterTooltipLine and item-bridge.ts
- Fix starter set item tooltip regex ordering (+所有技能 without trailing $ and +生命补给 before +生命)
- Use getLocalizedNpcName for Town NPC stone menu headers in both ENG and CHI modes across getNpcMenuLayout, handleNpcMenuClick, and drawNpcMenu
- Add SUPERUNIQUE_TBL_ALIASES in monsterDisplayName for 7 SuperUniques whose SuperUniques.txt IDs differ from .tbl keys
- Export cleanChiItemName in ground-labels.ts and apply to CHI ground item labels and drop-to-ground status messages
- Update verify-issue-503-browser.ts LeftDockPanelKind loop + vendor/NPC coverage and expand issue-503-bilingual-parity.test.ts

Refs #503
2026-09-28 07:35:16 +00:00
troytt 6fa9c7784e feat(i18n): implement full Chinese (CHI) and English (ENG) bilingual versions (#503)
- Add src/i18n/lang.ts for URL/query/storage language detection, runtime state, and language switcher URL generation preserving query parameters
- Expand scripts/pack-canonical-tbl.ts and regenerate src/data/canonical-tbl-strings.ts with 3,721 ENG and 3,374 CHI 1.13c .tbl entries (UI, monsters, SuperUniques, levels, skills, items)
- Add completedEn speech strings for Act II Quest 2 and Act IV Quest 2 in src/data/canonical-quest-data.ts
- Add index.html bilingual entry portal, acts-zh.html (CHI), acts-en.html (ENG), and language switcher in acts.html; configure multi-page rollup inputs in vite.config.ts
- Localize all 15 UI/game modules (level-names-zh, character-sheet, control-bar, globes, ground-items, ground-labels, item-bridge, inventory, skill-tree-panel, hotkeys, npc-table, world-panels, monsters, hud-manager, act-scene) for authentic CHI and zero-CJK ENG modes
- Add tests/issue-503-bilingual-parity.test.ts and scripts/verify-issue-503-browser.ts

TAG=agy
CONV=5016e6fd-4af8-421f-ae4b-6d443a0a102a
2026-09-28 07:35:16 +00:00
troytt 44ec4124b9 fix(monsters): apply 1.13c MonUMod resistance bonuses in applyEliteModifiers/enrichMonsterStats and isolate hover from 36px click-assist 2026-09-28 07:00:16 +00:00
troytt 0be447fab3 fix(hud): enforce 1.13c Line 1 rank color prefix, MonUMod champion subtype IDs, and elite=all demotion
- Apply abilityColorPrefix (ÿc4 for Unique/Boss, ÿc3 for Champion, '' for Normal/Minion) across the entire Line 1 subtext in buildMonsterHoverSubtext per D2Client.dll 0x6fb719b0 / 0x6fb71a20 so <Race> (Demon/Undead) and race-only Champions/Bosses (DescStr == 'dummy') render in their rank color instead of white (ÿc0), and single-token overflow truncation preserves the rank color.
- Support numeric MonUMod.txt Champion subtype IDs ('16', '36'..'39' from .rdata:0x6fb86d64), case-insensitive modifier keys, and target.affixes fallback in resolveMonsterTitleAndColor, and forward descStr, subType, and affixes in monsterToTargetHudInfo.
- Demote already-elite packs in rebudgetMonsterPacks before re-promoting when elite === 'all' to prevent double-multiplying HP (9x/16x) and level (+4/+6).
- Call mouseController.syncMonsterTargetHud(camX, camY) before reading getActiveTargetMonster() in onRender so moving monsters/camera have zero 1-frame lag on the [1.25, 1.25, 1.25, 1.0] sprite highlight tint.
- Add Round 2 regression tests in tests/monster-target-bar.test.ts.

TAG=agy
CONV=4761a588-f887-4d60-a654-44297372fd6a
2026-09-28 06:19:49 +00:00
troytt 3a4cb77d06 fix(hud): resolve monster lifebar review findings, dummy DescStr filter, thief umod, and target lock 2026-09-28 05:04:38 +00:00
troytt b084aaba7f feat(hud): implement authentic 1.13c monster hover lifebar and 2-line subtext tooltip 2026-09-28 04:18:50 +00:00
troytt 526d623f66 Merge branch 'feat/automap-113c'
# Conflicts:
#	public/ui/manifest.json
#	src/scene/act-scene.ts
#	src/ui/baked-ui-meta.ts
2026-09-28 01:33:06 +00:00
troytt a06777be07 fix(ui): remove non-authentic deposit/withdraw buttons over stash bottom keyhole area 2026-09-28 01:27:10 +00:00
troytt 14aa512e85 feat(automap): implement authentic Diablo II v1.13c isometric sprite Automap & Minimap 2026-09-28 01:27:10 +00:00
troytt b6fc2512d4 feat(drlg): generate Act I outdoor levels with the 1:1 D2MOO port (#455)
The eight Act I outdoor levels (Blood Moor 2, Cold Plains 3, Stony Field
4, Dark Wood 5, Black Marsh 6, Tamoe Highland 7, Burial Grounds 17, Moo
Moo Farm 39) are now generated by the function-by-function port of
D2MOO's D2Common DRLG in src/game/drlg, bit-exact against a native D2MOO
oracle. The legacy Act I generator (src/game/wilderness/*, the Blood Moor
branch and the Act I paths of wilderness.ts) is deleted; there is no
fallback. Acts 2-5 are unchanged.

Port (completes the kernel committed earlier):
- Tile-map stage: DRLGROOMTILE_AddRoomMapTiles with its tile-data,
  linked-tile and warp helpers, DRLGPRESET_AddPresetRoomMapTiles,
  DRLGOUTROOM_InitializeDrlgOutdoorRoom (drlg-outroom.ts), the
  DrlgDrlgLogic.cpp parts they reach (drlg-logic.ts), D2CMP shim updates.
- drlg-dump.ts: runAct1() driver API; schema 3 dumps with per-room tile
  lists. The port is now type-checked (tsconfig no longer excludes it).

Integration:
- drlg-map.ts (replaces drlg/adapter.ts): turns a generated level into
  the bake's DS1-shaped canvas with exact (style, sequence, type) per
  tile and per-cell DT1 masks, objects, seams from the DRLG level links,
  warps from their UNIT_TILE preset units; blank cells stay blocked.
- pack-act-assets: one D2 game seed per (act, variant), a DRLG bake job
  and index.json actLayouts; scripts/lib/drlg-mpq-source.ts feeds the
  port from the MPQs with the oracle's file list.
- act-variants.ts: WorldVariants picks one generated copy per act (and
  the Rogue Encampment DS1 that copy fixed); act-scene.ts and
  verify-world-walk both use it. act-scene no longer paints grass into
  the blank cells of DRLG scenes.
- world-graph: remove the invented Stony Field <-> Dark Wood seam
  (gAct1WildernessDrlgLink / gAct1MonasteryDrlgLink keep them apart;
  they meet only through the Underground Passage); world-placement
  anchors the second group at the Monastery Gate (3000, 1000).
- level-links: findBorderOpening takes an optional edge range.
- d2map: dt1MaskAllows extracted, behaviour unchanged.

Tools and tests:
- tools/d2moo-oracle: tile-map stage and schema 3; the 4 fixtures are
  regenerated (scripts/drlg-fixtures.ts).
- scripts/render-drlg-compare.ts (both dumps through the same adapter
  and renderer, fails unless the XOR is empty) and
  scripts/audit-levels-browser.ts (headless audit of every baked map).
- tests/drlg-act1-oracle.test.ts (all stages, all 4 fixtures) and
  tests/drlg-act1-invariants.test.ts; tests and stress scripts of the
  deleted generator are retired or now run on Acts 2-5 only.
- verify-world-walk: start in the town the runtime opens and floor the
  spawn sub-tile like the movement collision does.

Verification:
- drlg-diff --levels 2-7,17,39 --seeds 32: 32/32 identical at every
  stage; --trace-check 64/64, --isolated 32/32, difficulty 1 and 2 16/16.
- render-drlg-compare, 3 bake copies x 8 levels: 24/24 XOR empty.
- Full re-bake: 365 maps, 0 missing tiles. Browser audit: 355/365 maps,
  133/136 level ids clean (112/124/129: Act 5 minions without art, as
  before).
- verify:world-graph 37583 assertions; verify:world-walk 29/29;
  verify:entity-packs, typecheck clean. vitest 6369 passed; the 6
  failures (5 ground-item name formatting, 123-var3 waypoint) and the
  verify:packs / verify:generators failures also occur at bad6806.

Test pins updated, measured on the new bake: SceneEntrance 172 -> 166
and world-graph edges 286 -> 284 (the removed seam), seamless pairs
27 -> 26 and placement pairs 19 -> 18; full-spectrum floors / walls /
PNGs 1008898 / 237542 / 1390 (the old pins matched no bake of the
current code).

TAG=agy
CONV=a4f9163c-a011-4161-b169-7f361b1ed57e
2026-09-27 15:20:41 +00:00
troytt 230c20da67 fix(entities): bake the Hell Bovine (MonStats Code EC) art for the Moo Moo Farm
Commit 2e73d7b changed the Hell Bovine art token from CW to EC
(MonStats.txt hellbovine, Code EC) but never added EC to the act 1 list
of ACT_MONSTER_SPECS, so pack-entity-assets baked no ec-hth atlas and the
Moo Moo Farm's (level 39) Hell Bovines had no art.

- ACT_MONSTER_SPECS[1]: add { token: "EC", weapon: "hth" }.
- Re-baked entities: 70 monster atlases (was 69). entities/index.json is
  now sha256 675757cf...; the new ec-hth entry is its only change.
- Tests: pin 70 entities, 66 unique specs and the new index hash.

TAG=agy
CONV=a4f9163c-a011-4161-b169-7f361b1ed57e
2026-09-27 15:18:30 +00:00
troytt bad680600f feat(scene): replace G-key map transition with mouse-click warp & entrance interaction 2026-09-27 14:26:13 +00:00
troytt 1c738c5445 Merge branch 'fix/cube-transmute-btn' 2026-09-27 08:36:41 +00:00
troytt 3bf9a8c220 fix(ui): restore Horadric Cube Transmute and Close buttons per D2Client.dll 1.13c parity 2026-09-27 08:36:19 +00:00
troytt ffda82d650 Merge branch 'fix/vendor-item-bg-color' into main 2026-09-27 08:36:09 +00:00
troytt 598f8f2421 fix(ui): align vendor and gamble item background colors with D2 1.13c item usability rules 2026-09-27 08:35:32 +00:00
troytt 8c5ae5c623 fix(ui): 补齐物品栏金币按钮 (goldcoinbtn.dc6) 并对齐金币栏数值 2026-09-27 08:16:53 +00:00
troytt 855d610168 fix(ui): 点击商人面板买/卖/修理按钮后鼠标样式切换为原版 buysell.dc6 交易光标 (Fixes #491) 2026-09-27 07:47:31 +00:00
troytt d998a0551b fix(ui): restore authentic D2 v1.13c NPC dialog popup menu (Fixes #489) 2026-09-27 06:41:10 +00:00