把 Ren'Py 游戏翻译流程写成一个可复用 Skill

整理 Ren'Py 游戏汉化时最容易踩坑的流程、规则和验证方法,把一次翻译经验沉淀成可复用的 Codex Skill。

最近把一套 Ren’Py 游戏翻译流程整理成了一个 Codex Skill。它的作用不是“教 AI 怎么随便翻译几句文本”,而是把 Ren’Py 汉化里那些很容易被忽略的规则,变成一份可以反复执行的检查清单。

Ren’Py 游戏翻译看起来很简单:找到文本,翻成中文,保存。但真正做起来会发现,问题经常不在“这句话怎么翻”,而在“这句话到底会不会被 Ren’Py 正确匹配、正确加载、正确显示”。

所以这个 Skill 的核心思路是:不要把翻译当成纯文本替换,而要把它当成一个小型补丁工程。

为什么要写成 Skill

单次翻译靠经验可以做完,但下一次换一个游戏,很多坑还会再踩一遍。

比如:

  • old 字符串被改了一个空格,导致翻译完全匹配不上
  • 菜单选项带了文字标签或状态后缀,生成的翻译没有覆盖真实显示内容
  • 变量插值里的人名、阵营名仍然显示英文
  • 字体不支持中文,结果游戏里全是方块
  • 直接改原脚本,更新游戏后补丁很难迁移
  • 批量脚本写文件时编码错了,中文变成乱码或问号

这些不是“翻译水平”问题,而是流程问题。Skill 适合处理的正是这种流程:每次遇到 Ren’Py 项目,都按同一套顺序检查、修改和验证。

工作区应该放在哪里

Ren’Py 翻译最重要的目录是:

1
game/tl/<language>/

Skill 里的第一条规则就是:优先在翻译目录里工作,能不改原始脚本就不改原始脚本。

原因很现实。原脚本是游戏本体的一部分,直接改它虽然快,但后续更新、分发、回滚都会变麻烦。更稳的方式是把翻译、字体、界面覆盖、语言按钮、默认语言设置等内容尽量放进 game/tl/<language>/

这样做的好处是:

  • 删除语言文件夹就能恢复原版
  • 游戏更新时更容易迁移
  • 补丁边界清楚
  • 不容易误伤原游戏逻辑

如果原游戏没有 .rpy,只有 .rpyc 或资源包,那就先处理解包、反编译或生成翻译文件的问题,而不是直接乱改。

old/new 不能乱动

Ren’Py 里常见的翻译形式有两种。

一种是对话块:

1
2
translate chinese start_abc123:
    "这里写翻译后的台词"

另一种是字符串表:

1
2
3
translate chinese strings:
    old "Start"
    new "开始"

这里最容易犯的错是改 old
old 不是给你润色的原文,它是 Ren’Py 用来匹配原始文本的钥匙。空格、标点、文本标签、大小写、换行都可能影响匹配。

所以规则很简单:

1
2
old 保持原样
new 写翻译

如果一个 old 看起来有点怪,比如带着 {size=}、颜色标签、状态后缀,也不要顺手清理。真实运行时显示出来的字符串很可能就是这么匹配的。

菜单和 UI 要单独查

Ren’Py 自动生成翻译文件很有用,但它不一定能覆盖所有运行时可见文本。

除了对话,还要主动搜索这些位置:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
Character("...")
text "..."
textbutton "..."
tooltip "..."
renpy.input("...")
renpy.notify(...)
default xxx = "..."
define xxx = "..."
$ xxx = "..."
menu:

