dsh-hoi4-modding 1.1.1 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,190 +1,210 @@
1
- ---
2
- name: hoi4-modding
3
- description: 《钢铁雄心4》(Hearts of Iron IV, HOI4) 1.19.3 Mod 开发全流程技能:读游戏文件、新建 Mod、写国策/事件/决议/理念/角色/科技/州/MIO/特殊项目/scripted GUI、本地化与 DDS 图标、静态校验、安装启用、按 error.log 排错、发布创意工坊。Use whenever the user asks to create, edit, fix, validate, install, publish, or debug an HOI4 mod or asks about HOI4 scripting (scopes, effects, triggers, variables, focus trees, events, decisions, ideas, characters, MIO, special projects, GUI, localisation, DDS), even if they only say "做个国策树"/"加个事件"/"mod 报错了".
4
- whenToUse: 用户要做/改/修/校验/安装/发布 HOI4 Mod,或问 HOI4 脚本写法(scope/effect/trigger/变量/国策/事件/决议/理念/角色/MIO/特殊项目/GUI/本地化/DDS)时。
5
- ---
6
-
7
- # HOI4 1.19.3 Mod 制作全流程
8
-
9
- 面向 **1.19.3.0 "Operation Postern"**(`E:\Steam\steamapps\common\Hearts of Iron IV`)实测整理。
10
- 目标不是讲概念,而是**一次把可运行的 Mod 做出来**:放对文件 → 写对语法 → 本地化齐全 → 校验通过 → 装进游戏 → error.log 干净。
11
-
12
- > 本机还保留了一套 57 篇的深度知识库(见文末「深度资料」):需要查字段细节时读它;本 SKILL 与 `references/` 是压缩版,足够完成 90% 任务。
13
-
14
- ## 0. 开始前先确认 3 件事
15
-
16
- 1. **游戏路径**:`E:\Steam\steamapps\common\Hearts of Iron IV`(`HOI4_GAME` 环境变量可覆盖)。
17
- 2. **版本**:`launcher-settings.json` 里 `rawVersion` 应为 `1.19.3.0`;不是就按对应版本调整语法(尤其学说/特殊项目)。
18
- 3. **目标国家有没有专属国策树**:**1.19 每个国家同一时间只有一棵激活国策树**(`country = { }` 是打分,取最高分)。
19
- - 没有专属树(用 `generic_focus`,如 LUX、IRE、BHU):可以新建一整棵树,`add = 10` 就接管。
20
- - 已有专属树(SWE、GER、SOV…):不能"再加一棵";只能覆盖原树文件、或 `load_focus_tree` 换树(会顶掉原树)。先向用户确认接受哪种。
21
-
22
- ## 1. 铁律(违反任何一条都会踩坑)
23
-
24
- 1. **永不改游戏安装目录**;所有内容写在 Mod 目录,装到 `Documents/Paradox Interactive/Hearts of Iron IV/mod/`。
25
- 2. **同名文件 = 整体替换**(不是合并)。优先**新增文件**,不要复制整份原版文件。
26
- 3. **同 ID = 后者覆盖前者**;ID 用你的 `NS_` 前缀,事件用独立 `add_namespace`。
27
- 4. **本地化 `.yml` 必须 UTF-8 with BOM**;目录名与首行根键一致(`english` → `l_english:`,`simp_chinese` → `l_simp_chinese:`)。
28
- 5. **2D sprite 定义放 `interface/*.gfx`**,DDS 文件放 `gfx/interface/...`;`gfx/` 下的 `.gfx` 是 3D 用的。
29
- 6. **图标尺寸**:国策 100×88(+ `_shine`)、理念 60×68、决议 32×33、决议类别 40×51、肖像 156×210、旗帜 82×52 TGA。
30
- 7. **DDS 用未压缩 raw32 最稳**(原版 UI 同构:`dwFlags=0x81007`、无 mipmap);DXT 要求宽高为 4 的倍数。
31
- 8. **`.mod` 的 `path` 用纯 ASCII 正斜杠**;中文路径可能加载失败 → 用 `install_mod.py` 复制到玩家目录。
32
- 9. **`.mod` 字段是 `picture=`**,不是 `thumbnail=`;`supported_version` 写 `"1.19.*"` 或 `"1.19.3.0"`,写 `*`/`1.*` 会报错。
33
- 10. **不要依赖 DLC**:需要 DLC 内容时用 `has_dlc = "..."` 分支并标注;特殊项目依赖 `Gotterdammerung`。
34
- 11. **错误看 `logs/error.log`**(`[时间][游戏日期][文件:行]: 消息`),只 grep 自己的文件名/ID;原版噪声占 95%+。
35
- 12. **脚本改动必须重启游戏**,没有完整热重载;静态校验不能替代进游戏。
36
- 13. **科技页(`technology_folders`)的 `available` 只用 `original_tag`,不要用 `has_country_flag`**:
37
- 引擎建页画线时会对该触发器做二次运行时求值,旗帜判定失败时**整页连线被静默丢弃**(方框还在、日志干净、旧存档可能正常而新开档必现)。见 `references/tech-tree-ui.md` §3。
38
- 14. **大框/小框混排是三件套**:科技加 `force_use_small_tech_layout = yes` + 页面有 `techtree_<folder>_small_item` 模板 +
39
- `GFX_technology_<folder>_small_*_item_bg` 精灵**指向真正的小图**。模板 size 只管排版,背景贴图按自身像素绘制——精灵还指着 203×84 大图时,画面就是"小框模板 + 大框外观 + 整体偏位"。
40
-
41
- ## 2. 标准工作流
42
-
43
- ```
44
- 0) 侦察 读游戏文件确认目标系统/字段/原版参考(grep 原版用例)
45
- 1) 骨架 scripts/new_mod.py 生成 descriptor.mod + .mod + 本地化 + 示例内容
46
- 2) 内容 按 references/cheatsheet.md 的配方逐类添加(国策/事件/决议/理念/角色/科技/州/GUI…)
47
- 3) 本地化 每个 ID 同时补 english + simp_chinese(BOM),key 规则见 cheatsheet §2
48
- 4) 校验 python scripts/hoi4_lint.py <Mod目录>
49
- 5) 安装 python scripts/install_mod.py <Mod目录> --yes --enable
50
- 6) 实测 启动游戏(-debug_mode)→ 新开档 → 控制台触发 → 看 error.log
51
- 7) 发布 descriptor.mod 的 name/supported_version/tags/picture 齐全;干净 playset 复测
52
- ```
53
-
54
- 每次只加一类内容、加完就校验;不要一次写 2000 行再排错。
55
-
56
- ## 3. 配方索引(代码在 `references/cheatsheet.md`)
57
-
58
- | 任务 | 章节 |
59
- |---|---|
60
- | 新建 Mod 骨架 / `.mod` 与 `descriptor.mod` | cheatsheet §1 |
61
- | 本地化规则、key 命名、颜色/变量/图标 | §2 |
62
- | 国家精神(idea) | §3 |
63
- | 国策树(含一国一树规则、互斥/前置/奖励) | §4 |
64
- | 事件(MTTH / is_triggered_only / 选项 / 事件链) | §5 |
65
- | 决议(category / decision / targeted / 任务型) | §6 |
66
- | 角色(领袖/顾问/将领/科学家) | §7 |
67
- | 科技(folder / dependencies / on_research_complete) | §8 |
68
- | **科技树 UI:页面可用性 / 连线 / 大小框 / 拆页合并 / 调试手法** | `references/tech-tree-ui.md` |
69
- | 州、资源、建筑 | §9 |
70
- | 动态变量 + 动态修正 | §10 |
71
- | scripted GUI 面板(4 文件挂载) | §11 |
72
- | MIO / 特殊项目 | §12 |
73
- | 贴图、DDS、GFX 注册 | §13 |
74
- | 调试命令与 error.log 对照表 | §14 |
75
- | 1.19 与旧教程差异清单 | §15 |
76
-
77
- ## 4. 工具(`scripts/`,仅标准库;DDS 工具需 Pillow)
78
-
79
- `$S` = **本技能资源目录**下的 `scripts`(加载技能时返回的 Base directory;本地安装通常是
80
- `~/.agents/skills/hoi4-modding/scripts`,从插件市场安装时在插件包的 `skills/hoi4-modding/scripts`)。
81
- Windows PowerShell 示例(`python` 不可用时换成本机 Python 绝对路径):
82
-
83
- ```powershell
84
- $S = "$env:USERPROFILE\.agents\skills\hoi4-modding\scripts" # 市场安装:换成技能返回的 Base directory\scripts
85
- $GAME = "E:\Steam\steamapps\common\Hearts of Iron IV"
86
-
87
- # 新建 Mod 骨架(--focus 可选;--tag 默认 LUX,因为 LUX 没有专属国策树)
88
- & python "$S\new_mod.py" "D:\mods\MyMod" --name "My Mod" --prefix MY --tag LUX --focus
89
-
90
- # 静态校验(语法/编码/本地化/GFX/ID冲突/.mod 结构;首次约 20s 建原版索引)
91
- & python "$S\hoi4_lint.py" "D:\mods\MyMod" --game $GAME
92
-
93
- # 只查语法、不建原版索引(快)
94
- & python "$S\hoi4_lint.py" "D:\mods\MyMod" --no-vanilla
95
-
96
- # 从官方 documentation/*.md 生成 effects/triggers/modifiers/console 参考
97
- & python "$S\build_reference.py" --game $GAME --out .\reference
98
-
99
- # 安装到玩家 mod 目录并启用(复制安装;不要 --link,路径含中文时会被警告)
100
- & python "$S\install_mod.py" "D:\mods\MyMod" --yes --enable
101
-
102
- # 卸载
103
- & python "$S\install_mod.py" "D:\mods\MyMod" --uninstall --yes
104
-
105
- # DDS 图标:生成/检查(Pillow)
106
- & python "$S\dds_helper.py" make icon.png out.dds --width 60 --height 68
107
- & python "$S\dds_helper.py" check out.dds
108
-
109
- # 科技页完整性审计(注册表 <-> 页面/页签/item 模板/网格/科技/本地化)
110
- & python "$S/tech_tree_audit.py" "D:/mods/MyMod"
111
-
112
- # 科技页可用性:has_country_flag -> original_tag(--check 先看,--apply 写入并备份,--revert 回滚)
113
- & python "$S/tech_folder_available.py" "D:/mods/MyMod" --check
114
- & python "$S/tech_folder_available.py" "D:/mods/MyMod" --apply
115
-
116
- # item 模板尺寸 vs 背景精灵像素(专治"小框显示成大框")
117
- & python "$S/item_sprite_check.py" "D:/mods/MyMod" --folder my_folder
118
-
119
- # error.log 分诊(科技树 / 贴图 / scope / 未知字段 / 本地化)
120
- & python "$S/errorlog_triage.py"
121
- ```
122
-
123
- > Git Bash 中把 `$S\x.py` 写成 `"$S/x.py"`、`$GAME` 写成 `/e/Steam/...` 即可。
124
- > 本机 DSH 自带 Python:`C:\Users\17876\.dsh\dsh-runtimes\dsh-primary-runtime\dependencies\python\python.exe`(含 Pillow)。
125
-
126
- `new_mod.py` 会生成:`descriptor.mod`、同级 `.mod`(path 指向目标目录)、`localisation/{english,simp_chinese}`(BOM)、1 个理念、`events/` 1 个可触发事件、可选国策树;并自动跑一次 lint。
127
-
128
- ## 5. 排错:从 error.log 反推
129
-
130
- 先确认「只启用原版 + 你的 Mod」,再 grep 自己的文件/ID:
131
-
132
- | error.log 关键字 | 常见原因 | 修法 |
133
- |---|---|---|
134
- | `Invalid Scope, supported: Country, provided: None` | effect/trigger 用错 scope | 查效果文档的 `Supported Scopes`;用 `every_country`/`GER = { }` 切 scope |
135
- | `Unknown effect-type: xxx` | 关键字拼错/版本没有/不在该 scope | `grep xxx reference/effects.json`;对照 1.19 官方文档 |
136
- | `Unknown trigger-type` / `Not a valid value` | trigger 名或参数值错误 | 查 `reference/triggers.json`;值看文档枚举 |
137
- | `Unknown modifier: xxx` | 修正名拼错(静态修正/动态修正都会) | `grep xxx reference/modifiers.json` |
138
- | `Unexpected token` | 括号/引号不平衡;`.mod` 字段拼错(如 `thumbnail`) | 跑 lint;检查 `picture=`/`path=` |
139
- | `Tried to get dynamic token` / `dynamic token ... OOS` | 本地化/脚本拼接 key 未注册 | 改用普通 loc key 或 `synchronized_dynamic_tokens` |
140
- | 图标空白/黑块 | GFX 未注册、texturefile 不存在、DDS 头不对 | `dds_helper.py check`;确认 sprite 在 `interface/*.gfx` |
141
- | 中文方框 | GUI 用了没有中文 `bitmapfont_override` 的字体名 | 换有中文覆盖的字体(见知识库 `05_presentation/chinese_fonts.md`) |
142
- | 国策树不显示 | 原版树分数更高;或树 id/坐标错误 | 按 §4 规则选「无专属树国家」或覆盖原树 |
143
- | 科技页**方框全在、连线一条没有**、日志干净 | `technology_folders.available` 用了 `has_country_flag`,建页画线阶段判定失败 → 整页 path 静默丢弃 | 改成 `original_tag = <TAG>`(`tech_folder_available.py`),**新开档**验证 |
144
- | 小框科技显示成大框且整体偏位 | 小框模板生效了,但 `GFX_technology_<folder>_small_*_item_bg` 指向 203×84 大图 | `item_sprite_check.py` 定位后把 textureFile 换成 72×72 小图 |
145
- | 某页永远不显示 | `available = { always = no NOT = {...} }`(AND 关系恒 false) | 去掉 `always = no`,只留 `NOT = {...}` 或 `original_tag` |
146
-
147
- 游戏内调试:`-debug_mode` 启动,控制台(`~`/`^`)常用 `event hho.1`、`focus.autocomplete`、`debug_events`、`tag SWE`、`pp 500`;完整命令见 `reference/CHEATSHEET_console.md`(若已生成)。
148
-
149
- ## 6. 验收清单
150
-
151
- - [ ] `hoi4_lint.py` 0 error(warning 尽量清零)。
152
- - [ ] 所有新增 ID 有 en + zh 本地化,`.yml` 带 BOM。
153
- - [ ] 所有 `GFX_` 引用真实存在;自绘 DDS 尺寸/格式正确。
154
- - [ ] 没有覆盖原版整文件(除非有意);`.mod` path 为 ASCII。
155
- - [ ] 干净 playset 进游戏:新开档、触发全部内容、`error.log` 无自己文件的报错。
156
- - [ ] **新开档**逐个相关国家打开科技页确认连线(旧存档会掩盖 available 触发器的时机问题)。
157
- - [ ] `tech_tree_audit.py` 报告 0 问题;大小框混排页跑 `item_sprite_check.py` 无可疑项。
158
- - [ ] 发布信息(name/supported_version/tags/picture/README/依赖 DLC)齐全;联机 checksum 一致。
159
-
160
- ## 7. 深度资料
161
-
162
- 本机知识库(若存在,优先读具体主题文档):
163
-
164
- ```
165
- C:\Users\17876\Desktop\DeepseekHarness\钢铁雄心4\
166
- ├─ PLAYBOOK.md # 14 个任务配方(最常用)
167
- ├─ knowledge/00_environment.md # 两个根目录、加载顺序、覆盖语义、日志、性能
168
- ├─ knowledge/01_script/ # scope / effect/trigger / 变量 / 动态变量 / on_actions
169
- ├─ knowledge/02_content/ # 国策/事件/决议/理念/角色/科技/MIO/特殊项目…
170
- ├─ knowledge/03_military/、04_world_map/、05_presentation/、06_workflow/
171
- ├─ reference/ # 自动生成的 effects/triggers/modifiers/console 数据
172
- └─ example_mods/ # 两个可运行示例(hello_hoi4 / advanced_systems)
173
- ```
174
-
175
- 不在本机时:用 `references/cheatsheet.md` + 游戏自带 `documentation/*.md`(官方字段参考,但注意它**不是全集**:`unit_modifiers`、`is_fighting_in_strategic_region`、`is_deployed` 等 1.19 可用写法未收录,冲突时以游戏文件为准)。
176
-
177
- ## 8. 跨平台与共享
178
-
179
- 本技能是标准 Agent Skills 目录(`SKILL.md` + 可选 `scripts/`、`references/`),复制即可迁移:
180
-
181
- | 平台 | 安装位置 |
182
- |---|---|
183
- | DeepSeek Harness | `~/.agents/skills/hoi4-modding/` |
184
- | Claude Code | `~/.claude/skills/hoi4-modding/` 或项目内 `.claude/skills/hoi4-modding/` |
185
- | 其他兼容客户端 | 其 Skills 设置/目录;zip 根目录必须是 `hoi4-modding/` |
186
-
187
- - 游戏/玩家目录会**自动探测**;探测失败时设 `HOI4_GAME` / `HOI4_USER_DIR`(Linux Proton 必须设 `HOI4_USER_DIR`)。
188
- - 依赖:Python 3.10+(标准库;DDS 需 Pillow)+ 本机 HOI4 1.19.3。
189
- - 共享边界:不含游戏本体资源,只有原创笔记/脚本;不依赖本机知识库也能运行(`references/cheatsheet.md` 自足)。
190
- - 详细安装/自检/更新说明见同目录 `INSTALL.md`。
1
+ ---
2
+ name: hoi4-modding
3
+ description: 《钢铁雄心4》(Hearts of Iron IV, HOI4) 1.19.3 Mod 开发全流程技能:读游戏文件、新建 Mod、写国策/事件/决议/理念/角色/科技/州/MIO/特殊项目/scripted GUI、本地化与 DDS 图标、静态校验、安装启用、按 error.log 排错、发布创意工坊。Use whenever the user asks to create, edit, fix, validate, install, publish, or debug an HOI4 mod or asks about HOI4 scripting (scopes, effects, triggers, variables, focus trees, events, decisions, ideas, characters, MIO, special projects, GUI, localisation, DDS, tank designer/module slots/2D icons/3D models), even if they only say "做个国策树"/"加个事件"/"mod 报错了".
4
+ whenToUse: 用户要做/改/修/校验/安装/发布 HOI4 Mod,或问 HOI4 脚本写法(scope/effect/trigger/变量/国策/事件/决议/理念/角色/MIO/特殊项目/GUI/本地化/DDS)时。
5
+ ---
6
+
7
+ # HOI4 1.19.3 Mod 制作全流程
8
+
9
+ 面向 **1.19.3.0 "Operation Postern"**(`E:\Steam\steamapps\common\Hearts of Iron IV`)实测整理。
10
+ 目标不是讲概念,而是**一次把可运行的 Mod 做出来**:放对文件 → 写对语法 → 本地化齐全 → 校验通过 → 装进游戏 → error.log 干净。
11
+
12
+ > 本机还保留了一套 57 篇的深度知识库(见文末「深度资料」):需要查字段细节时读它;本 SKILL 与 `references/` 是压缩版,足够完成 90% 任务。
13
+
14
+ ## 0. 开始前先确认 3 件事
15
+
16
+ 1. **游戏路径**:`E:\Steam\steamapps\common\Hearts of Iron IV`(`HOI4_GAME` 环境变量可覆盖)。
17
+ 2. **版本**:`launcher-settings.json` 里 `rawVersion` 应为 `1.19.3.0`;不是就按对应版本调整语法(尤其学说/特殊项目)。
18
+ 3. **目标国家有没有专属国策树**:**1.19 每个国家同一时间只有一棵激活国策树**(`country = { }` 是打分,取最高分)。
19
+ - 没有专属树(用 `generic_focus`,如 LUX、IRE、BHU):可以新建一整棵树,`add = 10` 就接管。
20
+ - 已有专属树(SWE、GER、SOV…):不能"再加一棵";只能覆盖原树文件、或 `load_focus_tree` 换树(会顶掉原树)。先向用户确认接受哪种。
21
+
22
+ ## 1. 铁律(违反任何一条都会踩坑)
23
+
24
+ 1. **永不改游戏安装目录**;所有内容写在 Mod 目录,装到 `Documents/Paradox Interactive/Hearts of Iron IV/mod/`。
25
+ 2. **同名文件 = 整体替换**(不是合并)。优先**新增文件**,不要复制整份原版文件。
26
+ 3. **同 ID = 后者覆盖前者**;ID 用你的 `NS_` 前缀,事件用独立 `add_namespace`。
27
+ 4. **本地化 `.yml` 必须 UTF-8 with BOM**;目录名与首行根键一致(`english` → `l_english:`,`simp_chinese` → `l_simp_chinese:`)。
28
+ 5. **2D sprite 定义放 `interface/*.gfx`**,DDS 文件放 `gfx/interface/...`;`gfx/` 下的 `.gfx` 是 3D 用的。
29
+ 6. **图标尺寸**:国策 100×88(+ `_shine`)、理念 60×68、决议 32×33、决议类别 40×51、肖像 156×210、旗帜 82×52 TGA。
30
+ 7. **DDS 用未压缩 raw32 最稳**(原版 UI 同构:`dwFlags=0x81007`、无 mipmap);DXT 要求宽高为 4 的倍数。
31
+ 8. **`.mod` 的 `path` 用纯 ASCII 正斜杠**;中文路径可能加载失败 → 用 `install_mod.py` 复制到玩家目录。
32
+ 9. **`.mod` 字段是 `picture=`**,不是 `thumbnail=`;`supported_version` 写 `"1.19.*"` 或 `"1.19.3.0"`,写 `*`/`1.*` 会报错。
33
+ 10. **不要依赖 DLC**:需要 DLC 内容时用 `has_dlc = "..."` 分支并标注;特殊项目依赖 `Gotterdammerung`。
34
+ 11. **错误看 `logs/error.log`**(`[时间][游戏日期][文件:行]: 消息`),只 grep 自己的文件名/ID;原版噪声占 95%+。
35
+ 12. **脚本改动必须重启游戏**,没有完整热重载;静态校验不能替代进游戏。
36
+ 13. **科技页(`technology_folders`)的 `available` 只用 `original_tag`,不要用 `has_country_flag`**:
37
+ 引擎建页画线时会对该触发器做二次运行时求值,旗帜判定失败时**整页连线被静默丢弃**(方框还在、日志干净、旧存档可能正常而新开档必现)。见 `references/tech-tree-ui.md` §3。
38
+ 14. **大框/小框混排是三件套**:科技加 `force_use_small_tech_layout = yes` + 页面有 `techtree_<folder>_small_item` 模板 +
39
+ `GFX_technology_<folder>_small_*_item_bg` 精灵**指向真正的小图**。模板 size 只管排版,背景贴图按自身像素绘制——精灵还指着 203×84 大图时,画面就是"小框模板 + 大框外观 + 整体偏位"。
40
+ 15. **坦克设计器是全局 GUI**:改 `interface/tank_designer_view.gui` 会影响所有国家/底盘;窗口背景 `GFX_tank_designer_popup_bg` 是**固定 1092×553 贴图**,只加高窗口而不换背景 → 内容溢出到窗口外/地图上(见 `references/tank-designer.md` §4.3)。
41
+ 16. **槽位按钮位置 ≠ 槽位数据**:`pos_custom_module_slot_window_N` 决定按钮在界面上的位置,底盘 `module_slots` 的**书写顺序**决定第 N 个位置是哪一类槽;模块类别由模块的 `category =` 隐式创建(`references/tank-designer.md`)。
42
+
43
+ ## 2. 标准工作流
44
+
45
+ ```
46
+ 0) 侦察 读游戏文件确认目标系统/字段/原版参考(grep 原版用例)
47
+ 1) 骨架 scripts/new_mod.py 生成 descriptor.mod + .mod + 本地化 + 示例内容
48
+ 2) 内容 按 references/cheatsheet.md 的配方逐类添加(国策/事件/决议/理念/角色/科技/州/GUI…)
49
+ 3) 本地化 每个 ID 同时补 english + simp_chinese(BOM),key 规则见 cheatsheet §2
50
+ 4) 校验 python scripts/hoi4_lint.py <Mod目录>
51
+ 5) 安装 python scripts/install_mod.py <Mod目录> --yes --enable
52
+ 6) 实测 启动游戏(-debug_mode)→ 新开档 → 控制台触发 → 看 error.log
53
+ 7) 发布 descriptor.mod 的 name/supported_version/tags/picture 齐全;干净 playset 复测
54
+ ```
55
+
56
+ 每次只加一类内容、加完就校验;不要一次写 2000 行再排错。
57
+
58
+ ## 3. 配方索引(代码在 `references/cheatsheet.md`)
59
+
60
+ | 任务 | 章节 |
61
+ |---|---|
62
+ | 新建 Mod 骨架 / `.mod` 与 `descriptor.mod` | cheatsheet §1 |
63
+ | 本地化规则、key 命名、颜色/变量/图标 | §2 |
64
+ | 国家精神(idea) | §3 |
65
+ | 国策树(含一国一树规则、互斥/前置/奖励) | §4 |
66
+ | 事件(MTTH / is_triggered_only / 选项 / 事件链) | §5 |
67
+ | 决议(category / decision / targeted / 任务型) | §6 |
68
+ | 角色(领袖/顾问/将领/科学家) | §7 |
69
+ | 科技(folder / dependencies / on_research_complete) | §8 |
70
+ | **科技树 UI:页面可用性 / 连线 / 大小框 / 拆页合并 / 调试手法** | `references/tech-tree-ui.md` |
71
+ | 州、资源、建筑 | §9 |
72
+ | 动态变量 + 动态修正 | §10 |
73
+ | scripted GUI 面板(4 文件挂载) | §11 |
74
+ | MIO / 特殊项目 | §12 |
75
+ | 贴图、DDS、GFX 注册 | §13 |
76
+ | **坦克设计器:16 槽布局 / 加高窗口 / 隐藏升级区 / 模块类别** | `references/tank-designer.md` |
77
+ | **坦克 3D 模型:复用原版实体 / 换贴图 / 自制 mesh** | `references/tank-models-3d.md` |
78
+ | **科技/装备图标:照片→173×77 DDS、去背、安全区** | `references/icon-dds-pipeline.md` |
79
+ | 调试命令与 error.log 对照表 | §14 |
80
+ | 1.19 与旧教程差异清单 | §15 |
81
+
82
+ ## 4. 工具(`scripts/`,仅标准库;DDS 工具需 Pillow)
83
+
84
+ `$S` = **本技能资源目录**下的 `scripts`(加载技能时返回的 Base directory;本地安装通常是
85
+ `~/.agents/skills/hoi4-modding/scripts`,从插件市场安装时在插件包的 `skills/hoi4-modding/scripts`)。
86
+ Windows PowerShell 示例(`python` 不可用时换成本机 Python 绝对路径):
87
+
88
+ ```powershell
89
+ $S = "$env:USERPROFILE\.agents\skills\hoi4-modding\scripts" # 市场安装:换成技能返回的 Base directory\scripts
90
+ $GAME = "E:\Steam\steamapps\common\Hearts of Iron IV"
91
+
92
+ # 新建 Mod 骨架(--focus 可选;--tag 默认 LUX,因为 LUX 没有专属国策树)
93
+ & python "$S\new_mod.py" "D:\mods\MyMod" --name "My Mod" --prefix MY --tag LUX --focus
94
+
95
+ # 静态校验(语法/编码/本地化/GFX/ID冲突/.mod 结构;首次约 20s 建原版索引)
96
+ & python "$S\hoi4_lint.py" "D:\mods\MyMod" --game $GAME
97
+
98
+ # 只查语法、不建原版索引(快)
99
+ & python "$S\hoi4_lint.py" "D:\mods\MyMod" --no-vanilla
100
+
101
+ # 从官方 documentation/*.md 生成 effects/triggers/modifiers/console 参考
102
+ & python "$S\build_reference.py" --game $GAME --out .\reference
103
+
104
+ # 安装到玩家 mod 目录并启用(复制安装;不要 --link,路径含中文时会被警告)
105
+ & python "$S\install_mod.py" "D:\mods\MyMod" --yes --enable
106
+
107
+ # 卸载
108
+ & python "$S\install_mod.py" "D:\mods\MyMod" --uninstall --yes
109
+
110
+ # DDS 图标:生成/检查(Pillow)
111
+ & python "$S\dds_helper.py" make icon.png out.dds --width 60 --height 68
112
+ & python "$S\dds_helper.py" check out.dds
113
+
114
+ # 坦克设计器体检(窗口/槽位位置/槽位模板/模块类别/底盘槽数/背景尺寸)
115
+ & python "$S ank_designer_probe.py" --game $GAME
116
+
117
+ # 生成坦克设计器槽位布局(默认 16 槽紧凑版,写 mod/interface/tank_designer_view.gui;不修改游戏目录)
118
+ & python "$S ank_designer_layout.py" --mod "D:\mods\MyMod" --dry-run
119
+ & python "$S ank_designer_layout.py" --mod "D:\mods\MyMod"
120
+
121
+ # 科技卡图标:照片/矢量图 → 173×77 DDS(去背 + 安全区 + 183×84 卡片预览)
122
+ & python "$S ech_icon_import.py" "虎式E型.png" out/GER_tiger_e.dds --card-preview preview.png
123
+
124
+ # 科技页完整性审计(注册表 <-> 页面/页签/item 模板/网格/科技/本地化)
125
+ & python "$S/tech_tree_audit.py" "D:/mods/MyMod"
126
+
127
+ # 科技页可用性:has_country_flag -> original_tag(--check 先看,--apply 写入并备份,--revert 回滚)
128
+ & python "$S/tech_folder_available.py" "D:/mods/MyMod" --check
129
+ & python "$S/tech_folder_available.py" "D:/mods/MyMod" --apply
130
+
131
+ # item 模板尺寸 vs 背景精灵像素(专治"小框显示成大框")
132
+ & python "$S/item_sprite_check.py" "D:/mods/MyMod" --folder my_folder
133
+
134
+ # error.log 分诊(科技树 / 贴图 / scope / 未知字段 / 本地化)
135
+ & python "$S/errorlog_triage.py"
136
+ ```
137
+
138
+ > Git Bash 中把 `$S\x.py` 写成 `"$S/x.py"`、`$GAME` 写成 `/e/Steam/...` 即可。
139
+ > 本机 DSH 自带 Python:`C:\Users\17876\.dsh\dsh-runtimes\dsh-primary-runtime\dependencies\python\python.exe`(含 Pillow)。
140
+
141
+ `new_mod.py` 会生成:`descriptor.mod`、同级 `.mod`(path 指向目标目录)、`localisation/{english,simp_chinese}`(BOM)、1 个理念、`events/` 1 个可触发事件、可选国策树;并自动跑一次 lint。
142
+
143
+ ## 5. 排错:从 error.log 反推
144
+
145
+ 先确认「只启用原版 + 你的 Mod」,再 grep 自己的文件/ID:
146
+
147
+ | error.log 关键字 | 常见原因 | 修法 |
148
+ |---|---|---|
149
+ | `Invalid Scope, supported: Country, provided: None` | effect/trigger 用错 scope | 查效果文档的 `Supported Scopes`;用 `every_country`/`GER = { }` 切 scope |
150
+ | `Unknown effect-type: xxx` | 关键字拼错/版本没有/不在该 scope | `grep xxx reference/effects.json`;对照 1.19 官方文档 |
151
+ | `Unknown trigger-type` / `Not a valid value` | trigger 名或参数值错误 | 查 `reference/triggers.json`;值看文档枚举 |
152
+ | `Unknown modifier: xxx` | 修正名拼错(静态修正/动态修正都会) | `grep xxx reference/modifiers.json` |
153
+ | `Unexpected token` | 括号/引号不平衡;`.mod` 字段拼错(如 `thumbnail`) | 跑 lint;检查 `picture=`/`path=` |
154
+ | `Tried to get dynamic token` / `dynamic token ... OOS` | 本地化/脚本拼接 key 未注册 | 改用普通 loc key 或 `synchronized_dynamic_tokens` |
155
+ | 图标空白/黑块 | GFX 未注册、texturefile 不存在、DDS 头不对 | `dds_helper.py check`;确认 sprite 在 `interface/*.gfx` |
156
+ | 坦克设计器内容溢出窗口/跑到地图上 | 窗口加高但背景贴图固定 1092×553 | 用 `tank_designer_layout.py` 生成紧凑布局,或按 `references/tank-designer.md` §4.3 做加高背景 sprite |
157
+ | 坦克设计器槽位数/位置不对 | 界面位置数 与 底盘 `module_slots` 数量/顺序不一致 | `tank_designer_probe.py` 打印两者后对比 |
158
+ | 设计器槽位互相叠压/挤出容器 | 槽位模板宽 76px > 列距/容器宽 | 列距 ≥76 或加宽 `equipment_modules`(原版 73 列距本身叠 3px) |
159
+ | 中文方框 | GUI 用了没有中文 `bitmapfont_override` 的字体名 | 换有中文覆盖的字体(见知识库 `05_presentation/chinese_fonts.md`) |
160
+ | 国策树不显示 | 原版树分数更高;或树 id/坐标错误 | 按 §4 规则选「无专属树国家」或覆盖原树 |
161
+ | 科技页**方框全在、连线一条没有**、日志干净 | `technology_folders.available` 用了 `has_country_flag`,建页画线阶段判定失败 → 整页 path 静默丢弃 | 改成 `original_tag = <TAG>`(`tech_folder_available.py`),**新开档**验证 |
162
+ | 小框科技显示成大框且整体偏位 | 小框模板生效了,但 `GFX_technology_<folder>_small_*_item_bg` 指向 203×84 大图 | `item_sprite_check.py` 定位后把 textureFile 换成 72×72 小图 |
163
+ | 某页永远不显示 | `available = { always = no NOT = {...} }`(AND 关系恒 false) | 去掉 `always = no`,只留 `NOT = {...}` 或 `original_tag` |
164
+
165
+ 游戏内调试:`-debug_mode` 启动,控制台(`~`/`^`)常用 `event hho.1`、`focus.autocomplete`、`debug_events`、`tag SWE`、`pp 500`;完整命令见 `reference/CHEATSHEET_console.md`(若已生成)。
166
+
167
+ ## 6. 验收清单
168
+
169
+ - [ ] `hoi4_lint.py` 0 error(warning 尽量清零)。
170
+ - [ ] 所有新增 ID 有 en + zh 本地化,`.yml` 带 BOM。
171
+ - [ ] 所有 `GFX_` 引用真实存在;自绘 DDS 尺寸/格式正确。
172
+ - [ ] 没有覆盖原版整文件(除非有意);`.mod` path 为 ASCII。
173
+ - [ ] 干净 playset 进游戏:新开档、触发全部内容、`error.log` 无自己文件的报错。
174
+ - [ ] **新开档**逐个相关国家打开科技页确认连线(旧存档会掩盖 available 触发器的时机问题)。
175
+ - [ ] `tech_tree_audit.py` 报告 0 问题;大小框混排页跑 `item_sprite_check.py` 无可疑项。
176
+ - [ ] 坦克设计器:窗口背景覆盖整个窗口;槽位位置数 = 底盘 `module_slots` 数;槽位不叠压、能选模块并保存设计。
177
+ - [ ] 坦克 3D:`graphic_db` 的 `models` 实体存在,`.asset` 至少 `idle/move/attack` 三个 state,贴图齐全。
178
+ - [ ] 发布信息(name/supported_version/tags/picture/README/依赖 DLC)齐全;联机 checksum 一致。
179
+
180
+ ## 7. 深度资料
181
+
182
+ 本机知识库(若存在,优先读具体主题文档):
183
+
184
+ ```
185
+ C:\Users\17876\Desktop\DeepseekHarness\钢铁雄心4\
186
+ ├─ PLAYBOOK.md # 14 个任务配方(最常用)
187
+ ├─ knowledge/00_environment.md # 两个根目录、加载顺序、覆盖语义、日志、性能
188
+ ├─ knowledge/01_script/ # scope / effect/trigger / 变量 / 动态变量 / on_actions
189
+ ├─ knowledge/02_content/ # 国策/事件/决议/理念/角色/科技/MIO/特殊项目…
190
+ ├─ knowledge/03_military/、04_world_map/、05_presentation/、06_workflow/
191
+ ├─ reference/ # 自动生成的 effects/triggers/modifiers/console 数据
192
+ └─ example_mods/ # 两个可运行示例(hello_hoi4 / advanced_systems)
193
+ ```
194
+
195
+ 不在本机时:用 `references/cheatsheet.md` + 游戏自带 `documentation/*.md`(官方字段参考,但注意它**不是全集**:`unit_modifiers`、`is_fighting_in_strategic_region`、`is_deployed` 等 1.19 可用写法未收录,冲突时以游戏文件为准)。
196
+
197
+ ## 8. 跨平台与共享
198
+
199
+ 本技能是标准 Agent Skills 目录(`SKILL.md` + 可选 `scripts/`、`references/`),复制即可迁移:
200
+
201
+ | 平台 | 安装位置 |
202
+ |---|---|
203
+ | DeepSeek Harness | `~/.agents/skills/hoi4-modding/` |
204
+ | Claude Code | `~/.claude/skills/hoi4-modding/` 或项目内 `.claude/skills/hoi4-modding/` |
205
+ | 其他兼容客户端 | 其 Skills 设置/目录;zip 根目录必须是 `hoi4-modding/` |
206
+
207
+ - 游戏/玩家目录会**自动探测**;探测失败时设 `HOI4_GAME` / `HOI4_USER_DIR`(Linux Proton 必须设 `HOI4_USER_DIR`)。
208
+ - 依赖:Python 3.10+(标准库;DDS 需 Pillow)+ 本机 HOI4 1.19.3。
209
+ - 共享边界:不含游戏本体资源,只有原创笔记/脚本;不依赖本机知识库也能运行(`references/cheatsheet.md` 自足)。
210
+ - 详细安装/自检/更新说明见同目录 `INSTALL.md`。
@@ -555,3 +555,60 @@ spriteTypes = {
555
555
  - **理念**:支持 `on_add`/`on_remove`(旧教程说没有是错的)。
556
556
  - **文档滞后**:官方 `documentation/*.md` 不是全集(`unit_modifiers`、`is_fighting_in_strategic_region`、`is_deployed` 等未收录),冲突以游戏文件为准。
557
557
  - **路径**:`.mod` 的 `path` 建议纯 ASCII;`-debug_mode` 不是 `-debug`。
558
+
559
+
560
+ ## 16. 坦克设计器 / 3D 模型 / 图标(速查)
561
+
562
+ ### 16.1 坦克设计器文件
563
+
564
+ | 文件 | 作用 |
565
+ |---|---|
566
+ | `interface/tank_designer_view.gui` | 窗口、`equipment_modules`(槽位容器)、`pos_custom_module_slot_window_N`(每个槽的坐标) |
567
+ | `interface/equipmentdesignerview.gui` | 通用控件;`equipment_designer_module_slot_entry` 槽位按钮模板 = **76×47** |
568
+ | `interface/equipmentdesigner/tanks/*.gui` | 每类底盘蓝图(`equipment_designer_<底盘>` / archetype 回退) |
569
+ | `common/units/equipment/tank_chassis.txt` | archetype 的 `module_slots`;普通底盘 `module_slots = inherit` |
570
+ | `common/units/equipment/modules/*.txt` | 模块;`category =` 隐式建类别 |
571
+ | `gfx/interface/equipmentdesigner/graphic_db/*.txt` | `graphic_db = { GFX_2d_icon models = { ENTITY } }` |
572
+
573
+ 原版 9 槽顺序(= 数据 `module_slots` 顺序):炮塔/主武器/悬挂/装甲/引擎/特殊1–4;
574
+ 界面位置 `pos_0..8` 由原版 GUI 决定,改槽数 = 加 `pos_custom_module_slot_window_N` + 底盘多写槽。
575
+
576
+ ### 16.2 16 槽紧凑布局(不加高窗口)
577
+
578
+ ```pdx
579
+ @fixed_btn_mod_col_0 = 0
580
+ ...
581
+ @fixed_btn_mod_col_6 = 432
582
+ @fixed_btn_mod_row_0 = 0 # 上排 7
583
+ @fixed_btn_mod_row_1 = 50 # 第二排 2(通信左 / 工程右)
584
+ @fixed_btn_mod_row_2 = 300 # 下排 7
585
+ ```
586
+
587
+ - 窗口高 542 不用加高;蓝图保持 `position {x=3 y=50} size 508×248`;
588
+ - 隐藏 `equipment_upgrade_0/1`、auto 按钮:把 position 改成 `-4000/-4000`;
589
+ - 槽位宽 76、列距 72(原版就是 73)→ 相邻叠 4px,视觉连成一排;要严格不叠压需加宽容器。
590
+
591
+ ### 16.3 3D 模型四层
592
+
593
+ ```
594
+ graphic_db models = { ENTITY }
595
+ → gfx/entities/*.asset entity = { name pdxmesh = ... state = {idle/move/attack} }
596
+ → gfx/entities/*.gfx pdxmesh = { name file = "gfx/models/units/tanks/x.mesh" }
597
+ → gfx/models/units/tanks/*.mesh + *.anim + *_diffuse/_normal/_specular.dds
598
+ ```
599
+
600
+ 复用原版:`GER_iw_armor_entity` / `GER_light_armor_entity` / `GER_medium_armor_entity` /
601
+ `GER_heavy_armor_entity` / `GER_super_heavy_armor_entity`。
602
+
603
+ ### 16.4 科技卡图标 173×77
604
+
605
+ ```
606
+ Icon 控件中心 x=74(卡宽 183)→ 内容右移 8px:左留 20 / 右留 4 / 上下 2,最大内容 149×73
607
+ ```
608
+
609
+ - 透明 PNG 最好;白底/棋盘格需要去背;**白色涂装保护**:区域亮度≥235 且 relY<0.8 → 保留;
610
+ - 输出 raw32 DDS 173×77,sprite 名 `GFX_<tech>_medium`;
611
+ - 批量导入必须有别名表(文件名≠科技 id 时)。
612
+
613
+ 对应脚本:`tank_designer_probe.py` / `tank_designer_layout.py` / `tech_icon_import.py`,
614
+ 专题文档 `references/tank-designer.md`、`references/tank-models-3d.md`、`references/icon-dds-pipeline.md`。
@@ -0,0 +1,123 @@
1
+ # 科技/装备 2D 图标流水线:照片 → 173×77 DDS(实战)
2
+
3
+ > 适用:把坦克照片/矢量图做成 HOI4 科技卡图标、装备 2D 图标;处理白底/棋盘格/阴影、保护白色涂装、
4
+ > 解决“图标出框 / 偏左 / 白边 / 涂装被挖空”。
5
+ > 本文是 `hist_tech_trees`(30 辆德国坦克科技)全套照片图标的量产经验。
6
+
7
+ ## 0. 关键结论(先看这 4 条)
8
+
9
+ 1. **科技卡图标画布 173×77**;卡片背景 183×84,卡内 `Icon` 控件是 `position {x=74 y=50}` + `centerposition`,
10
+ 所以 **173 宽的图在 183 卡里左右各出 5px**:内容必须留安全边距,否则炮管/履带会被卡片边框裁掉。
11
+ 2. 原版照片/渲染图多数是**白底或 8px 棋盘格(纯白+灰 130/192)**,必须去背景;透明 PNG 最省事,优先找。
12
+ 3. **白色涂装/白色编号会被“去白底”算法一起挖掉**:保护规则 = 区域平均亮度 ≥235 **且** 相对位置偏上(relY<0.8)→ 保留。
13
+ 4. 批量导入必须有 **别名表**:文件名 ≠ 科技中文名(如 `四号坦克F型.png` → `GER_pz4_f1`、`38(t)A型`、`35(t)`)。
14
+
15
+ ## 1. 卡片几何:为什么图标要“右移”
16
+
17
+ ```pdx
18
+ # countrytechtreeview.gui 的 item 模板(原版)
19
+ containerWindowType = { name = "techtree_GER_armor_item" size = { width = 183 height = 84 }
20
+ iconType = { name = "Icon" position = { x = 74 y = 50 } centerposition = yes }
21
+ instantTextBoxType = { name = "Name" position = { x = 6 y = -1 } }
22
+ background = { spriteType = "GFX_technology_unavailable_item_bg" } # 286×109
23
+ }
24
+ ```
25
+
26
+ - 卡片可见内容区约 **183×84**;`Icon` 的中心在卡片 x=74,而卡片中心是 91.5 → 图标整体天然偏左 17.5px。
27
+ - 因此 **173×77 的图标内容**建议:
28
+ - 水平:左边距 **20px**、右边距 **4px**(内容整体右移 8px,把炮管/车身放在视觉中心);
29
+ - 垂直:上下各留 **2px**,最大内容 **149×73**。
30
+ - 具体数值可按立绘方向微调(炮口朝左的图可反过来),但**右侧不能顶满**,否则车头/炮口出框。
31
+
32
+ ## 2. 输入类型与去背景
33
+
34
+ | 输入 | 处理 |
35
+ |---|---|
36
+ | 透明 PNG/WebP(矢量导出) | 直接用 alpha,最省事;裁 bbox → 缩放 → 贴到安全区 |
37
+ | 纯白底 | 从边界 flood fill 去白(容差 ~12),保留内部白色(高光/白涂装) |
38
+ | 8px 棋盘格(白 + 灰 130/192) | 先识别两种背景色,按“边界连通 + 颜色接近任一背景色”泛洪;再做 1px 腐蚀+描边 |
39
+ | 阴影/渐变背景 | 难;优先找透明版,或 PS 手动抠图 |
40
+ | 白底带白色涂装 | 用第 3 条保护规则,否则涂装会被挖空 |
41
+
42
+ 推荐流程:
43
+
44
+ ```
45
+ 1) 转 RGBA
46
+ 2) 估计背景色:取四条边上的高频中性色(R≈G≈B),最多取 2 个峰
47
+ 3) 从边界 flood fill:颜色接近任一背景色 → 透明
48
+ 4) 保护:连通的“白色区域”若 平均亮度≥235 且 中心 relY<0.8 → 保留(白涂装/编号)
49
+ 5) 其他内部洞(履带缝、观察窗):用前景色填充或按最近深色覆盖
50
+ 6) 腐蚀 1px(去掉白边),边缘轻微重着色
51
+ 7) 预乘 alpha 下采样(避免灰边)
52
+ 8) 裁 bbox → 按最大 149×73 等比缩放 → 贴到 173×77 画布的安全位置(左 20/右 4/上下 2)
53
+ 9) 输出 PNG + DDS(dds_helper raw32 173×77)
54
+ 10) 合成 183×84 卡片预览,检查不越框
55
+ ```
56
+
57
+ ## 3. 别名与匹配
58
+
59
+ 批量导入时用**文件名模糊匹配** + 显式别名表:
60
+
61
+ ```python
62
+ ALIASES = {
63
+ "四号坦克F型": "GER_pz4_f1", # 早期 F1(短管)与后期 F2 区分
64
+ "38(t)A型": "GER_pz38t_ad",
65
+ "35(t)": "GER_pz35t",
66
+ }
67
+ ```
68
+
69
+ 匹配顺序:`big_zh/big_en` 精确 → 小名(small_zh)精确 → 小名首词 → 唯一子串包含 → 别名表。
70
+ **不要用“任意包含”直接命中**:`四号坦克F型` 会同时匹配 F1/F2/G/H,必须最先用别名表消歧。
71
+
72
+ ## 4. 输出与注册
73
+
74
+ ```bash
75
+ python "$S/dds_helper.py" make GER_pz4_f1.png \
76
+ gfx/interface/technologies/GER_armor/GER_pz4_f1.dds --width 173 --height 77
77
+ python "$S/dds_helper.py" check gfx/interface/technologies/GER_armor/GER_pz4_f1.dds
78
+ ```
79
+
80
+ ```pdx
81
+ # interface/NS_tech_icons.gfx
82
+ spriteTypes = {
83
+ spriteType = { name = "GFX_GER_pz4_f1_medium" texturefile = "gfx/interface/technologies/GER_armor/GER_pz4_f1.dds" }
84
+ }
85
+ ```
86
+
87
+ - 科技卡模板里图标 sprite 名按原版约定:`GFX_<tech>_medium`(`<tech>_small` 用于小框);
88
+ - **每张图 173×77,raw32 未压缩**(原版 UI 同构;体积约 53KB/张,30 张 1.6MB,可接受);
89
+ - 共享占位图标时只注册一张 sprite,多个科技共用。
90
+
91
+ ## 5. 卡片预览自检(不越框)
92
+
93
+ ```python
94
+ CARD = Image.open(GAME / "gfx/interface/techtree/technology_available_item_bg.dds").convert("RGBA")
95
+ card = CARD.resize((183, 84), Image.LANCZOS)
96
+ icon = Image.open("GER_pz4_f1.png").convert("RGBA")
97
+ card.alpha_composite(icon, (74 - icon.width // 2, 50 - icon.height // 2))
98
+ card.save("preview_card.png")
99
+ ```
100
+
101
+ 检查点:炮管/车头不出框;左右留白均衡(视觉重心略右);与同排其他卡片的车体大小一致(缩放按“车长”统一,
102
+ 不要按图片 bbox 高度统一,否则炮塔高低不一)。
103
+
104
+ ## 6. 踩坑表
105
+
106
+ | 症状 | 原因 / 修法 |
107
+ |---|---|
108
+ | 图标左侧被裁 | 内容顶满 173 宽;加大 left margin(本项目用 20px) |
109
+ | 图标整体偏左 | 没考虑 Icon 控件中心 x=74;内容整体右移 8px |
110
+ | 白边/灰边 | 未腐蚀边缘;缩放前未预乘 alpha |
111
+ | 白色涂装/编号被挖空 | 缺少白涂装保护规则(亮度≥235 + relY<0.8) |
112
+ | 棋盘格残留 | 只按单色去背;需检测两种背景色并联合泛洪 |
113
+ | 各卡大小不一 | 缩放基准不一致(按车长/统一系数,而不是 bbox 高) |
114
+ | 导入后图标不显示 | sprite 没注册 / 路径大小写 / DDS 尺寸不对(必须 173×77 或模板要求尺寸) |
115
+ | 装备图标显示错位 | 装备 2D 图标尺寸不同(原版 81×37 等),不要拿科技卡 173×77 混用 |
116
+
117
+ ## 7. 配套脚本
118
+
119
+ `scripts/tech_icon_import.py`(需 Pillow):
120
+ - 单张/批量(目录或 JSON 映射)输入 → 去背(transparent / white / checker / auto)→ 安全区 173×77 →
121
+ PNG + DDS(调用 `dds_helper.py`);
122
+ - `--card-preview` 输出 183×84 合成卡,直接目检是否出框;
123
+ - `--alias alias.json` 传文件名→科技 id 映射,批量时用于消歧。