[P3][T6] 按子系统人工精读审计低命名可追溯区域 #86

Closed
opened 2026-09-18 09:47:29 +00:00 by troytt · 2 comments
Owner

背景

scratch/audit_coverage.py 抽取原版 328 个 DRLG* / DUNGEON* 函数定义,
检查它们是否在仓库 src/ scripts/ tests/ 中被提及:
72 个被提及,256 个从未出现;过滤掉内存/销毁/激活类噪声后,
仍有 135 个影响内容的函数从未出现。

按前缀统计(已排除 _Free / _Alloc / _Realloc):

前缀 覆盖 主要缺名
DRLGOUTJUNG_ 0/5 (0.0%) BuildJungle, BuildKurastBazaar, BuildLowerKurast, BuildUpperKurast, SpawnRandomPreset
DRLGOUTROOM_ 0/4 (0.0%) InitializeDrlgOutdoorRoom, LinkLevelsBy{LevelCoords,LevelDef,OffsetCoords}
DRLGOUTDESR_ 1/11 (9.1%) AddExits, PlaceBorders, PlaceCliffs, PlaceFillsIn{Canyon,FarOasis,LostCity}, PlaceTombEntriesInCanyon …
DRLGPRESET_ 3/29 (10.3%) GenerateLevel, BuildPresetArea, ParseDS1File, SpawnHardcodedPresetUnits, ChangeMapAI, UpdatePops …
DRLGOUTWILD_ 2/9 (22.2%) GetBridgeCoords, SpawnCliffCaves, SpawnCottage, SpawnRiver, SpawnTownTransitionsAndCaves
DRLGOUTSIEGE_ 2/7 (28.6%) PlaceBarricadeEntrancesAndExits, PlaceCaves, PlacePrisons, PlaceSpecialPresets
DRLGOUTPLACE_ 5/13 (38.5%) BuildKurast, LinkAct2{Canyon,Outdoors}, LinkAct4{ChaosSanctum,Outdoors}, LinkAct5Ubers
DRLGOUTDOORS_ 8/19 (42.1%) CalculatePathCoordinates, TestGridCellSpawnValid, TestGridCellNonLvlLink, SpawnRandomOutdoorDS1 …
DRLGMAZE_ 30/46 (65.2%) GetFreeLocationForRoom{E,N,S,W}, PlaceAdjacentPresetRoom, PlaceRoomForArcaneBranch, SetRoomSize …
DRLGTILESUB_ 4/6 (66.7%) InitializeDrlgFile, TestReplaceSubPreset

这份数据的正确解读

[!CAUTION]
这些百分比衡量的是「命名可追溯性」,不是「实现存在性」。

反例:DRLGOUTJUNG_ 是 0%,但 src/game/wilderness-jungles.ts(708 行)
显然实现了丛林生成,只是用了本地命名。

正确解读是:「这个子系统当初不是逐行对照原版写的」,
不是「这个子系统缺失」。任何人不得把这张表当成缺陷清单直接开工。

另有两条附带观察:

  • src/game/wilderness-acts.ts:701 存在运行时告警
    Act 4 basalt plateaus not implemented for level ${request.levelId};
  • verify-packs 输出 楼梯来源:美术瓦片 415,迷宫楼梯间 0,兜底 80 —— 'room' 这条来源
    从未被命中,疑似死代码路径,值得顺手确认。

本 issue 的任务

这是一个审计任务,不是实现任务。产出是一份「哪些是真差异、哪些只是命名不同」的结论,
以及据此拆出的后续 issue。

建议顺序(按「低可追溯 × 玩法影响」排序,与 P2 的瓦片缺失名单吻合):

  1. DRLGOUTDESR_(Act 2 沙漠,9.1%) —— 对应 43 Desert 3 的瓦片缺失
  2. DRLGOUTJUNG_(Act 3 丛林 / Kurast,0%) —— 对应 79/80/81 的 6%+ 瓦片缺失,影响最大
  3. DRLGPRESET_(预设流水线,10.3%) —— 面最广,几乎所有关卡都经过它
  4. DRLGOUTROOM_(室外 Room 链接,0%)

