国际化

国际化与本地化

国际化(简称 i18n)是一种代码设计方式,使代码无需更改即可适配多种语言。本地化则是将显示文本适配为用户语言的过程。

同一物品翻译键通过 en_us 与 zh_cn 语言文件按客户端语言设置显示不同文本

原创说明图,依据 Forge 1.21.x 官方文档 绘制。

i18n 使用翻译键实现。翻译键是标识一段可显示文本的字符串,不属于某种特定语言。例如 block.minecraft.dirt 是泥土方块名称的翻译键。这样就可以在不关心具体语言的情况下引用显示文本,适配新语言也无需修改代码。

本地化按照游戏的区域设置进行。Minecraft 客户端通过语言设置指定区域设置;独立服务器唯一支持的区域设置是 en_us。可用区域设置列表见 Minecraft Wiki。

语言文件

语言文件的路径为 assets/[namespace]/lang/[locale].json。例如,examplemod 提供的所有美式英语翻译位于 assets/examplemod/lang/en_us.json。文件格式是翻译键到值的 JSON 映射,必须使用 UTF-8 编码。旧版 .lang 文件可用转换工具转换为 JSON。

{
  "item.examplemod.example_item": "Example Item Name",
  "block.examplemod.example_block": "Example Block Name",
  "commands.examplemod.examplecommand.error": "Example Command Errored!"
}

在方块和物品中使用

Block、Item 和其他少数 Minecraft 类内置了用于显示名称的翻译键。这些键通过重写 #getDescriptionId 指定。Item 还有 #getDescriptionId(ItemStack),可以重写以根据 ItemStack NBT 提供不同的翻译键。

默认情况下,#getDescriptionId 返回方块或物品的注册表名称,前面加上 block. 或 item.,并将冒号替换为点。BlockItem 默认重写此方法以使用对应 Block 的翻译键。例如,ID 为 examplemod:example_item 的物品实际上需要语言文件中有以下一行:

{
  "item.examplemod.example_item": "Example Item Name"
}

注意:翻译键的唯一用途是国际化。不要用它实现逻辑,应使用注册表名称。

本地化方法

警告:常见问题是让服务端替客户端进行本地化。服务端只能按自身的区域设置本地化,该设置不一定与已连接客户端的区域设置相同。

为了尊重客户端的语言设置,服务端应使用 TranslatableComponent 或其他保留语言中立翻译键的方法,让客户端按自己的区域设置本地化文本。

net.minecraft.client.resources.language.I18n(仅客户端)

此 I18n 类仅存在于 Minecraft 客户端,供只在客户端运行的代码使用。尝试在服务器上使用它会抛出异常并导致崩溃。

  • get(String, Object...) 使用客户端的区域设置进行本地化和格式化。第一个参数是翻译键,其余参数是 String.format(String, Object...) 的格式化参数。

TranslatableContents

TranslatableContents 是延迟本地化和格式化的 ComponentContents。它在向玩家发送消息时很有用,因为消息会自动按玩家自己的区域设置本地化。

TranslatableContents(String, Object...) 构造函数的第一个参数是翻译键,其余参数用于格式化。只支持 %s、%1$s、%2$s、%3$s 等格式说明符。格式化参数可以是 Component,它们会被插入结果文本并保留所有属性。

可以向 Component#translatable 传入 TranslatableContents 的参数来创建 MutableComponent,也可以向 MutableComponent#create 传入 ComponentContents 本身来创建。

TextComponentHelper

  • createComponentTranslation(CommandSource, String, Object...) 根据接收方创建本地化并格式化的 MutableComponent。如果接收方是原版客户端,则立即执行本地化和格式化;否则,通过包含 TranslatableContents 的 Component 延迟执行。只有服务器需要允许原版客户端连接时,此方法才有用。

原文:Internationalization and Localization。

译注:原文提及 TranslatableComponent 和 ItemStack NBT,相关内容可能滞后;请核对目标版本的 API,示例尚未编译验证。