Files
2026-07-20 10:56:52 +08:00

4.7 KiB
Raw Permalink Blame History

04 本地化工作流 (Localization Workflow)

项目遵循 ADR-A1:所有玩家可见字符串必须通过 tr("KEY") 包裹,禁止业务代码中出现裸字符串。


1. 文件位置

translations/
  zh_CN.po   ← 简体中文(权威主档)
  zh_TW.po   ← 繁体中文
  en.po      ← 英文
  ja.po      ← 日文

2. .po 文件格式

每条翻译的格式为:

msgid "UI_WAVE"
msgstr "第 %d 波"
  • msgid:代码中 tr("KEY") 使用的键
  • msgstr:该语言显示的文字
  • %d%s%.1f 等格式占位符必须与代码中 tr("KEY") % value 完全对应

3. 添加新翻译字符串(标准流程)

Step 1 — 在代码中使用 tr() 键

# ❌ 错误:裸字符串
label.text = "商店已关闭"

# ✅ 正确:通过键引用
label.text = tr("SHOP_CLOSED_MSG")

# 带参数
label.text = tr("UI_WAVE") % current_wave      # → "第 3 波"
label.text = tr("UI_KILLS") % [kills, alive]   # → "击杀: 7  存活: 3"

Step 2 — 在全部四个 .po 文件中添加对应条目

zh_CN.po(权威档,写游戏实际中文):

msgid "SHOP_CLOSED_MSG"
msgstr "商店已关闭"

zh_TW.po(繁体,改繁体字):

msgid "SHOP_CLOSED_MSG"
msgstr "商店已關閉"

en.po(英文):

msgid "SHOP_CLOSED_MSG"
msgstr "Shop Closed"

ja.po(日文):

msgid "SHOP_CLOSED_MSG"
msgstr "ショップが閉店しました"

Step 3 — 验证(运行时检查)

在游戏内执行脚本验证无缺键:

var keys = ["SHOP_CLOSED_MSG"]  # 你新加的键
for loc in ["zh_CN","zh_TW","en","ja"]:
    Locale.set_locale(loc)
    for k in keys:
        if tr(k) == k:
            print("缺键!语言: %s  键: %s" % [loc, k])

4. 键名规范

格式<模块>_<实体>_<含义>,全大写 + 下划线

前缀 用途 示例
UI_ 通用 HUD 标签 UI_WAVE, UI_HP
SHOP_ 商店界面 SHOP_TITLE, SHOP_REROLL
INV_ 背包界面 INV_TITLE, INV_BENCH
SETTLE_ 结算屏 SETTLE_TITLE, SETTLE_STATS
SETTINGS_ 设置面板 SETTINGS_DIFFICULTY
STATUS_ 状态消息 STATUS_PURCHASED
DIFF_ 难度名称 DIFF_BEGINNER, DIFF_CHALLENGE
SPELL_ 法术名/描述 SPELL_SPARK_BOLT_NAME, SPELL_SPARK_BOLT_DESC
CORE_ Core 名/描述 CORE_WAND_BASIC_NAME
STATUS_EFFECT_ 状态效果名 STATUS_EFFECT_BURN_NAME
BOSS_ Boss 名称 BOSS_FINAL_NAME

5. 法术 / Core 名称本地化(待完成)

当前法术 display_name 字段存储的是裸英/中文字符串(如 "Spark Bolt")。正式发布前需键化。

注意:修改后须同步更新商店按钮渲染(combat_s2.gd → _refresh_shop_ui),将 spell.display_name 改为 tr(spell.display_name)

Step 1 — 修改 wand_preset.gd

# 当前(裸字符串)
n.display_name = "Spark Bolt"
n.description  = "发射一颗期限 4s 的电光飞弹,造成 3 伤害。"

# 修改为(键)
n.display_name = "SPELL_SPARK_BOLT_NAME"
n.description  = "SPELL_SPARK_BOLT_DESC"

Step 2 — 在四语 .po 中添加

# zh_CN.po
msgid "SPELL_SPARK_BOLT_NAME"
msgstr "电花弹"

msgid "SPELL_SPARK_BOLT_DESC"
msgstr "发射一颗快速电花飞弹,造成 3 点闪电伤害。"

Step 3 — 显示时包裹 tr()

# UI 显示法术名时
btn.text = tr(spell.display_name)
# 法术描述
desc_label.text = tr(spell.description)

6. 添加新语言

Step 1 — 创建新 .po 文件(以韩语为例)

translations/ko.po

内容:复制 en.po,将 Language: en 改为 Language: ko,翻译所有 msgstr

Step 2 — 在 locale_manager.gd 中注册

const LOCALES: Array = ["zh_CN", "zh_TW", "en", "ja", "ko"]  # 追加 "ko"

新语言将自动在商店语言切换按钮中循环出现。


7. 在游戏内切换语言(测试用)

# 切换到英文
Locale.set_locale("en")

# 循环切换(等同商店 🌐 按钮)
Locale.cycle_locale()

# 查看当前语言
print(Locale.get_locale())

8. 提交规范

每次提交涉及玩家可见字符串的改动时,须同时更新四个 .po 文件。允许以英文或空字符串占位(msgstr ""),但 PR 审查时须标注"待翻译"。


9. 工具推荐

工具 用途
Poedit .po 文件 GUI 编辑器,支持模糊匹配和自动翻译接口
VSCode + gettext 插件 轻量化文本编辑
Godot 内置本地化 Project → Project Settings → Localization → Translations 可预览各语言