Cataclysm-DDA 模组文本怎么提取翻译模板并生成 po 文件?
2026/9/15 17:53:26 网站建设 项目流程

Cataclysm-DDA 模组文本怎么提取翻译模板并生成 po 文件?

【免费下载链接】Cataclysm-DDACataclysm - Dark Days Ahead. A turn-based survival game set in a post-apocalyptic world.项目地址: https://gitcode.com/GitHub_Trending/ca/Cataclysm-DDA

你给 Cataclysm: DDA 写了一个模组(mod),现在希望模组的物品名、描述等文本能被其他语言的玩家看到。任务就两步:从模组的 JSON 文件里提取出一份.pot翻译模板,再用它为目标语言初始化一个.po翻译文件,供译者填写。官方流程记录在 doc/TRANSLATING_MOD.md 中,下面按该文档的示例(一个放在./mods/demo的演示模组)走一遍,并标注了文档与当前脚本实现之间的两处出入,避免你照着命令执行时卡住。

准备:模组 JSON 与依赖

模组目录里的 JSON 决定能提取到什么。以文档中的演示模组为例,MOD_INFOname/descriptionBOOK的名称、描述都是可提取文本:

[ { "type": "MOD_INFO", "id": "demo", "name": "Demo MOD", "description": "This mod adds a book.", "category": "content", "dependencies": [ "cdda" ] }, { "type": "BOOK", "id": "demo_item", "name": { "str": "Guide to Translate a MOD", "str_pl": "copies of Guide to Translate a MOD" }, "description": "A thin book teaching how to translate a mod." } ]

字符串有三种写法(语法说明见 doc/JSON/JSON_INFO.md 和 doc/TRANSLATING.md):

  • 直接写字符串,例如"name": "bar"
  • 需要复数形式时用对象,"name": { "str": "bar", "str_pl": "baz" }"str_pl"可选;
  • 需要给译者提供上下文时加"//~"注释,例如"name": { "//~": "as in 'foobar'", "str": "bar" }
  • 某条文本不参与翻译时,在"//~"里写"NO_I18N",或在对象顶层指定"//I18N": false

运行提取脚本的环境要求(依据 lang/extract_json_strings.py 源码):

  • Python 3.7 或更高(脚本内明确检查,不满足会打印Requires Python 3.7 or higher.并退出);
  • 脚本import polib,即依赖第三方库 polib;
  • 后续生成.po、编译.mo用到 gettext 工具链里的msginitmsgfmt

另外注意:提取器 lang/string_extractor/parse.py 对每个带type的 JSON 对象做类型分派,遇到不认识的type会直接抛异常终止;没有type键的对象被静默忽略。所以提取前确认模组 JSON 合法、类型都是游戏已支持的。

第一步:提取 .pot 翻译模板

文档给出的命令(在 Cataclysm-DDA 根目录执行):

# In Cataclysm DDA root directory mkdir -p ./mods/demo/lang/po python3 ./lang/extract_json_strings.py -i ./mods/demo -o ./mods/demo/lang/po/demo.pot

执行成功后,./mods/demo/lang/po/demo.pot就是翻译模板,包含模组全部待翻译的原文。

已知出入:当前仓库的 lang/extract_json_strings.py 参数表里没有-o,必填参数是-r(reference POT,JSON 提取出的字符串会追加写入该文件),不传-r时脚本打印Have to specify reference file path.后退出。仓库自身的 lang/update_pot.sh 也是用-r lang/po/base.pot调用它。源码还显示-r指向的文件必须先存在(有isfile检查)。若你按文档原样执行-o版本失败,改用下面这种与脚本参数一致的写法:

# 先创建模板文件满足 -r 的“文件必须已存在”前提 touch ./mods/demo/lang/po/demo.pot python3 ./lang/extract_json_strings.py -i ./mods/demo -r ./mods/demo/lang/po/demo.pot

第二步:检查模板内容

打开生成的.pot文件,确认每条文本都成了msgid条目。文档示例(来自 doc/TRANSLATING_MOD.md,实际提取结果条目顺序和注释以你的模组为准):