尤其是菜单选项。它们经常带条件、标签、样式或自定义 screen 处理。你在翻译文件里看到的 old "Yes",不一定覆盖了运行时真正显示的 {color=#fff}Yes{/color}

如果某个选项死活不翻译,别先怀疑 Ren’Py。先把运行时原文和 old 逐字节对一下,包括空格和标签。

变量插值是隐藏大坑

这次整理 Skill 时,最值得单独记下的是变量插值。

Ren’Py 里常见写法是:

1
"Welcome to [tribe_name], [player_name]."

如果 tribe_name 的值是 "Wartribe",即使你在字符串表里写了:

1
2
old "Wartribe"
new "战族"

最终显示时也不一定会自动变成中文。因为普通的 [tribe_name] 插值只是把变量当前值拿出来显示,不会必然再走一遍翻译表。

这种情况下要用翻译感知插值:

1
"欢迎来到 [tribe_name!t],[player_name!t]。"

如果变量翻译后还需要继续插值,可以看情况用:

1
[variable!ti]

这个坑很隐蔽,因为外面的句子已经翻译了,只有嵌进去的人名、地名、阵营名还保留英文。看起来像漏翻,其实是插值方式不对。

高级补丁放 zzz.rpy

有些问题不是一句 old/new 能解决的,比如:

  • 添加语言切换按钮
  • 设置默认语言
  • 替换字体
  • 调整中文 UI 样式
  • 覆盖 screen
  • 修正少量源代码层面的文本

这类内容可以放到翻译目录里的补丁文件,例如:

1
game/tl/chinese/zzz.rpy

常见做法是加:

1
init offset = 1

让补丁比原定义更晚加载。这样可以覆盖 screen、style、define 等内容,又不会直接动原文件。

默认语言也要分清:

1
define config.default_language = "chinese"

这更适合“首次启动默认中文”。
如果用 config.language 强行指定语言,就可能变成每次启动都锁死语言,不一定符合玩家预期。

字体不是最后再想的事

中文翻译里,字体问题经常到最后才暴露:文本已经翻好了,进游戏一看全是方块。

Skill 里把字体和样式也放进检查范围。一般有几种处理方式:

  • translate <language> style 里覆盖样式
  • translate <language> python 里设置 GUI 变量
  • game/tl/<language>/ 下镜像放置字体资源
  • zzz.rpy 做语言限定的字体覆盖

关键是尽量让字体修复只影响目标语言,不要全局改坏原版 UI。

不要信任批量替换

批量脚本很诱人,尤其是翻译量大的时候。但 Ren’Py 文件里有很多结构性内容:

  • 缩进
  • 引号
  • 转义符
  • 文本标签
  • 插值变量
  • %\/ 这类特殊符号

如果脚本没有严格按 UTF-8 读写,中文很容易变成乱码、问号或损坏标签。

所以 Skill 里明确写了:在 Windows 上做批量编辑时,要使用明确的 UTF-8 读写方式。改完后要扫一遍:

1
2
3
4
5
乱码
???? 
损坏的 {tag}
损坏的 [variable]

翻译文件不是普通 Markdown,不能只看文本大概对不对。

验证要看三个文件

改完之后,不要只打开一两句台词看看。至少要检查:

1
2
3
errors.txt
traceback.txt
text_overflow.txt

它们分别对应不同问题:

  • errors.txt:生成或启动阶段的问题
  • traceback.txt:运行时崩溃
  • text_overflow.txt:文本溢出、排版放不下

还要实际测试:

  • 主菜单
  • 设置界面
  • 语言切换
  • 存档读档
  • 代表性对话
  • 选项菜单
  • 字体显示
  • 被覆盖的 label 或 screen

Ren’Py 翻译不是“文件能保存就完成”,而是“游戏运行时每条路径都能正确显示”。

这个 Skill 最有用的地方

我觉得它最有用的不是告诉 AI “请翻译成中文”,而是强迫 AI 先尊重 Ren’Py 的工程规则。

它会提醒我:

  • 不要乱改 old
  • 不要直接动原脚本
  • 不要忽略菜单和 UI
  • 不要忘记变量插值的 !t
  • 不要把字体和排版当成收尾小事
  • 不要跳过运行验证

这比单纯提高翻译文风重要得多。

总结

Ren’Py 游戏汉化本质上不是文本替换,而是一套围绕运行时匹配、语言加载、界面覆盖和补丁分发的工程流程。

把这套流程写成 Skill 之后,AI 就不只是“会翻译”,而是会按固定步骤处理项目结构、翻译文件、UI 字符串、变量插值、字体、补丁和验证。

下一次再做 Ren’Py 游戏翻译时,就不用从零回忆哪些坑要避开。直接让 Skill 接管检查清单,人只需要把关翻译质量和最终体验。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计