fix(drlg): 消除 pickVariant 45度斜向机械平铺条纹并纠正生成器虚构 Style #116

Closed
opened 2026-09-18 14:13:52 +00:00 by troytt · 1 comment
Owner

背景与问题描述

在 #111 全地图走查中,发现:

  • Act 4 Mesa 1~3 地表呈现极度明显的 45 度倾斜机械重复斑纹;
  • Act 3 Kurast 1~3 (79~81) 堤道缺失 400 余片瓦片,整条堤道穿孔;
  • Act 4 Mesa 2~3 (105~106) 熔岩裂谷缺失 300 余片瓦片;
  • Act 5 Siege 1 (110) 破损木栅栏缺失百余片瓦片。

根因剖析 (1.13c 对比)

  1. 变体抽取 PRNG 线性周期共振:
    src/game/d2map.ts:402 中的 pickVariant() 采用了公式:
    state = (BigInt(seed >>> 0) + BigInt(cellX >>> 0)) * BigInt(cellY >>> 0)
    该公式在数学上具有强烈的对角线乘积周期性,在 2.5D 等距视角变换 (cellX - cellY, cellX + cellY) 投影下,被几何放大为肉眼刺眼的 45 度平行倾斜条纹。
  2. 生成器虚构 Style 编号:
    • wilderness-acts.ts 在绘制 Kurast 堤道时硬编码 style: 5,而 Kurast (LevelType 18) 的合法地表 style 为 20~22, 30~31, 35, 46, 50,根本不存在 style 5;
    • wilderness-acts.ts 在 Mesa 绘制熔岩裂谷时硬编码 style: 20,而 style 20 属于 Act 4 Lava,Mesa (LevelType 23) 并未载入 Lava 库;
    • wilderness-siege.ts 中的 stampBreachedBarricade 硬编码了 sequence: rng.int(1, 2),而 Expansion/Siege/fence.dt1 的 style 2 只有 sequence 10, 11。

修复要求

  1. 在 src/game/d2map.ts 中重构 pickVariant 的散列算法,采用高质量伪随机混合算法(如 SplitMix64 或 PCG32 哈希),彻底打破坐标对角线共振条纹。
  2. 纠正 wilderness-acts.ts 中的硬编码瓦片:
    • Kurast 堤道改为合法 Kurast 石砖瓦片(style 20 / style 21);
    • Mesa 裂谷地表改为 Mesa 库合法瓦片(style 10);
    • 修正 wilderness-siege.ts 中栅栏越界 sequence。
  3. 增加单元测试 tests/variant-distribution.test.ts,验证随机分布平坦度与无对角线周期性,以及所有关卡生成器生成的瓦片编号均合法。
  4. 门禁通过:npm run typecheck、npx vitest run。

关联主 Issue: #111

## 背景与问题描述 在 #111 全地图走查中,发现: - Act 4 Mesa 1~3 地表呈现极度明显的 45 度倾斜机械重复斑纹; - Act 3 Kurast 1~3 (79~81) 堤道缺失 400 余片瓦片,整条堤道穿孔; - Act 4 Mesa 2~3 (105~106) 熔岩裂谷缺失 300 余片瓦片; - Act 5 Siege 1 (110) 破损木栅栏缺失百余片瓦片。 ## 根因剖析 (1.13c 对比) 1. **变体抽取 PRNG 线性周期共振**: `src/game/d2map.ts:402` 中的 `pickVariant()` 采用了公式: `state = (BigInt(seed >>> 0) + BigInt(cellX >>> 0)) * BigInt(cellY >>> 0)` 该公式在数学上具有强烈的对角线乘积周期性,在 2.5D 等距视角变换 `(cellX - cellY, cellX + cellY)` 投影下,被几何放大为肉眼刺眼的 45 度平行倾斜条纹。 2. **生成器虚构 Style 编号**: - `wilderness-acts.ts` 在绘制 Kurast 堤道时硬编码 `style: 5`,而 Kurast (LevelType 18) 的合法地表 style 为 20~22, 30~31, 35, 46, 50,根本不存在 style 5; - `wilderness-acts.ts` 在 Mesa 绘制熔岩裂谷时硬编码 `style: 20`,而 style 20 属于 Act 4 Lava,Mesa (LevelType 23) 并未载入 Lava 库; - `wilderness-siege.ts` 中的 `stampBreachedBarricade` 硬编码了 `sequence: rng.int(1, 2)`,而 `Expansion/Siege/fence.dt1` 的 style 2 只有 sequence 10, 11。 ## 修复要求 1. 在 `src/game/d2map.ts` 中重构 `pickVariant` 的散列算法,采用高质量伪随机混合算法(如 SplitMix64 或 PCG32 哈希),彻底打破坐标对角线共振条纹。 2. 纠正 `wilderness-acts.ts` 中的硬编码瓦片: - Kurast 堤道改为合法 Kurast 石砖瓦片(`style 20` / `style 21`); - Mesa 裂谷地表改为 Mesa 库合法瓦片(`style 10`); - 修正 `wilderness-siege.ts` 中栅栏越界 sequence。 3. 增加单元测试 `tests/variant-distribution.test.ts`,验证随机分布平坦度与无对角线周期性,以及所有关卡生成器生成的瓦片编号均合法。 4. 门禁通过:`npm run typecheck`、`npx vitest run`。 关联主 Issue: #111
Author
Owner

修复完成并已合并至 main

  • Commit: f111ba5a7415d038375af0d976f0f31195fefbe2 (Merge: 51c869d)
  • 变更摘要:
    1. 改进 src/game/d2map.ts 中的 pickVariant 算法:引入 SplitMix64 伪随机空间坐标散列,彻底消除原有简单算术乘积在斜 45 度方向产生的明显机械周期性几何平铺条纹伪影。
    2. 在 src/game/wilderness-acts.ts 与 src/game/wilderness-siege.ts 中纠正野外生成器虚构硬编码的 Style 编号,改为基于当前 DT1 库实际导出的 styles/sequences。
    3. 新增单元测试 tests/variant-distribution.test.ts 验证变体分布方差与空间均匀性。
  • 验证结果: npm run typecheck 0 errors,全量 vitest run 测试通过。
### 修复完成并已合并至 main - **Commit**: `f111ba5a7415d038375af0d976f0f31195fefbe2` (Merge: `51c869d`) - **变更摘要**: 1. 改进 `src/game/d2map.ts` 中的 `pickVariant` 算法:引入 SplitMix64 伪随机空间坐标散列,彻底消除原有简单算术乘积在斜 45 度方向产生的明显机械周期性几何平铺条纹伪影。 2. 在 `src/game/wilderness-acts.ts` 与 `src/game/wilderness-siege.ts` 中纠正野外生成器虚构硬编码的 Style 编号,改为基于当前 DT1 库实际导出的 styles/sequences。 3. 新增单元测试 `tests/variant-distribution.test.ts` 验证变体分布方差与空间均匀性。 - **验证结果**: `npm run typecheck` 0 errors,全量 `vitest run` 测试通过。
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#116
No description provided.