每个子系统的审计方法:

  1. 读原版该前缀下的全部函数,画出调用关系与数据流;
  2. 在仓库里找到功能对应的本地实现(按行为找,不要按名字找);
  3. 逐条比对:算法形态、常量、RNG 消耗次数与顺序;
  4. 产出三类结论:
    • ✅ 等价(可能命名不同)—— 建议补一条注释指明对应的原版函数名;
    • ⚠️ 近似(行为接近但 RNG/分布不同)—— 开 issue,标明影响面;
    • ❌ 缺失或错误 —— 开 issue,附原版伪码;
  5. 涉及 RNG 次数或精确常量的结论,必须回 1.13c 二进制复核(工具见下方溯源栏)。

验收标准

  • 至少完成前 2 个子系统(DRLGOUTDESR_、DRLGOUTJUNG_)的精读
  • 每个子系统产出一份结论表:原版函数 → 仓库对应物 → 等价/近似/缺失 → 证据
  • 对判定为「近似」或「缺失」的项逐个开出子 issue(挂本里程碑)
  • 对判定为「等价」的项,在仓库代码里补注释指明对应原版函数名,
    提升下一轮审计的可追溯率
  • 顺带确认 楼梯来源 'room' 是否为死代码,是则清理或补测试

溯源

审计报告 113c-divergence-audit.md(条目编号与本 issue 标题中的 T 编号对应)
黄金标准 1.13c D2Common.dll,PE 时间戳 0x4B95C439 = 2010-03-09,ImageBase 0x6FD50000
可读代理 D2MOO 源码为 1.10f,非 1.13c。已通过「6/6 常量表命中 + 两个函数反汇编控制流比对」验证其 DRLG 部分与 1.13c 一致,详见报告开头「代理有效性验证」

[!WARNING]
引用 D2MOO 行号时请注意它是 1.10f。涉及 RNG 消耗次数或精确常量的改动,必须回到 1.13c 二进制复核
(工具:scratch/probe_113c_drlg.py、scratch/xref.py、scratch/findbytes.py + objdump)。

