先说一个看起来有点蠢的问题:

一段游戏文本里,到底哪些是给人类看的?

比如,这一句:

Welcome back, {player_name}!\nHP: %03d
        

人类看到的是「欢迎回来」和「生命值」。

而游戏在后台看到的东西,显然要复杂得多:

  • {player_name} 是变量,需要在运行时替换为玩家的名字,不然每个玩家都拥有同一个名字:{玩家名}。
  • \n 是换行,并不是字母 n,请不要假装没看到前面的反斜杠……
  • %03d 是数字占位符,而不是直接翻译成「百分之三D」,显然玩家并不知道D为什么还要有百分之三。

它们被塞在同一行里,看起来都是字符,但它们本质上是不同类型的内容。

对翻译者来说,这只是游戏里的一句对话。

对游戏引擎来说,这则是一小段带着约束力的合同:某些部分可以改,而某些部分少一个符号都不行,否则就崩溃给你看。

然后,我们把整行都丢给 AI,并且认真叮嘱:

请只翻译人类能看到的文字,而其他内容千万不要动。

模型很礼貌地答应了,并表示“好的,我接住了。”

至于它到底接没接住,用什么姿势接住的,那就是另一回事了。

01 首先,AI 并非是故意搞破坏,它只是不知道哪些东西可以碰,哪些东西不可以碰

AI 可能看得出 {player_name} 像个变量,但它实际上并没有运行你的游戏,也不知道少一个括号会造成什么真实后果。对它来说,这仍然是输入文字的一部分,也就仍然属于可以被改写的范畴。

所以,下面这些事情每天都在发生:

{player_name}  →  {玩家名}
        %03d           →  %3d
        \n             →  \\n
        {b}...{/b}     →  {b}...{b}
        

有时它会翻译变量名,有时会顺手整理空格和标点。甚至有时候,它会觉得两个长得奇怪的标签是重复内容,于是非常热心地帮你删掉一个。

哪怕你在提示词里告诉 AI 这是什么引擎,它确实可以认出大部分变量和标签。可认得是一回事,在接下来的几万行里每一行都严格执行,又是另一回事。

上下文一长,前面那句“这些东西千万别动”就会被它挤到记忆的角落里。更何况在开发游戏时,人类制作者多少都会塞一些自定义标签或者奇怪的语法进去,AI 没见过也完全合理。

而且相对于传统翻译引擎来说,AI 是“活的”,所以它完全会自作主张地开始思考:

“这个空格好像没用,删!”

“等等,这两个标签是不是重复了,删!”

“这到底是不是变量名?算了,还是翻了吧。”

所以,知道归知道,漏还是会漏。

单独看,每个改动确实大差不差。

但把文本塞回游戏引擎以后,结果通常包括但不限于:

  • 玩家的名字在游戏里凭空消失了。
  • 数字格式彻底乱套了。
  • UI 画面上直接出现 \n 两个字符。
  • 句子直接突破对话框,一骑绝尘。
  • 后面整整几万字的文本一起变成了粗体或红色。
  • 最干脆的情况:游戏直接报错,拒绝启动。

而且,这种迷惑行为并不只会发生在 AI 身上。

人类翻到深夜第 3000 行,前额叶同样会日常死机并直接手滑。

翻译工具自己如果处理转义不对,也一样能把东西弄坏。

在工作记忆这方面,人类的脑细胞并没有比大模型可靠多少。AI 会产生幻觉,人类也会,而且人类有时候还会错得极其自信。

尤其是多人同时参与一个翻译项目的时候,“我以为我们之前定好的就是这个啊”“哎呀,我漏了一个括号”之类的状况,发生的概率大概是 100%。

在做 Goblin Forge 之前,我本来就在参与多人翻译项目。

当时,我花了整整一天,纯手工去核对 4 万多行句子里的换行标记是不是少了半个括号,以及 player_name 是不是又被翻译成了“玩家名”。

一边平静地检查,一边我的脑子在嚎叫:

都说了无数次了,为什么还是能漏掉这么多?

所以我越来越觉得,所谓“保护代码”,既不能指望 AI,也不能指望人类。只要文本经过了导入、编辑、翻译、批量替换或者导出,它在任何一个环节都存在被破坏的可能。

既然大家都不太靠谱,那我们就需要换一种方式了。

02 那么,在提示词里,多叮嘱一些,有用吗?

有用,但不够。

你确实可以在提示词里写上:

Preserve all variables, placeholders, tags and escape sequences exactly.

这也确实会降低出错的概率。

但问题在于,“降低概率”在面对脆弱的游戏地基时,并没有人类想象中那么实用。模型迟早会因为各种不可控的变量蹦出新的变化,进而在你不知情的情况下,又把地基炸了。

大模型换了,出错概率会变。

句子变长了,出错概率会变。

上下文里刚好出现一段长得像代码的自然语言,结果同样会变。

更麻烦的地方在于,就算前 999 行它表现得像个毫无瑕疵的模范员工,第 1000 行是否出错,依然是一个独立事件。

