[M15] 地图与怪物生成逻辑 hardcode / fallback 全量审计(追踪) #64
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#64
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?
概述
对
main分支(origin/main=4c2e399,审计时src/与远端逐字节一致)的地图与怪物生成逻辑做了一次全量 hardcode / fallback 审计。审计方式:三个并行只读子代理逐行通读全部源文件 + 模式扫描(
TODO|FIXME|HACK|placeholder|fallback|approximat|heuristic|stub|synthetic|unimplemented+??/||/catch)。覆盖范围:约 15,000 行
src/game/wilderness{,-acts,-jungles,-siege}.ts、src/game/maze{,-objects,-special-passes}.ts、src/game/world-graph.ts、src/game/level-links.ts、src/game/preset.ts、src/game/monster{s,-mapping,-rooms,-streaming,-art}.ts、src/scene/act-scene.ts总览
LvlWarp.txt几何是真解析的(唯一亮点)合计:约 145 处硬编码 + 约 128 处 fallback + 约 2,200 行本应解析自 MPQ 的手写常量表。
三个核心发现
1. 最严重的问题不是任何单点 bug,而是「静默降级」设计
三层全部采用:数据缺失时不报错、不中断,而是替换成合成值继续生成。
结果是:一个数据完全损坏的世界仍然能「成功」生成,并通过全部 885 个测试。
最典型的例子:
src/game/maze.ts:856声明UNIMPLEMENTED_PASSES = []并注释「11 个核心 pass 均已实现」,但同文件:594-598与scripts/pack-act-assets.ts:733-740都明说墓穴 / 下水道 / 第三幕地牢的楼梯 pass 尚未转写。设计好的预警通道恒报「无缺失」。2. 修复成本远低于表面规模 —— 真解析器已写好但从未被调用
readSuperUniques()monsters.ts:605-644CANONICAL_SUPER_UNIQUES_BY_LEVELreadEliteModifiers()monsters.ts:660-682CANONICAL_ELITE_MODIFIERS+ 内联数值MonsterKind.codemonsters.ts:171-172MONSTER_ART_MAPMonsterArt.meleeRangemonsters.ts:376-389DEFAULT_REACH_PX = 40LevelRow.offsetX/offsetYworld-graph.ts:399-400SEAMLESS_ADJACENCY删表大多只需改接线,不需要写新解析器。
3. 部分「地形生成」是凭空发明,还会破坏真实数据
y(x) = H*(0.35+0.3t) + sin(2πt)*4Act 3 - BridgeDS1stampThemedRoads会walls.length = 0删除格子内所有墙层子 Issue
fix(diag)消除静默降级 —— 让数据缺失响亮失败refactor(monsters)用 MPQ 表取代约 1500 行手写怪物数据fix(world)消除不可达关卡、编造的楼梯位置与传送无限弹射refactor(map)用 LvlPrest/Levels/Objects 表取代约 1100 ���手写地图数据refactor(map)处理凭空发明的程序化地形 passchore消除重复真相源、死代码与形同虚设的逻辑规则修复路线图
值得称赞、不要动的部分
LvlWarp.txt几何是真解析的 ——parseWarpGeometry(world-graph.ts:755-780)正确按(Id, Direction)读取全部列。全树无任何手打 warp 几何。LvlMaze.txt输入是表驱动的 ——pack-act-assets.ts:1557-1563逐关读取SizeX/SizeY/Rooms/Merge。MonStats.txt × MonLvl.txt ÷ 100,含五列校验与完整推理文档(monsters.ts:32-71)。Levels.txtmon 列是真读的 ——monsters.ts:536-543遍历mon/nmon/umon,含Rarity加权。BaseId回退解析 —— 正确处理 60 个无 MonStats2 行的怪物(monsters.ts:350-390)。warp-tiles.ts的 DS1 特殊瓦片语义 —— 有文档且经 10 个关卡验证。assignGateSides失败时抛异常 ——world-graph.ts:576-645是全树少数响亮失败的地方。combat.ts:380-385)。总体验收标准
stats中所有字段反映真实计数,无伪造值npm run typecheck零错误,npx vitest run全绿TAG=agy
CONV=2a1934de-30ef-464e-b3f3-fcbcdbbc49f1
🎉 [M15] 地图与怪物生成逻辑 hardcode / fallback 全量消除 —— 圆满完成!
Milestone 6 (M15) 下规划的 6 个子 Issue 已全部按高保真规范串行修复、独立交叉复验通过,并合入主线分支
main:SuperUniques.txt/MonStats2.txt/MonUMod.txt;修复奶牛等怪物动画 Token;消灭红框占位符;实装攻击距离与属性缩放5f484e5955e9edSUB_TILES_PER_TILE;消除血腥丘陵假步长;动态解析string.tbl关卡名;消灭模块循环依赖;校验 DS1 Type 2 物件池710efa0generateAct3Jungle死代码;保护真实 DS1 预设不被道路/桥梁破坏性抹除;程序化地形 Pass 全指标上报;赋予血腥丘陵障碍物种子多样性c377e8ePACK_RADIUS_PX;修复等距瓦片默认高度;支持mon25动态列;普通怪依据 Rarity 加权选型;实装精英词缀数值机制a7e526d全局验证汇总 (HEAD =
a7e526d)npm run typecheck: 0 错误npx vitest run: 61 test files passed, 1 skipped; 1018 passed (+95 个新增专项测试), 2 skipped (全绿)npx tsx scripts/verify-packs.ts: 1671/1671 项断言通过(逐像素比对了 280.2 MB 的索引数据)TAG=agy
CONV=2a1934de-30ef-464e-b3f3-fcbcdbbc49f1