## 背景 `scratch/audit_coverage.py` 抽取原版 328 个 `DRLG*` / `DUNGEON*` 函数定义, 检查它们是否在仓库 `src/` `scripts/` `tests/` 中被提及: **72 个被提及,256 个从未出现**;过滤掉内存/销毁/激活类噪声后, 仍有 **135 个影响内容的函数从未出现**。 按前缀统计(已排除 `_Free` / `_Alloc` / `_Realloc`): | 前缀 | 覆盖 | 主要缺名 | |---|---|---| | `DRLGOUTJUNG_` | 0/5 (0.0%) | BuildJungle, BuildKurastBazaar, BuildLowerKurast, BuildUpperKurast, SpawnRandomPreset | | `DRLGOUTROOM_` | 0/4 (0.0%) | InitializeDrlgOutdoorRoom, LinkLevelsBy{LevelCoords,LevelDef,OffsetCoords} | | `DRLGOUTDESR_` | 1/11 (9.1%) | AddExits, PlaceBorders, PlaceCliffs, PlaceFillsIn{Canyon,FarOasis,LostCity}, PlaceTombEntriesInCanyon … | | `DRLGPRESET_` | 3/29 (10.3%) | GenerateLevel, BuildPresetArea, ParseDS1File, SpawnHardcodedPresetUnits, ChangeMapAI, UpdatePops … | | `DRLGOUTWILD_` | 2/9 (22.2%) | GetBridgeCoords, SpawnCliffCaves, SpawnCottage, SpawnRiver, SpawnTownTransitionsAndCaves | | `DRLGOUTSIEGE_` | 2/7 (28.6%) | PlaceBarricadeEntrancesAndExits, PlaceCaves, PlacePrisons, PlaceSpecialPresets | | `DRLGOUTPLACE_` | 5/13 (38.5%) | BuildKurast, LinkAct2{Canyon,Outdoors}, LinkAct4{ChaosSanctum,Outdoors}, LinkAct5Ubers | | `DRLGOUTDOORS_` | 8/19 (42.1%) | CalculatePathCoordinates, TestGridCellSpawnValid, TestGridCellNonLvlLink, SpawnRandomOutdoorDS1 … | | `DRLGMAZE_` | 30/46 (65.2%) | GetFreeLocationForRoom{E,N,S,W}, PlaceAdjacentPresetRoom, PlaceRoomForArcaneBranch, SetRoomSize … | | `DRLGTILESUB_` | 4/6 (66.7%) | InitializeDrlgFile, TestReplaceSubPreset | ## 这份数据的正确解读 > [!CAUTION] > **这些百分比衡量的是「命名可追溯性」,不是「实现存在性」。** > > 反例:`DRLGOUTJUNG_` 是 0%,但 `src/game/wilderness-jungles.ts`(708 行) > 显然实现了丛林生成,只是用了本地命名。 > > 正确解读是:「这个子系统当初不是逐行对照原版写的」, > **不是**「这个子系统缺失」。任何人不得把这张表当成缺陷清单直接开工。 另有两条附带观察: - `src/game/wilderness-acts.ts:701` 存在运行时告警 `Act 4 basalt plateaus not implemented for level ${request.levelId}`; - `verify-packs` 输出 `楼梯来源:美术瓦片 415,迷宫楼梯间 0,兜底 80` —— `'room'` 这条来源 **从未被命中**,疑似死代码路径,值得顺手确认。 ## 本 issue 的任务 这是一个**审计任务,不是实现任务**。产出是一份「哪些是真差异、哪些只是命名不同」的结论, 以及据此拆出的后续 issue。 建议顺序(按「低可追溯 × 玩法影响」排序,与 P2 的瓦片缺失名单吻合): 1. **`DRLGOUTDESR_`(Act 2 沙漠,9.1%)** —— 对应 43 Desert 3 的瓦片缺失 2. **`DRLGOUTJUNG_`(Act 3 丛林 / Kurast,0%)** —— 对应 79/80/81 的 6%+ 瓦片缺失,影响最大 3. **`DRLGPRESET_`(预设流水线,10.3%)** —— 面最广,几乎所有关卡都经过它 4. **`DRLGOUTROOM_`(室外 Room 链接,0%)** 每个子系统的审计方法: 1. 读原版该前缀下的全部函数,画出调用关系与数据流; 2. 在仓库里找到功能对应的本地实现(按行为找,不要按名字找); 3. 逐条比对:**算法形态**、**常量**、**RNG 消耗次数与顺序**; 4. 产出三类结论: - ✅ 等价(可能命名不同)—— 建议补一条注释指明对应的原版函数名; - ⚠️ 近似(行为接近但 RNG/分布不同)—— 开 issue,标明影响面; - ❌ 缺失或错误 —— 开 issue,附原版伪码; 5. 涉及 RNG 次数或精确常量的结论,**必须回 1.13c 二进制复核**(工具见下方溯源栏)。 ## 验收标准 - [ ] 至少完成前 2 个子系统(`DRLGOUTDESR_`、`DRLGOUTJUNG_`)的精读 - [ ] 每个子系统产出一份结论表:原版函数 → 仓库对应物 → 等价/近似/缺失 → 证据 - [ ] 对判定为「近似」或「缺失」的项逐个开出子 issue(挂本里程碑) - [ ] 对判定为「等价」的项,在仓库代码里补注释指明对应原版函数名, 提升下一轮审计的可追溯率 - [ ] 顺带确认 `楼梯来源 'room'` 是否为死代码,是则清理或补测试 --- ### 溯源 | | | |---|---| | 审计报告 | `113c-divergence-audit.md`(条目编号与本 issue 标题中的 T 编号对应) | | 黄金标准 | 1.13c `D2Common.dll`,PE 时间戳 `0x4B95C439` = 2010-03-09,ImageBase `0x6FD50000` | | 可读代理 | D2MOO 源码为 **1.10f**,非 1.13c。已通过「6/6 常量表命中 + 两个函数反汇编控制流比对」验证其 DRLG 部分与 1.13c 一致,详见报告开头「代理有效性验证」 | > [!WARNING] > 引用 D2MOO 行号时请注意它是 1.10f。涉及 RNG 消耗次数或精确常量的改动,**必须**回到 1.13c 二进制复核 > (工具:`scratch/probe_113c_drlg.py`、`scratch/xref.py`、`scratch/findbytes.py` + `objdump`)。
troytt added this to the [M17] 核心地下城与碰撞层原版一致性 (1.13c) milestone 2026-09-18 09:47:29 +00:00
Author
Owner

与 #83 的关系

#83(Kurast / Mesa / Desert / Barricade 瓦片引用缺失)是本审计的具体症状,
两者目标子系统完全重叠:

#83 的关卡 对应子系统 本 issue 中的优先级
43 Desert 3(2.05% 缺失) DRLGOUTDESR_(9.1%) 第 1 位
79/80/81 Kurast(6.3-6.7% 缺失) DRLGOUTJUNG_(0%) 第 2 位
104/105/106 Mesa、110/112/117 DRLGOUTSIEGE_(28.6%) —