#. ~ MOD name #: mods/demo/modinfo.json msgid "Demo MOD" msgstr "" #. ~ Description of MOD "Demo MOD" #: mods/demo/modinfo.json msgid "This mod adds a book." msgstr "" #. ~ Item name #: mods/demo/modinfo.json msgid "Guide to Translate a MOD" msgid_plural "copies of Guide to Translate a MOD" msgstr[0] "" msgstr[1] ""

可以核对:#.行是译者注释(对应 JSON 里的"//~"),#:行是字符串来源文件,复数字符串带msgid_plural。你写进 JSON 的文本如果没出现在模板里,多半是命中了上面的忽略规则(NO_I18N//I18N: false或无type的对象)。

第三步:用 msginit 初始化目标语言的 .po 文件

文档以俄语(ru)为例,从模板生成本地翻译文件:

msginit -o mods/demo/lang/po/ru.po -i mods/demo/lang/po/translation.pot -l ru

-l后跟语言代码。生成./mods/demo/lang/po/ru.po后,译者在这个文件里逐条填写msgstr

已知出入:文档第一步生成的模板叫demo.pot,这条msginit命令却引用translation.pot(文档后文的目录树里也写作translation.pot)。执行前把-i改成你实际生成的模板文件名,保证两者一致即可。

.po是纯文本,译者的填写要点(依据 doc/TRANSLATING.md 的 Tips 与文档示例):

  • 复数条目要按目标语言填写全部形式。文档中的俄语示例是 3 个形式(msgstr[0]/msgstr[1]/msgstr[2],对应Plural-Forms: nplurals=3; ...),英语模板只有 2 个;具体几格由目标语言的Plural-Forms决定,不要照抄英语的数量。
  • %s%3$d这类占位符和<name>这类标签保持原样,不翻译。

第四步:编译 .mo 并确定发布形态

翻译完成后,把.po编译成游戏可加载的.mo

mkdir -p mods/demo/lang/mo/ru/LC_MESSAGES/ msgfmt -o mods/demo/lang/mo/ru/LC_MESSAGES/demo.mo mods/demo/lang/po/ru.po

注意输出文件名用模组 id(这里是demo.mo),与MOD_INFO里的"id"一致。

开发期目录结构与发布结构不同(均为文档示例):开发时保留模板和.po供译者使用;发布模组时只打包.mo.pot.po只你自己和译者需要:

demo ├── lang │ └── mo │ └── ru │ └── LC_MESSAGES │ └── demo.mo ├── modinfo.json └── your_mod_content.json

验证方式

文档给出的验证路径是实际进游戏:玩家使用对应语言版本(示例为俄语)运行时,lang/mo/ru/LC_MESSAGES/demo.mo会被自动加载,游戏内显示俄文文本,即翻译生效。另外 doc/TRANSLATING.md 说明运行时的回退行为:运行时找不到对应翻译就返回原文。所以若游戏里某条文本仍显示英语,先回查它是否在模板里、.po里是否填了msgstr.mo是否重新编译过——这三种情况文档均表现为“显示原文”,需自己逐层核对。

边界:模组流程与主游戏翻译脚本不要混用

仓库里还有一组主游戏维护者用的脚本,与模组的翻译流程是两套:

  • lang/update_pot.sh 用xgettext提取src/*.cpp/src/*.h的 C++ 字符串、再用extract_json_strings.py追加data/下的 JSON 字符串,最终产出主游戏的lang/po/cataclysm-dda.pot
  • lang/compile_mo.sh 只遍历lang/po/*.po,编译成lang/mo/<语言>/LC_MESSAGES/cataclysm-dda.mo,可传单语言参数只编译指定语言(例如lang/compile_mo.sh zh_TW)。

它们处理的是主游戏自身文本,不会读取你模组目录里的lang/po/*.po;模组的.po.mo编译按上面的msgfmt命令在模组目录内完成。同理,主游戏文本走 Transifex 项目协作,模组文本走本文的本地.pot/.po流程(文档也允许把.pot上传到在线翻译平台,二选一)。

【免费下载链接】Cataclysm-DDACataclysm - Dark Days Ahead. A turn-based survival game set in a post-apocalyptic world.项目地址: https://gitcode.com/GitHub_Trending/ca/Cataclysm-DDA

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询