界面本地化
约 769 字大约 3 分钟
客户端展示的 M9A 项目文本——任务名称、选项标签、说明、预设、资源与控制器名称——来自 interface.json 和 tasks/ 下的文件。这些字符串通过 MaaFramework Project Interface V2 的国际化机制进行本地化。
工作方式
interface.json 中声明可用的翻译文件:
"languages": {
"zh_cn": "i18n/zh_cn.json",
"en_us": "i18n/en_us.json"
}路径相对于 interface.json 所在目录。M9A 将这些 Project Interface 资产放在项目根目录的 i18n/ 中,而不是 resource/;后者只存放 MaaFW 运行资源。每个翻译文件都是「键 → 译文」的扁平映射:
{
"Task.Wilderness": "收取荒原",
"Option.Wilderness.Wellspring": "好梦井"
}任何支持国际化的字段,只要其值以 $ 开头,就会被当作翻译文件中的键。客户端按当前语言解析该键。缺少译文时的回退行为取决于客户端,可能显示键本身或回退到稳定名称,因此所有引用都必须通过 pnpm check:i18n 保证完整。
{
"name": "收取荒原",
"label": "$Task.Wilderness",
"entry": "Wilderness"
}name 是 ID,不是显示名
name 是稳定标识符。它会被写入用户配置文件,并被预设的任务列表以及各任务的 option 数组引用,因此重命名会破坏用户已有的配置。它保持中文原样不变,显示文本改由 label 提供。
option 映射的键和 cases[].name 同理:在旁边新增 label,绝不要改写键本身。
如果某个 case 的 name 在各语言下写法一致(Yes、No、24h、MAX、纯数字等),则无需 label,客户端会回退显示 name;但其 description 仍可能需要一个键。
支持填键的字段
label、description、desc、pattern_msg、icon、doc,以及项目级的 title、contact、license、welcome。注意 pipeline_override 属于面向游戏的 pipeline 数据,不参与翻译。
键命名规范
键使用 ASCII、以点分隔,结构与字符串出现的位置一致:
| 类型 | 格式 | 示例 |
|---|---|---|
| 任务 | Task.<Name> | Task.BalancedFarming |
| 任务说明 | Task.<Name>.desc | Task.BalancedFarming.desc |
| 选项 | Option.<Task>.<Option> | Option.Combat.StageType |
| 选项 case | Option.<Task>.<Option>.<Case> | Option.Combat.StageType.MainStory |
| 选项输入框 | Option.<Task>.<Option>.<Input> | Option.Combat.StageCustom.Chapter |
| 预设 | Preset.<Name> | Preset.DailyIdle |
| 接口层级 | Controller.*、Resource.*、Group.* | Resource.GlobalEn |
说明追加 .desc,pattern_msg 追加 .msg。被多个选项共用的字符串(例如编队序号)使用 Common.* 键,只需翻译一次。
新增任务的流程
- 照常在
tasks/下编写任务,name保持中文。 - 添加
"label": "$Task.<Name>";若有说明,再添加"description": "$Task.<Name>.desc"。 - 在
i18n/zh_cn.json和i18n/en_us.json两个文件中补上对应条目。 - 运行
pnpm check:i18n。
校验
pnpm check:i18n 已并入 pnpm check,出现以下情况会导致校验失败:
- 某个
$key引用在语言文件中缺少对应条目 - 语言文件中存在已无人引用的条目
- 两个语言文件的键集合不一致
- 任意支持国际化的字段仍然写死了中文
新增语言
在 interface.json 的 languages 中添加文件,复制 i18n/zh_cn.json 作为起点并翻译其值即可。校验要求新文件的键集合与现有文件完全一致。
