Files
dragon-hd/docs/superpowers/plans/2026-09-20-high-impact-simple-first.md
T

175 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# DragonHD 高收益、低复杂度优先 Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** 先补齐可直接影响游玩体验的教程中文,再用少量贴图证明 2× 高清化收益,最后按验证结果扩大范围。
**Architecture:** 沿用已验收的字体补丁、GB2312 文本和资源解包成果。显示文本采用原文校验后的定点替换;高清素材采用独立清单、小批量构建及恢复。中文排版和贴图升级各自交付,避免同时更换多个变量。
**Tech Stack:** Python、Pillow、现有 res 工具;字体回归使用 Keystone/UnicornDDS 写回先确认编码工具及 mipmap 支持。
**Spec:** `docs/superpowers/specs/2026-09-20-next-steps.md`
## Global Constraints
- 游戏目录:`F:\steam\steamapps\common\The I of the Dragon`;工作目录:`E:\DragonHD`
- 保留目前 12px CJK 字库和通过验收的排版补丁。
- 脚本仅改显示调用中的文本字面量;逻辑标识、事件名、路径、单位类型保持字节不变。
- 每批单独记录原文件 SHA256、变更文件清单和可验证的恢复方式。
- 新文本须能 GB2312 编码,保留原有格式占位符和引擎控制符。
- 贴图第一轮只做 2×,保留比例;透明通道、压缩类型及 mipmap 策略逐项核验。
- Git 只提交自制工具、文本映射和文档,原始/生成游戏资源留在本地。
- 先看原比例游戏截图,再判断是否扩大处理范围;局部放大截图只辅助检查。
## 排序与完成条件
| 顺序 | 工作 | 可见收益 | 复杂度 | 首批完成条件 |
|---|---|---|---|---|
| 1 | 教程显示文本汉化 | 入门流程基本不再出现英文讲解 | 低—中 | 教程提示/任务说明中文;关键教程事件正常推进 |
| 2 | 8 张贴图 2× 试做 | 判断实际清晰度提升,避免白做整库 | 中,TGA 较低 | 至少 2 张通过实机原比例对比;逐文件可恢复 |
| 3 | 合格类型批量 20–50 张 | 扩大已确认有效的高清范围 | 低—中,依赖第 2 项 | 常见素材观感提升,未出现黑边、接缝或明显卡顿 |
| 4 | 主线按章翻译 | 扩大中文覆盖到正式任务 | 中,依赖第 1 项 | 首章显示文本完成,任务触发和读档正常 |
第 1、2 项是下一轮可执行任务;第 3、4 项是通过前置验收后再展开的队列。
不以“479/496”补到 100% 为目标:格式串、路径和空值保留其原有用途。
## 开始前复核
在工作目录运行:
```powershell
python tools/test_cjk_layout.py -q
python tools/test_cjk_titles.py -q
python tools/check_translations.py
git status --short
```
预期:14 项排版测试及 2 项标题测试通过,格式占位符不匹配为 0。
记录当前游戏文件哈希,不覆盖 `backup_game/font-layout-20260920` 中的既有快照。
## Task 1: 教程文本完整提取、翻译与回灌
**Files:**
- Create: `tools/script_text.py`(扫描允许的显示调用并精确定位字符串跨度)。
- Create: `tools/test_script_text.py`(编码、转义、续行、只修改显示文本的行为测试)。
- Create: `tools/tutorial_cn.json`(原文校验值及中文映射)。
- Modify: `docs/DEVLOG.md`(验收结果及未覆盖项)。
- Local input: `F:\steam\steamapps\common\The I of the Dragon\Data\Scripts\English\Tutorial.dsc`
- Local output: `build/tutorial/Tutorial.dsc``build/tutorial/manifest.json`
**Interfaces:**
- `patch_display_calls(source: bytes, translations: dict[str, str]) -> bytes`
- 映射键为解码后的原文字面量;同文同步替换,未命中的映射报错。
- 仅允许 `DisplayMessage` 的两个字符串实参与 `SetMissionDescription` 的字符串实参。
- CLI`python tools/script_text.py --source <path> --mapping tools/tutorial_cn.json --out build/tutorial/Tutorial.dsc`
- 工具只生成文件,不在构建时写游戏目录。
- [ ] **Step 1:固定输入。** 复制教程到本批次备份并计算 SHA256。当前文件为 21,166 字节;扫描可见 22 处 `DisplayMessage(`(含函数定义)、15 处 `SetMissionDescription(`,最终以解析出的字面量为准。
- [ ] **Step 2:建立失败测试。** 除下例外,补充注释内伪调用、变量实参、转义引号、反斜杠续行、重复原文、映射缺项与不可编码字符的样例。禁止用匹配全部引号字符串的正则替换脚本。
```python
import unittest
from script_text import patch_display_calls
class ScriptTextTests(unittest.TestCase):
def test_only_display_literals_change(self):
source = b'DisplayMessage("Help", "Move");\r\nEnableEvent("Move");\r\n'
actual = patch_display_calls(source, {'Help': '帮助', 'Move': '移动'})
expected = 'DisplayMessage("帮助", "移动");\r\nEnableEvent("Move");\r\n'.encode('gb2312')
self.assertEqual(actual, expected)
```
- [ ] **Step 3:运行测试并确认失败原因。** `python -m unittest discover -s tools -p test_script_text.py -v`
- [ ] **Step 4:实现字节扫描器。** 逐字节维护注释/字符串/转义/括号状态,只标记允许调用的字面量范围;按原范围倒序替换。输出前检查原文命中、GB2312、占位符与控制符;原文件其他字节全部保留。
- [ ] **Step 5:翻译第一组实机可达提示。** 先做 Tutorial、Camera rotation、Center the camera、Zoom、Flight 及其重复任务说明。表达简洁,键位说明准确,不擅自改变操作要求。
- [ ] **Step 6:执行测试与构建。** 使用上述测试命令和 CLI;核对所有改动仅在提取的字面量跨度中,备份哈希与输入一致。
- [ ] **Step 7:完成其余教程显示文本。** 用同一映射、同一规则补齐;控制符 `\a/\f/\n` 与格式参数单独检查。记录保留英文的专名及理由。
- [ ] **Step 8:退出游戏后部署教程副本。** 依次验收镜头旋转、镜头回正、缩放、飞行及后续教程步骤;检查提示显示和下一事件触发,保存实机截图与结果。中途恢复旧教程后验证哈希一致,再装回新版。
- [ ] **Step 9:提交独立变更。** `git add tools/script_text.py tools/test_script_text.py tools/tutorial_cn.json docs/DEVLOG.md``git commit -m "feat: translate tutorial display text without changing events"`
**完成门槛:** 显示文本中文、脚本逻辑字节不变、教程触发链实机通过,已有字体回归仍通过。仅文件成功生成不算教程已验收。
## Task 2: 8 张 2× 贴图试做,先评估再扩大
**Files:**
- Create: `tools/hd_pilot.json`(本轮选择及源文件哈希)。
- Create: `tools/hd_pilot.py`(选图、对比页、构建清单)。
- Create: `tools/test_hd_pilot.py`(尺寸、通道、清单与误选保护)。
- Create: `docs/hd-pilot-review.md`(每张在游戏中的结论)。
- Existing inputs: `report/upscale_plan.csv``report/textures_report.csv``png/``original/`
- Local outputs: `build/hd-pilot/`;原图不覆盖。
**首批候选(已在当前资源清单中核对存在):**
| 素材 | 原尺寸 | 用途 |
|---|---|---|
| `BigRock.tga` | 128×128 | 简单 TGA 回灌验证 |
| `Black_stone.tga` | 128×128 | 石材细节对比 |
| `creatures\amfibrahiy1.dds` | 256×128 | 不透明 DXT1 生物样本 |
| `creatures\Beatle.dds` | 256×256 | 不透明 DXT1 生物样本 |
| `buildings\arka.dds` | 256×128 | 建筑边缘细节 |
| `buildings\bochka01.dds` | 256×256 | 常见道具细节 |
| `buildings\brev-tor.dds` | 128×128 | 木材端面 |
| `buildings\brev.dds` | 128×256 | 木材表面 |
候选名称仅用于定位;先在游戏中确认可见场景。难以找到的素材换成同组、已确认可见的条目,并更新清单。自动分类可能遗漏平铺用途,实际出现接缝的样本移入后续专项。
**Interfaces:**
- `validate_size(original: tuple[int, int], result: tuple[int, int]) -> None`:只接受精确 2×,否则抛出 `ValueError`
- `hd_pilot.json` 每项:`name``source_sha256``scale: 2``alpha_policy: "preserve"`
- 每张比较原图、Lanczos 2× 基线、可用模型 2× 候选;尚无模型时先完成基线/回灌,不宣称 AI 高清化完成。
- [ ] **Step 1:记录源素材并建清单。** 核对原尺寸、通道、FourCC 和 mipmap;排除字体、UI 图集、烘焙文字、透明特效与已知平铺纹理。
- [ ] **Step 2:添加失败测试。**
```python
import unittest
from hd_pilot import validate_size
class PilotTests(unittest.TestCase):
def test_preserves_aspect_ratio_at_exact_two_times(self):
validate_size((256, 128), (512, 256))
with self.assertRaises(ValueError):
validate_size((256, 128), (512, 512))
```
- [ ] **Step 3:运行失败测试。** `python -m unittest discover -s tools -p test_hd_pilot.py -v`
- [ ] **Step 4:实现构建约束。**
```python
def validate_size(original, result):
if result != (original[0] * 2, original[1] * 2):
raise ValueError('pilot texture must be exactly 2x with unchanged aspect ratio')
```
- [ ] **Step 5:先完成两张 TGA 的原比例/放大对比。** Pillow 生成 Lanczos 基线;若已有可用超分模型,再生成模型版,保留三个版本。不要将普通插值称为新增细节。
- [ ] **Step 6:验证 DDS 写回。** 先做原尺寸 decode/encode 对照,核对 DXT1、通道与 mipmap;确认工具链后再做六张 DDS 的 2×。若编码或材质兼容未通过,本轮仅交付已通过的 TGA 结果,并在审查文档标记 DDS 阻塞原因。
- [ ] **Step 7:逐张回灌。** 优先使用已验证的松散文件覆盖方式;有打包加载差异再以现有 `replace_res_entries` 工具重建副本,逐条核对非目标资源哈希。单独保存每个被覆盖文件及是否原本存在。
- [ ] **Step 8:同存档同视角截图比较。** 记录正常距离的观感、边缘光晕、纹理游动、接缝、加载耗时和帧率;帧率在同一场景预热后测三次。若中位帧率下降超过 5%,调查原因并暂不扩大批次。
- [ ] **Step 9:恢复验证与小批次结论。** 恢复原文件并验哈希;只重新部署“正常视距可见改善、无明显副作用”的样本。逐张标记通过/维持原版/需专项处理。
- [ ] **Step 10:提交工具与结果文档。** `git add tools/hd_pilot.py tools/test_hd_pilot.py tools/hd_pilot.json docs/hd-pilot-review.md``git commit -m "feat: add validated two-times texture pilot"`
**完成门槛:** 至少 2 张实机效果优于原图且可完整恢复。即使模型版更锐,也允许选择观感更自然的基线或原版。
## 后续队列的启动条件
- **Task 32050 张高清小批次。** 第 2 项确认至少一种素材类别收益稳定后再编写该批实施清单。优先玩家常见生物、建筑、道具;按清单逐张记录,不把全部 1195 张自动纳入。
- **Task 4:主线首章汉化。** 第 1 项显示文本工具和事件回归验收后,以 `MainMission.dsc` 的实际显示调用清单确定章节边界,再单独编写实施计划。未证实的调用不加入自动替换白名单。
## 每项交付时报告
报告本项改了什么、实机看到的收益、验证结果、已知未完成点和恢复方式。
每项单独提交;没有明确收益的试验及时止步,不因已经生成文件就继续批处理。
## 2026-09-20 分批执行进度
按用户“一步一步尝试汉化”将 Task 1 的首次实机批次缩小为开场、旋转镜头、镜头回正、缩放,飞行留待下一批。
- [x] 固定原始备份与 SHA256,建立独立工作区。
- [x] 文本扫描器和 14 项测试;首批 9 条映射、12 处显示文字。
- [x] 非显示字节逐段核对;原有 16 项字体回归通过。
- [x] 在独立副本执行恢复并核对原始哈希;生成差异和验证记录。
- [x] 游戏退出后部署,重读游戏文件并通过校验。
- [ ] 用户实机验证首批中文显示和教程事件推进。
- [ ] 首批确认后继续飞行及后续教程;Task 1 整体验收仍未完成。