而且它每次翻车的方向也未必一样:这次翻译变量名,下次吞掉半个括号,再下一次又多加一根反斜杠,甚至两次翻译的同一个变量名可能都是不同的翻法。

在这种无序的出错面前,人类连该从哪里开始查都不知道。

03 所以,终极防爆手段:给代码叠上只读Buff

既然事实已经证明,不管是人类的工作记忆,还是大模型的全功率对齐,都不靠谱,那就干脆不要再把所有东西都当成普通文字放在一起。

我们需要做的是干脆把这些不能碰的东西,从句子里剥离出来,彻底让 AI 碰不到,人也无法随意手滑。

在一行游戏文本里,真正需要被编辑的,其实只有人类能看懂的那部分。

至于剩下的变量、占位符、标签和换行符,理应被单独标记并锁死。

而且,不能只是给它们换个颜色,这种改色只算一种视觉提醒,而且提醒的大概率是人类,而不是AI。

所以,真正的保护,是让这些内容直接变成只读状态。

它们在界面里可以被观看,可以被整体移动,但绝对无法被拆开,并顺手改掉任何半个字符。

翻译进行时,它们就老老实实地待在原地。人类只负责修改人类的语言,AI 也只被允许处理人类的语言。

最后,再彻底核对一遍原文和译文里的结构,类似于打包快递之前的清点零件:该在的东西都在,该叫什么还叫什么。

04 但是,工具依然有认错的概率

不同游戏引擎有不同的写法,加上各种插件和开发者自己发明的怪异语法,情况就会变得无序起来。

因此,工具预先认识的规则再多,也不可能自动猜中所有游戏开发者的想法。

规则设得太宽,会把本来应该翻译的文字一起锁住。规则设得太窄,又会让真正的代码漏过去。

所以比较稳的做法是,先拿几十行包含各种奇怪符号的文本丢进去测试一遍,确认没问题以后,再拿去处理几千、几万行的项目。

请务必打消一上来就直接把整个项目彻底交出去的念头。

规则写错的时候,工具并不会报错,照样可以很有自信地替你翻完几万行。

等到最后返工的时候,痛苦的就是你自己了,哈哈,别问我是怎么知道的。

05 不管你打算用什么工具,至少遵守这几条生存法则

不管你最后决定使用表格、脚本、聊天机器人还是什么高级的 CAT 工具,请记住:

别相信你的记忆。

  • 第一步永远是备份,除非你真的想要大晚上的,守着磁盘恢复工具,不停地流冷汗。
  • 请列出所有不能碰的格式,包括但不限于:变量、占位符、标签、转义符、脚本命令。
  • 请先翻小样本,最好是包含各种奇怪符号的,大概 50–100 行吧。
  • 比较原文和译文里的结构,记得数量、名字、配对关系都要检查一遍。
  • 再跑全部文本,请务必不要反过来,除非你觉得反复重装游戏是一种享受。
  • 最后进游戏测试。

很多人总觉得只要文件成功写回去了,游戏能顺利启动了,就代表大功告成。

但现实往往是:

占位符一个不差,玩家一打开对话框,文本直接突破天际。

明明是个中年男人的角色,开口却是:人家觉得……

甚至更隐蔽的情况是,文件看起来天衣无缝,但玩家只要触发了某一条特定的分支剧情,游戏就会极其干脆地当场死机。

所以,永远不要把「翻译完成」和「测试完成」画上等号。

最后还是得进游戏看一遍,甚至是好几遍,否则现在省下来的时间,很可能会在返工的时候连本带利地还回来。

06 因此,我把这套物理保护盾整进了 Goblin Forge

鉴于我反复被 AI 和人类的记忆按在地上摩擦,我在做 Goblin Forge 时,第一件事就是解决这个问题。

文件导入以后,系统会自动识别所有的变量、标签、占位符和转义符,然后把它们打包塞进一个只读的“代码胶囊”里。

这个胶囊在翻译界面中是一个不可分割的物理整体,你可以直接看到它原本的字符,也可以切换显示它的具体含义。

胶囊本身允许被整体移动、添加或者删除,但你就是没办法拆开它改动里面任何半个字符,除非你去修改默认的设置和模板。

这样一来,像括号只删了一边,或者标签漏掉半个符号之类的情况,在物理层面上被直接阻断了。

翻译完成以后,Goblin Forge 还会像核对零件清单一样,再核对一遍原文和译文的结构。

如果少了零件、多了零件,或者前后对不上,就会把那一行标注出来,让你在润色和校对的时候知道应该去哪里补救。

当然,不同游戏总会有一些自己的奇怪写法。所以,除了软件预设的常见格式和引擎模板,你也可以根据项目添加自定义的保护规则。

第一次使用时,仍然建议先拿一小部分真实文本试水,看看有没有被规则漏掉的东西。

从导入时识别,到翻译时锁住,再到翻译后的结构检查,这些步骤在 Goblin Forge 里是连在一起的。

毕竟我再也不想花一整天,在四万多行文本里大海捞针了。