refactor(map-gen/preset): 纠正固定地图“象限(quadrant)”错误认知,实现 File1..File6 独立版本(Variants)自动选择与世界图连通匹配 #42

Closed
opened 2026-09-17 05:20:34 +00:00 by troytt · 1 comment
Owner

背景与认知纠正

此前在工程注释(src/game/acts.ts:11)与 UI(src/scene/act-scene.ts 的 quadrantSelect)中,误将 LvlPrest.txt 中的 File1..File6(如第一幕罗格营地的 TownN1.ds1、TownE1.ds1、TownS1.ds1、TownW1.ds1)定义为“营地的四个象限(quadrants)”,并误认为需要将它们拼接缝合。

经过核查,这一认知是错误的:

  1. 尺寸核对:在官方 Levels.txt 中,第一幕城镇总尺寸定义为 57 × 41;而 TownN1、TownE1、TownS1、TownW1 四个 DS1 文件各自的解码尺寸均恰好是 57 × 41,每一个文件本身就是一张完整的罗格营地全景图。
  2. 设施与 NPC 独立完整:每个文件各自均拥有 1 个传送点、篝火、储物箱、全套 6 位核心 NPC(阿卡拉、恰西、卡夏、基德、瓦瑞夫、凯恩)以及 1 处大门出口。
  3. 官方规范定义:LvlPrest.txt 的表头字段明确定义为 Files(The amount of versions the map has)与 File 1 to File 6(The location of the ds1 versions)。N1/E1/S1/W1 分别对应通往鲜血荒地(Blood Moor)的出口朝向(North/East/South/West)。

暗黑2原版逻辑(Oracle / Ground Truth)

在官方 D2 源码(D2Common/DRLG/DrlgPreset.cpp 中的 DRLGPRESET_GenerateLevel)中:

  • 当固定预制关卡拥有多个备选版本(Files > 1)时,引擎在单局游戏生成世界时,依据地图种子(Seed % Files)或根据与相邻野外地图(鲜血荒地)衔接大门的朝向,自动抽选其中唯一一个匹配的完整版本实例化为该局的城镇。
  • 玩家在单次游戏中只体验该特定出口朝向的城镇,全过程无手动象限选择。

差异点与当前缺陷

  1. 命名与概念混淆:代码与文档中大量残留 quadrant(象限)术语,误导了地图拼装与世界连通的设计思路。
  2. 生成未与世界图出入口对齐:当前离线烘焙将 4 个版本全部作为独立子关卡打包,而在运行时由玩家在 UI 下拉框里手动切换,破坏了世界连通性与单局游戏的沉浸感。
  3. 边界衔接缺乏朝向匹配:当鲜血荒地(Blood Moor)生成的大门朝向确定时,城镇版本未与鲜血荒地的入口朝向进行互逆对齐(如鲜血荒地西侧入口必须对接营地东门 TownE1)。

解决建议与改造方案

  1. 术语与概念清理:将 acts.ts、d2map.ts、act-scene.ts 中的 quadrant(象限)全面重命名为 variant / presetVersion(版本变体)。
  2. 依据世界图自动匹配单版本:在生成或进入第一幕城镇时,依据当前局地图种子及鲜血荒地(Level 2)对接边界的开口朝向,自动选定唯一的营地版本(如鲜血荒地在东则选 TownE1),废除界面上的手动象限选择。
  3. 第二幕鲁高因对齐:同样针对第二幕鲁高因(LutW.ds1 西门 vs LutN.ds1 北门),依据与碎石荒地(Rocky Waste)的对接方位实现自动化单版本匹配。
