载入中...
搜索中...
未找到
本地化模块

本地化模块

脚本入口: eve.I18n()

面向游戏的多语言支持:载入按语言分组的翻译表(JSON),按点号路径取字符串、 替换 {name} 占位符、按语言复数规则选择复数形式,并支持缺失键回退到默认语言。

基本用法

i18n <- eve.I18n();
i18n.loadFromFile("zh", "locales/zh.json"); // 从 VFS 读 JSON 翻译表
i18n.loadFromFile("en", "locales/en.json");
i18n.setDefaultLanguage("en");
i18n.setLanguage("zh");
local title = i18n.get("menu.start"); // "开始游戏"
local hi = i18n.getWithParams("greeting", {name = "Alice"}); // "你好,Alice!"
local items = i18n.getPlural("items", 5); // "5 件物品"

产品内容应把全部语言作为一个版本化原子包发布:

local admitted = i18n.replaceBundleFromJson(bundleJson);
if (!admitted.ok) throw admitted.status.summary;

包必须使用 schema: "eve.i18n.bundle"、version: 1、defaultLocale 和 locales。replaceBundleFromJson 会严格拒绝未知根字段、非法或空键、非字符串叶子、 缺少 other 的复数表、语言间缺失/多余键、单复数类型漂移和 {placeholder} 不一致。 验证在候选副本上完成,失败不改变已发布语言、当前语言或默认语言。成功后当前语言若仍存在则保留, 否则切换到新默认语言。hasInLanguage(lang, key) 检查精确语言而不使用回退, validateKeyCoverage(key) 则以结构化结果验证每个已发布语言都精确拥有产品 key, 缺失诊断会指出具体语言与 key 路径。 getKeyCount(lang) 返回该语言拥有的单数与复数键总数。

翻译表格式

JSON 根节点是对象;值可以是字符串、数字/布尔(转字符串),或**复数形式表** (键全部为 zero/one/two/few/many/other 的对象,作为该键的复数形式)。

{
"menu": { "start": "Start", "quit": "Quit" },
"greeting": "Hello, {name}!",
"items": { "one": "{n} item", "other": "{n} items" }
}
  • 点号路径:menu.start → menu -> start。
  • 占位符:{name} / {n} 由 getWithParams / getPluralWithParams 的表或复数计数替换。
  • 缺失键:先查当前语言,再查默认语言,最后返回键本身(方便开发期看到未翻译项)。
  • 转义:JSON 原生支持 \uXXXX(含代理对)与 \n、\"</tt> 等转义。 <h2>复数规则</h2> 内置 CLDR 风格规则覆盖常用语言: <table class="markdownTable"> <tr class="markdownTableHead"> <th class="markdownTableHeadNone"> 语言

形式

en/de/es/it/nl/sv/da/no/fi/el…

one (n==1),其余 other

fr/pt

n∈{0,1} → one,其余 other

ru/uk/be

one/few/many 三形式(%10 与 %100 规则)

pl

one/few/many

cs/sk

one/few/other

zh/ja/ko/th/vi/id/ms/tr/my…

无复数区分,恒为 other

语言代码会截取 -/_ 前缀(如 zh-CN → zh)。选定形式缺失时依次回退 other → one;整键缺失再回退默认语言。

目标导向指南

为多语言配置对话

在 eve_init 中载入翻译表并设置语言,之后所有显示文本(含 Dialogue 台词、 UI 文案、选项标签)都通过 i18n.get* 取,便于后期扩展新语言:

dlg.say("alice", i18n.get("line.hello"));
dlg.addChoice("yes", i18n.get("choice.yes"));

热重载翻译表

loadFromFile 会记录文件路径与修改时间;每帧调用 i18n.update(dt) 即可在 文件变更后自动重新载入(可通过 setAutoReload(false) 关闭):

function eve_update(dt) {
i18n.update(dt);
// ...
}

常见问题

  • loadFromJson 解析失败或根节点不是对象时返回 false(错误静默,可用 hasLanguage 确认)。
  • getPlural 只认复数形式表;普通字符串键会原样返回(不做复数处理)。
  • setLanguage 只接受已载入的语言,否则返回 false 且保持原语言。

API 快查

  • clear()、get(key)、getDefaultLanguage()、getLanguage()、getLanguageAt(index)
  • getLanguageCount()、getPlural(key, n)、getPluralWithParams(key, n, params)
  • getWithParams(key, params)、has(key)、hasLanguage(lang)
  • isAutoReload()、兼容入口 loadFromFile(lang, path) / loadFromJson(lang, json)、 结构化入口 replaceLocaleFromFile(lang, path) / replaceLocaleFromJson(lang, json)
  • replaceBundleFromJson(json)、selectLanguage(lang)、hasInLanguage(lang, key)、 validateKeyCoverage(key)、 getKeyCount(lang)
  • setAutoReload(enable)、setDefaultLanguage(lang)、setLanguage(lang)、unload(lang)
  • update(dt)

params 是 Squirrel 表,值为字符串 / 数字 / 布尔时自动转字符串;非表或 null 视为空参数。

使用要点

  • 模块对象和翻译表应一次性载入并保存在全局状态,不要在每帧重复载入。
  • update(dt) 应在 eve_update 调用;文本查询可在更新或渲染阶段进行。
  • 参数约束、默认值和返回类型以头文件与 addFunc 绑定为准。

源码: src/modules/i18n/ 相关测试: 在 test/ 中搜索 i18n。