LucasSKrewer/kenshi-modkit
GitHub: LucasSKrewer/kenshi-modkit
一个纯 Python 的 Kenshi 模组脚本化读写工具链,支持无 FCS 环境下的批量编辑、版本控制友好导出以及模组间字段级冲突检测。
Stars: 0 | Forks: 0
# kenshi-modkit
通过 Python 脚本读取、编辑和**写入** Kenshi 模组 (`.mod` / `.base`),无需
打开 Forgotten Construction Set。基于 Python 3.12,除了标准库外**零依赖**。
存在的意义:FCS 是一个 GUI 工具。在二进制格式被映射解析后,模组就成了
代码——支持可读的 diff、批量编辑、生成变体,以及任何现有工具都无法做到的,**检测已安装模组之间的冲突**。
格式记录在 [FORMATO.md](FORMATO.md) 中,包括
社区公开规范未涵盖的 `filetype 17`。
## 状态
| | |
|---|---|
| 读取 / 写入 filetype 16 和 17 | ✅ **24/24 个文件**实现字节级一致的 round-trip |
| 编辑字段、引用、标头字符串 | ✅ |
| 通过克隆创建记录 | ✅ 已在游戏内验证 |
| Kenshi 加载通过脚本生成的模组 | ✅ 已在游戏内验证 (2026-07-27) |
| Typecode 映射 | ✅ 部分——确定的有 45 个,共 78 个 ([TYPECODES.md](TYPECODES.md)) |
| 冲突检测器 | ✅ |
| 从零开始创建记录 | ❌ 依赖于缺失的 typecode |
| Filetype 15 (存档) | ❌ 未实现 |
字节级一致的 round-trip 是该项目的事实标准:读取一个文件并
重新写入必须产生完全相同的字节。否则,通过脚本写入模组就是一种盲猜。它在 24 个文件上通过了测试,包括 `gamedata.base`、`Dialogue.mod`
(39,077 条记录) 以及 **Genesis.mod**——19.7 MB,**26,495 条记录**。
游戏内测试 (`teste_ingame.py`) 生成了一个包含**已编辑** (1000 → 7777 猫币) game start 和另一个**通过克隆创建** game start 的模组,并且两者都出现在了新游戏界面上。
## 工具
| | |
|---|---|
| `kenshimod.py` | 核心库:`ler`、`gravar`、`clonar_registro`、`substituir_em_ids`、`campo`/`set_campo` |
| `caminhos.py` | 自动检测 Kenshi 安装路径 (无需硬编码路径) |
| `roundtrip.py` | 保真度测试——它是我们能够信任该解析器的依据 |
| `dump.py` | `.mod` → 可读文本,`--json` (版本控制友好),`--tipos` |
| `validar.py` | 结合加载顺序解决悬空引用 / strid 重复问题 |
| `conflitos.py` | 检查哪些模组在争抢同一条记录,以及最终哪个值生效 |
| `typecodes.py` | 通过将记录与 `fcs.def` 相关联来建立 typecode 映射 |
| `teste_ingame.py` | 生成一个用于编辑**和**创建记录的模组,以在游戏中进行验证 |
| `pesquisa/` | 逆向工程探测 ([方法](pesquisa/LEIA.md)) |
## 安装
无需安装。克隆代码库并使用 Python 3.12 运行——没有任何依赖项。
Kenshi 文件夹会被**自动检测** (`caminhos.py`):检查顺序依次为环境变量 `KENSHI_DIR`、脚本同目录下的
`kenshi_dir.txt` 文件、Steam 注册表 + `libraryfolders.vdf`,最后
是默认路径。要查看它找到了什么,可以运行:
```
python caminhos.py
```
## 用法
```
python roundtrip.py --tudo
python dump.py "/mods/KenshiCoop/KenshiCoop.mod"
python validar.py "/mods/KenshiCoop/KenshiCoop.mod"
python conflitos.py --todos # e se eu ativasse todos os instalados?
python typecodes.py
python teste_ingame.py --instalar
```
```
import kenshimod as km
import caminhos
mod = km.ler(os.path.join(caminhos.mods_dir(), "Foo", "Foo.mod"))
for rec in mod["records"]:
if km.campo(rec, "long", "money") is not None:
km.set_campo(rec, "long", "money", 5000)
km.gravar(r"out\Foo\Foo.mod", mod)
```
游戏的约定:模组必须放在 `Kenshi\mods\\.mod` 路径下才能
在 launcher 中显示,而当前启用的加载顺序存放在 `data\mods.cfg` 中。
## 冲突检测器输出示例
覆盖本身不一定是问题——两个模组可能会修改同一条记录的
不同字段。真正的冲突是针对同一个字段出现了不同的值,
这就是该工具要区分的内容:
```
28902 registros tocados, 856 por 2+ mods
578 conflitos de campo (mesmo campo, valor diferente)
mods que se sobrepõem (quantidade de registros em comum):
508 Genesis.mod x Slopeless.mod
131 Genesis.mod x shops have more items +.mod
43 AnimationOverhaul.mod x Genesis.mod
```
## 免责声明
这是一个第三方工具,与 Lo-Fi Games 没有任何关联。仅当你明确要求时 (`--instalar`),它才会将模组写入游戏的
文件夹;`data/`、
`gamedata.base` 和 Workshop 模组会被视为只读。尽管如此,在覆盖写入之前,请务必备份重要数据。
## 致谢
- Filetype 15 和 16 规范:来自 Steam 用户
**Weaver** 的指南
[Kenshi gamedata/mod/save file format](https://steamcommunity.com/sharedfiles/filedetails/?id=797652627)。
`filetype 17` 是在本项目中被解析出来的。
- 之前的 Python 相关工作:
[Superfly-Johnson/kenshi-mod-tools](https://github.com/Superfly-Johnson/kenshi-mod-tools) (MIT)。
MIT 许可证——参见 [LICENSE](LICENSE)。
标签:Python, SOC Prime, 二进制解析, 冲突检测, 开发工具, 无后门, 游戏Mod, 逆向工具