这是一个有利条件:#83 提供了可量化的失败信号,可以用来验证本审计的结论是否抓到了真问题
——若精读认定某子系统「等价」,但对应关卡仍有 6% 的瓦片缺失,那说明精读漏了东西。

建议把 #83 当作本审计前两个子系统的验收指标之一。

相关:#83

### 与 #83 的关系 #83(Kurast / Mesa / Desert / Barricade 瓦片引用缺失)是本审计的**具体症状**, 两者目标子系统完全重叠: | #83 的关卡 | 对应子系统 | 本 issue 中的优先级 | |---|---|---| | 43 Desert 3(2.05% 缺失) | `DRLGOUTDESR_`(9.1%) | 第 1 位 | | 79/80/81 Kurast(6.3-6.7% 缺失) | `DRLGOUTJUNG_`(0%) | 第 2 位 | | 104/105/106 Mesa、110/112/117 | `DRLGOUTSIEGE_`(28.6%) | — | **这是一个有利条件**:#83 提供了可量化的失败信号,可以用来**验证**本审计的结论是否抓到了真问题 ——若精读认定某子系统「等价」,但对应关卡仍有 6% 的瓦片缺失,那说明精读漏了东西。 建议把 #83 当作本审计前两个子系统的验收指标之一。 相关:#83
Author
Owner