## 背景与认知纠正 此前在工程注释(`src/game/acts.ts:11`)与 UI(`src/scene/act-scene.ts` 的 `quadrantSelect`)中,误将 `LvlPrest.txt` 中的 `File1..File6`(如第一幕罗格营地的 `TownN1.ds1`、`TownE1.ds1`、`TownS1.ds1`、`TownW1.ds1`)定义为“营地的四个象限(quadrants)”,并误认为需要将它们拼接缝合。 **经过核查,这一认知是错误的**: 1. **尺寸核对**:在官方 `Levels.txt` 中,第一幕城镇总尺寸定义为 `57 × 41`;而 `TownN1`、`TownE1`、`TownS1`、`TownW1` 四个 DS1 文件**各自的解码尺寸均恰好是 57 × 41**,每一个文件本身就是一张完整的罗格营地全景图。 2. **设施与 NPC 独立完整**:每个文件各自均拥有 1 个传送点、篝火、储物箱、全套 6 位核心 NPC(阿卡拉、恰西、卡夏、基德、瓦瑞夫、凯恩)以及 1 处大门出口。 3. **官方规范定义**:`LvlPrest.txt` 的表头字段明确定义为 `Files`(The amount of versions the map has)与 `File 1 to File 6`(The location of the ds1 versions)。`N1/E1/S1/W1` 分别对应通往鲜血荒地(Blood Moor)的出口朝向(North/East/South/West)。 ## 暗黑2原版逻辑(Oracle / Ground Truth) 在官方 D2 源码(`D2Common/DRLG/DrlgPreset.cpp` 中的 `DRLGPRESET_GenerateLevel`)中: - 当固定预制关卡拥有多个备选版本(`Files > 1`)时,引擎在单局游戏生成世界时,依据地图种子(`Seed % Files`)或根据与相邻野外地图(鲜血荒地)衔接大门的朝向,**自动抽选其中唯一一个匹配的完整版本**实例化为该局的城镇。 - 玩家在单次游戏中只体验该特定出口朝向的城镇,全过程无手动象限选择。 ## 差异点与当前缺陷 1. **命名与概念混淆**:代码与文档中大量残留 `quadrant`(象限)术语,误导了地图拼装与世界连通的设计思路。 2. **生成未与世界图出入口对齐**:当前离线烘焙将 4 个版本全部作为独立子关卡打包,而在运行时由玩家在 UI 下拉框里手动切换,破坏了世界连通性与单局游戏的沉浸感。 3. **边界衔接缺乏朝向匹配**:当鲜血荒地(Blood Moor)生成的大门朝向确定时,城镇版本未与鲜血荒地的入口朝向进行互逆对齐(如鲜血荒地西侧入口必须对接营地东门 `TownE1`)。 ## 解决建议与改造方案 1. **术语与概念清理**:将 `acts.ts`、`d2map.ts`、`act-scene.ts` 中的 `quadrant`(象限)全面重命名为 `variant` / `presetVersion`(版本变体)。 2. **依据世界图自动匹配单版本**:在生成或进入第一幕城镇时,依据当前局地图种子及鲜血荒地(Level 2)对接边界的开口朝向,自动选定唯一的营地版本(如鲜血荒地在东则选 `TownE1`),废除界面上的手动象限选择。 3. **第二幕鲁高因对齐**:同样针对第二幕鲁高因(`LutW.ds1` 西门 vs `LutN.ds1` 北门),依据与碎石荒地(Rocky Waste)的对接方位实现自动化单版本匹配。
troytt changed title from fix(map-gen/preset): 固定地图多 DS1 象限未拼接缝合,城镇场景被割裂为独立孤岛子场景 to refactor(map-gen/preset): 纠正固定地图“象限(quadrant)”错误认知,实现 File1..File6 独立版本(Variants)自动选择与世界图连通匹配 2026-09-17 05:28:41 +00:00
Author
Owner

已在分支 fix/issue-42 中真实修复并验证通过。

Commit: a01cffa
验证项:

  • 4/4 单元测试通过 (tests/variants.test.ts)
  • TypeScript 类型检查通过 (npx tsc --noEmit)
  • 全量 35 个测试套件 639 测试全绿
已在分支 `fix/issue-42` 中真实修复并验证通过。 Commit: `a01cffa` 验证项: - 4/4 单元测试通过 (`tests/variants.test.ts`) - TypeScript 类型检查通过 (`npx tsc --noEmit`) - 全量 35 个测试套件 639 测试全绿
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#42
No description provided.