fix(waypoint): 修复冰冷之原等 14 处场景小站未渲染缺陷,根除 ALL_WAYPOINT_IDS 跨幕 ID 冲突与打包管线实体漏注 #409
Labels
No Label
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: troytt/diablo2-web#409
Loading…
Reference in New Issue
No description provided.
Delete Branch "%!s(<nil>)"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
1. 缺陷背景与现象 (Defect Symptoms)
2. 全量 39 个小站与 109 个关卡变体审查结果 (Full Spectrum Audit: 39 Waypoints / 109 Variants)
经自动化脚本对
samples/d2-packs中全部关卡包进行逐一解析与审查,全游戏 39 处小站中,仅 25 处正常渲染,多达 14 处关卡(共计 37 个关卡变体)的小站物件完全或部分缺失未渲染!统计概览
source: "placed")详细审查清单
3-act-1-wilderness-2-var1/var2/var34-act-1-wilderness-3-var1/var2/var35-act-1-wilderness-4-var1/var2/var36-act-1-wilderness-5-var1/var2/var342-act-2-desert-2-var1/var2/var343-act-2-desert-3-var1/var2/var344-act-2-desert-4-var1/var2/var374-act-2-arcane-var1/var2/var376-act-3-jungle-1-var277-act-3-jungle-2-var278-act-3-jungle-3-var2/var379-act-3-kurast-1-var1/var2/var381-act-3-kurast-3-var1/var2/var3123-act-5-temple-2-var1/var2/var33. 根因深度剖析(暴雪 1.13c Ground Truth 与源码缺陷)
根因 1:
src/game/wilderness.ts中ALL_WAYPOINT_IDS跨幕 ID 碰撞,导致生成器误判已有小站而提前短路在暴雪 1.13c 汇编实现中(
D2Common.dll≈0x6FD92700DRLGOUTDOORS_SpawnAct12Waypoint),DS1 物件的id在不同 Act / 关卡类型下是局部作用域的,必须结合act与type进行映射(见object-lookup.ts)。各幕真实的小站 DS1 ID 与对应
Objects.txt关系为:Objects.txtrow 119(TokenWP)Objects.txtrow 156(TokenWM)Objects.txtrow 237(TokenWZ)Objects.txtrow 238(TokenWV)Objects.txtrow 38(TokenWT)然而在
src/game/wilderness.ts第 5997 行中,开发者为了检查预设是否已经放置了小站,错误地创建了一个跨幕混合的全局 Set:冲突事实:
TO),其 DS1id = 1。ALL_WAYPOINT_IDS包含了 Act 3 的小站 ID1,Act 1 荒野图块盖章后,canvas.objects.find()必然命中普通火把(id = 1)!stats.waypointsSpawned设为 1 并直接return,彻底抹杀了真正的户外小站生成逻辑(包括冰冷之原与血石荒地交界处专属的DRLGOUTDOORS_SpawnAct12Waypoint算法)!id = 0)和火把(id = 1),误匹配 Act 4(id = 0)和 Act 3(id = 1);id = 0)和武器架(id = 12),误匹配 Act 4(id = 0)和 Act 5(id = 12)。根因 2:
scripts/pack-act-assets.ts打包管线降级机制未注入实体物件,导致元数据孤立在
scripts/pack-act-assets.ts第 801~820 行:当生成器因根因 1 未能生成小站时,美术中的
waypointCells为空。打包器虽通过findWaypointSpot计算了备用放置坐标并生成了SceneWaypoint(即source: "placed"),但从未将该小站补入level.objects!导致:
scene.json中的objects数组完全没有小站条目。wptrlitonhth.dcc)没有被打包进关卡图集objects-*.png。根因 3:
src/scene/act-scene.ts渲染端仅依赖scene.objects,对waypoints元数据缺乏渲染补全在游戏运行端,小站交互(
pendingInteraction = { kind: "waypoint" })通过runtime.waypoints进行坐标与距离匹配(80px),而场景绘制循环仅遍历scene.objects/objectDrawables。因为物件列表缺失小站,前端画布在对应坐标处没有画出任何像素,直接导致了玩家看到的“隐形小站”。
根因 4:迷宫与预设关卡(Level 74 神秘避难所、Level 123 痛楚之厅)小站映射缺陷
maze.ts中的小站房间部件在未找到内嵌物件时,硬编码生成id = 119(Act 1 物件),在 Act 5 环境下无法映射到合法美术资源。4. 修复方案 (Remediation Plan)
wilderness.ts中的小站存在性检测:ALL_WAYPOINT_IDS集合。lookupObject(act, 2, obj.id)检测其解析后的 Token 是否为WP/WM/WZ/WV/WT),消除火把、树木、武器架等非小站物件的误判短路。pack-act-assets.ts实体注入:findWaypointSpot放置(source: "placed")或户外生成时,自动向level.objects中注入对应 Act 的规范小站物件。objects-*.png,使scene.json同时拥有元数据与渲染实体。maze.ts迷宫关卡小站生成:实机复现截图 (In-Game Reproduction Screenshot)
(角色传送至冰冷之原后,左侧已点亮小站菜单,但在场景中央只有空地皮,完全无小站实体模型)