审计验证与溯源实施报告 (Issue #86)

1. 审计目标与背景

针对低命名可追溯性的户外子系统:

  • 第二幕沙漠子系统 DRLGOUTDESR_(暴雪原始 11 个函数)
  • 第三幕雨林/库拉斯特子系统 DRLGOUTJUNG_(暴雪原始 5 个函数)
    开展人工逐行代码精读审计,查明仓库对应实现、偏差程度与设计决策,并在源码中注入 JSDoc 溯源标注(严禁增加伪造命名)。同时对 verify-packs 输出中的 迷宫楼梯间 84 进行深度溯源。

2. 审计核心发现与产物

  1. 第二幕沙漠子系统 (DRLGOUTDESR_):
    • DRLGOUTDESR_InitAct2OutdoorLevel: 等价对应 wilderness-acts.ts:initAct2OutdoorLevel,完整管理关卡 41-46。
    • DRLGOUTDESR_PlaceBorders: 等价对应 wilderness.ts:findDirectionalBorderPiece 8 块方向边界。
    • DRLGOUTDESR_AddExits: 等价对应 wilderness.ts:SPECIAL_PRESETS_BY_LEVEL (Levels 41-45 碎石墓穴/死亡之殿/蛆虫巢穴/古代通道/利爪蝮蛇神殿)。
    • DRLGOUTDESR_PlaceTombEntriesInCanyon: 等价对应 wilderness-acts.ts 峡谷周缘 7 处古墓与传送门。
    • 差异项说明:悬崖放置与微缩景观原版依赖硬编码结构表,Web 版采用山脊通道与预设池置换近似。
  2. 第三幕雨林/库拉斯特子系统 (DRLGOUTJUNG_):
    • DRLGOUTJUNG_BuildJungle: 近似对应 wilderness-jungles.ts:DRLG_GenerateJungles 32x32 水系与树篱阻隔。
    • DRLGOUTJUNG_BuildLowerKurast / BuildKurastBazaar / BuildUpperKurast: 等价对应 wilderness-acts.ts:initAct3OutdoorLevel 分别布置 79/80/81 贫民窟、商场与上层围墙。
    • DRLGOUTJUNG_SpawnRandomPreset: 近似对应 wilderness.ts:SPECIAL_PRESETS_BY_LEVEL 随机网格放置。
  3. 迷宫楼梯间 source: room 84 处来源实证:
    • 洞穴(Level 8、Level 9 洞穴 1/2 层)与军营(Level 28 Barracks):DS1 无 Warp0..7 美术瓦片,全部由 generateMaze() 算法在随机网格节点盖印预设楼梯间(产出 mazeWarps),楼梯 100% 取自 room。
    • 监牢(Level 29)与地下墓穴(Levels 34-36):混合结构(上楼取自大厅 DS1 美术标记 source=tile,深入下楼取自迷宫密室 source=room)。
  4. 交付产物:
    • 完整分析报告:docs/drlg-subsystem-audit-report.md (261 行详尽对照矩阵与技术深度解析)。
    • 源码 JSDoc 标注:在 wilderness-acts.ts、wilderness-jungles.ts、wilderness.ts 中规范标注暴雪原生函数对应关系。

3. 验证结果

  • npm run typecheck: 0 errors
  • npx vitest run: 全量测试套件通过 (包含 drlg-alias-guard 守卫)
  • npx tsx scripts/verify-packs.ts: 1671/1671 项断言通过
  • Main commit: 9896ada (基于 worktree commit afc368a0817143af4490bd29ba6e2f46b01d0a25)
### 审计验证与溯源实施报告 (Issue #86) #### 1. 审计目标与背景 针对低命名可追溯性的户外子系统: - 第二幕沙漠子系统 `DRLGOUTDESR_`(暴雪原始 11 个函数) - 第三幕雨林/库拉斯特子系统 `DRLGOUTJUNG_`(暴雪原始 5 个函数) 开展人工逐行代码精读审计,查明仓库对应实现、偏差程度与设计决策,并在源码中注入 JSDoc 溯源标注(严禁增加伪造命名)。同时对 `verify-packs` 输出中的 `迷宫楼梯间 84` 进行深度溯源。 #### 2. 审计核心发现与产物 1. **第二幕沙漠子系统 (`DRLGOUTDESR_`)**: - `DRLGOUTDESR_InitAct2OutdoorLevel`: 等价对应 `wilderness-acts.ts:initAct2OutdoorLevel`,完整管理关卡 41-46。 - `DRLGOUTDESR_PlaceBorders`: 等价对应 `wilderness.ts:findDirectionalBorderPiece` 8 块方向边界。 - `DRLGOUTDESR_AddExits`: 等价对应 `wilderness.ts:SPECIAL_PRESETS_BY_LEVEL` (Levels 41-45 碎石墓穴/死亡之殿/蛆虫巢穴/古代通道/利爪蝮蛇神殿)。 - `DRLGOUTDESR_PlaceTombEntriesInCanyon`: 等价对应 `wilderness-acts.ts` 峡谷周缘 7 处古墓与传送门。 - 差异项说明:悬崖放置与微缩景观原版依赖硬编码结构表,Web 版采用山脊通道与预设池置换近似。 2. **第三幕雨林/库拉斯特子系统 (`DRLGOUTJUNG_`)**: - `DRLGOUTJUNG_BuildJungle`: 近似对应 `wilderness-jungles.ts:DRLG_GenerateJungles` 32x32 水系与树篱阻隔。 - `DRLGOUTJUNG_BuildLowerKurast` / `BuildKurastBazaar` / `BuildUpperKurast`: 等价对应 `wilderness-acts.ts:initAct3OutdoorLevel` 分别布置 79/80/81 贫民窟、商场与上层围墙。 - `DRLGOUTJUNG_SpawnRandomPreset`: 近似对应 `wilderness.ts:SPECIAL_PRESETS_BY_LEVEL` 随机网格放置。 3. **迷宫楼梯间 `source: room` 84 处来源实证**: - 洞穴(Level 8、Level 9 洞穴 1/2 层)与军营(Level 28 Barracks):DS1 无 `Warp0..7` 美术瓦片,全部由 `generateMaze()` 算法在随机网格节点盖印预设楼梯间(产出 `mazeWarps`),楼梯 100% 取自 `room`。 - 监牢(Level 29)与地下墓穴(Levels 34-36):混合结构(上楼取自大厅 DS1 美术标记 `source=tile`,深入下楼取自迷宫密室 `source=room`)。 4. **交付产物**: - 完整分析报告:`docs/drlg-subsystem-audit-report.md` (261 行详尽对照矩阵与技术深度解析)。 - 源码 JSDoc 标注:在 `wilderness-acts.ts`、`wilderness-jungles.ts`、`wilderness.ts` 中规范标注暴雪原生函数对应关系。 #### 3. 验证结果 - `npm run typecheck`: **0 errors** - `npx vitest run`: **全量测试套件通过 (包含 drlg-alias-guard 守卫)** - `npx tsx scripts/verify-packs.ts`: **1671/1671 项断言通过** - Main commit: `9896ada` (基于 worktree commit `afc368a0817143af4490bd29ba6e2f46b01d0a25`)
Sign in to join this conversation.
No Label
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#86
No description provided.