在魔兽地图汉化这方面,我自诩算上得资深人员之一。在汉化1.0的时代,我们直接拿导出的wts文件,一条条复制粘贴丢进谷歌和百度里翻译。在汉化2.0的时代,我们将wts和j里的字符串文本提取到Excel或wps里,删除重复数据再翻译。在汉化3.0的大模型时代,我们开始借助AI大模型翻译,优点是大模型能够在快速保持文本格式标点的情况下快速翻译,缺点是受大模型上下文限制,在翻译新地图或更新翻译时会出现上下文同一个词或描述翻译不一致的问题。

现在到了汉化4.0的AI Agent时代,我用 WorkBuddy 翻译,它能够像我一样去思考如何翻译做到格式零破坏、术语零冲突

这篇文章有两个目的:讲清楚这套方法为什么成立,
以及给你一份读完就能用的东西——一个包、一段话。
你只需安装WorkBuddy(这是我的邀请链接:https://www.workbuddy.cn/events/invite?inviteCode=2k3esywk0p),不需要装任何环境,不需要记任何命令。

赶时间的话直接看第二节,那里有你需要复制的全部内容。


一、先说清楚要解决的问题

现在有一张《肥羊镇最后的30分钟》的俄语 RPG 地图,我要把它更新汉化。我用在汉化3.0时代借助AI发的[DarkSheep魔兽汉化小助手]快速提取出来两张表:

一格是什么行数
字符串wts主表一句俄文(单位/物品/技能的名字与说明)10,000+
war3map.j 表一整行 JASS 代码,俄文藏在引号里2,900+

第一张表有编码、有类型区分(单位、物品、技能),能够辅助翻译;

第二张表是真正的难点,它的每一格长这样:

call DisplayTimedTextToForce(bj_FORCE_ALL_PLAYERS,45.00,"|cFFC60000危险逼近!|r\n\n|cFFFF5800来袭的是 - 亡灵 (400% 强度).")

我要翻译双引号里的俄语,同时一个字符都不能动外面那堆东西——它们看起来像排版噪音,但它们是代码
bj_FORCE_ALL_PLAYERS45.00、括号、逗号,还有引号内的 |cFFC60000|r

bj_FORCE_ALL_PLAYERS、括号、逗号 要是在批量AI机翻时被"顺手优化"一下,可能直接无法加载地图。

|cFFC60000 是引擎的颜色指令,|r 是颜色结束符,|n 是换行。虽然缺失游戏可以照常运行,但是某段文字颜色会丢失,影响玩家体验。


二、在 WorkBuddy 里怎么用(重中之重)

先说最重要的一点:

你除了安装WorkBuddy以外,不需要装任何东西,也不需要执行任何命令。
我这条路走下来的所有笨活——装依赖、跑脚本、比对格式、逐个核数字——
都是 AI 做的。你要做的只有三件事:关掉 Excel、确认回填、拍板疑难译名。

2.1 下载我沉淀下来的技能

目前版本2.0,后期不定期更新,当然你在使用过程中它自己也会“进化”。

解压后:

wow-rpg-l10n/
  README.md              和这一节说的一样
  方案参考.md             流水线原理 + 失败模式表
  skill/                 ★ 可安装的 WorkBuddy 技能
  prompts/
    00-冷启动.txt         ★ 新会话第一条消息
    01~06-*.txt           后续各阶段的提示词
  scripts/               主表流水线
  war3mapj/scripts/      war3map.j 流水线
  tools/
    new_map_project.py   新地图工程脚手架
    build_kit.py         重新打包本 kit

里面没有模型、没有二进制、不需要注册任何账号。

2.2 用法 A:装技能(强烈推荐)

skill/wow-rpg-l10n-localize/ 整个目录复制到 WorkBuddy 的技能目录:

skill/wow-rpg-l10n-localize/  →  ~/.workbuddy/skills/wow-rpg-l10n-localize/

之后任何新会话,只要说到"本地化""汉化""翻这张表",
WorkBuddy 会自动加载这套方法,你不用再交代背景。

技能里装的是这套方法最值钱的部分:踩过的坑、回归时必须绕开的误伤、哪些东西绝对不能交给 AI 决定。

虽然它总结提炼于我汉化的《肥羊镇最后的30分钟》,但它现在独立于任何一张具体地图

2.3 用法 B:临时用一次

不装技能也行。解压之后,在 WorkBuddy 里开一个新会话
把下面这段话改一改发出去:

我把 wow-rpg-l10n 解压到了 D:\l10n\wow-rpg-l10n。
我要汉化一张俄语 RPG 地图,表在 D:\maps\我的地图\xxx.xlsx:
第 3 列是俄文原文,第 4 列放中文译文,第 5 列是标记(标记写「未替换」的待翻)。

## 请先做这件事
读 project.json 和 方案.md,然后用不超过 10 行向我复述:
地图代号、主表路径、当前「未替换」有多少条、术语表有多少条。
**复述对得上再继续**,对不上先问我。

## 规则
1. 只翻译俄文,英文标识符一律保留。**(这条规则要根据你们翻译地图的语种去修改)**
2. 格式零改动:|cXXXXXXXX、|r、|n、{ }、\、/、* 的数量与位置必须与原文一致。
3. 数字逐个对读——曾出现把「每2秒」译成「每3秒」而自动校验没抓到的情况。
4. 名词查术语表,表里有的不许改;表里没有的,译完问我是否固化。
5. 每批 35 条左右,先翻译后校验,**回填必须等我明确同意**。
6. 不确定就问我,不要猜。

## 依赖
缺什么你自己装(装在隔离环境里,别动系统 Python)。命令你自己跑。

然后就进入循环了。你每天要发的消息,大概是这样:

「继续下一批。」

三个字。剩下的它自己跑。

2.4 你要做的三件事

你要做为什么不能交给它
关掉 Excel回填时文件被占用,脚本会退化成输出一个新文件,版本一多就分不清哪个是最终版
确认回填这是整套流程里唯一不可逆的动作。虽然有备份,但混乱一旦产生就要花时间理清
拍板疑难译名遇到没上下文线索的专名,它会列清单问你。猜错的代价远大于多问一次

第三件最容易被忽略,但它恰恰是质量的关键。
比如有个物品套装名Первопроходец,它给了「拓荒者」并标注"音意结合,置信度高",我确认了;
另有个词它标注"无上下文线索,置信度低",我给了一个符合语境的译法。
这些判断只有你能做,因为你知道这张地图的世界观。


(以下为选读内容,主要讲述了我想要解决的问题和思路)

三、它到底替你做了什么

这是我觉得最值得说清楚的一节。传统"用 AI 翻译"的用法是:你提问,它回答,你复制粘贴。

瓶颈从来不在 AI 的翻译能力,而在AI能不能最大程度的保持一个词语或一段描述在这成千上万行里的一致性。

而它就是建立了这样一套流程,这套流水线首先把角色的边界重新划了一遍:

环节谁做为什么
装 Python、装 openpyxlAI它自己会在隔离虚拟环境里装,不碰你的系统 Python
按对象分组、术语掩码AI + 脚本机械劳动,人有太多偶然性
逐格式比对、逐个核数字AI + 脚本人做会漏,机器又快又准
发现告警后归因AI这一步让错误类型收敛,而不是原地重复犯
判断某个词该怎么译只有你知道地图的世界观
决定是否写表唯一不可逆的动作

划完边界后,一个明显的事实浮出来:真正耗时的不是执行,是"发现翻译存在的问题并归因"。


四、核心分工:脚本负责"不会错",提示词负责"译得好"

这是整套方法最朴素也最重要的一个判断。

我把约束分成两类:

类型特征谁来做
可机械判定格式、数字、符号数量、术语一致性脚本
需要判断力语义流畅度、译名选择、文化适配AI + 提示词

让一个擅长语言、不擅长计数的大模型去数 |r 出现了几次,是浪费也是冒险。
反过来,让脚本去判断某个词在这里该译"揭露"还是"揭开",也不可能。

流水线定型是这样:

① 术语资产 glossary.json
② 按对象分组(同一技能的 name / tip / ubertip 一起送译)
③ 归一化 + 占位符掩码(俄文术语 → {{T_ARMOR}})
④ AI 翻译
⑤ 六项自动校验 + 回填
⑥ 术语全局回归 + 人工抽样

其中 ②③⑤⑥ 全是代码,④ 是 AI,① 是人与 AI 共同维护的资产。

但是流程建立之初行不通。我把一批俄文贴给 AI、译完粘回 Excel。
跑了三批就不行了,因为存在四类错误:

  1. 格式被"优化"。它觉得 |n 该换成真换行、|r 是多余的、句号该改中文句号。但那些是引擎指令。
  2. 术语翻车。同一个技能在三个字段里出现三次,给了三个译名——玩家看到同一技能两个名字,直接出戏。
  3. 数字失真。源文里有2有3,有时翻译结果却不知道先用2还是先用3。
  4. 前后不一致。第一次译成的说法,可能在第5次更新时就换了另一种——它根本不记得第五次之前译过什么。

第 4 点让我意识到一件事:对话记忆不是资产
指望 AI "记住"几千行前的译名,注定失败。真正可靠的记忆必须落盘。
这就是为什么每张地图都要有独立工程目录和 glossary.json


五、最得意的一个设计:术语掩码

术语一致性的常规做法是"译完后统一替换"。这条路我走过,是地狱。

因为我们的中文没有词边界。你要在一万个已译好的句子里替换「防御」→「护甲」,
而「防御塔」「防御图腾」「防御建筑」里的「防御」不能动。
你如果加白名单,白名单越来越长,总有漏的。

于是我们做了件相反的事:在 AI 看到俄文之前,先把术语挖掉。

俄文:Увеличивает защиту на 15 ед.
        ↓ 掩码
AI 看到:Увеличивает {{T_ARMOR}} на 15 ед.
        ↓ 翻译
AI 输出:提升 15 点 {{T_ARMOR}}
        ↓ 回填时还原
最终:提升 15 点护甲

它从头到尾没见过那些术语的俄文形式,所以不可能译错。

代价是要维护一张术语表和它的俄语变格形式——这个用俄语形态学规则能生成大部分,剩下的手工补。

配套还有"分组送译":批次不是随机切分,而是按注释列的 对象:代码 分组。(在本站的表格翻译教程里,我们将物编字符串提取到表格有一列是物编的注释,这个注释有利于"分组送译")
同一技能的名字、说明、扩展说明一起送译。分开的话会给三个略有差异的译名,
而这种错误自动校验抓不到——因为三者都是合法中文。


六、踩过的五个坑

1. 数字:唯一一类"校验通过但仍然错误"的情况

раз в 2 сек 译成「每 3 秒」,六项校验全部通过。
因为那行上下文里正好还有一个 3,数字多重集合恰好相等。

集合相等 ≠ 数值正确。

2. 「防御塔」变成「护甲塔」

术语回归时整格替换「防御」→「护甲」,地图里所有"防御塔"变成了"护甲塔"。

修法是给回归脚本加左右邻字判定专名白名单
遇到「防御」先看它前面是不是"座/建/造"、后面是不是"塔/图腾/建筑",再决定动不动。

3. 批次错位,最后几条永远漏翻

preprocess.py N offset 的 offset 是剩余未译列表的绝对偏移。
第二批取 offset=40 时,列表已经因为第一批回填而收缩,于是跳过几条。

后来改成每批固定取头部 preprocess.py 35 0,再没出过问题。

4. 手写批次 JSON 的笔误

少个括号、颜色码 |cFF00C9AD00 少写一位——这些笔误会连带污染数字集合校验,
报出来的错还指向错误的地方。改成让 AI 用脚本生成后彻底解决。

5. 自创占位符

它自己发明了 {{T_DMG}} 这种原文里没有的占位符,还原时查不到,
就残留在了游戏文本里。规则补了一条:只能使用原文真实出现过的占位符


七、war3map.j 那一侧的额外处理

这张表的校验器和主表不一样,值得单说。

最初我用"整行骨架逐字比对",结果满屏误报——中文语序一调整,
45.00 后面跟的东西顺序就变了,于是被判成"代码被改动"。

后来改成只锚定 JASS 标识符udg_ / gg_ / bj_ / s__ 开头的变量、
Xxx( 形式的函数调用),并且比对前做中英文标点归一化
(否则 ! 会被判违纪)。

道理还是那个:先问"这件事该谁做、判定标准是什么",再动手。


八、三条可以带走的经验

1. 对话记忆不是资产,落盘的才是。

术语表、校验规则、踩坑录——全部落盘。正因为如此,
换一个全新的会话也能瞬间恢复全部工作能力。
如果你的某个 AI 工作流"必须接着上次聊",说明有东西该从上下文里提出来写进文件了。

2. 先问"这件事该谁做",再问"该怎么做"。

整个方案里最有效的一步,不是写了多精妙的提示词,
而是把"数字符号数量"这类活从提示词里拿走、交给脚本。
提示词应该只承担真正需要判断力的部分。

3. 自动校验通过 ≠ 正确。

任何"机器说 OK"的地方,都要想一遍"它到底检查了什么"。
集合相等不等于数值正确,正则匹配不等于语义正确。


附录:六项自动校验 + 三项人工必查

自动:

  1. |cXXXXXXXX / |r / |n 标记数量一致
  2. {} 大括号平衡
  3. 数字多重集合一致
  4. 无西里尔字母残留
  5. 无非标准译法(legacy 黑名单)
  6. 无占位符残留

外加三项必查(前六项会漏):

  1. 数字逐个对读——不是数集合,是逐个数值比对
  2. 残留西里尔字母扫描
  3. {} 大括号平衡

第 1 项最重要,原因见第六节。


*如果你也在魔兽地图汉化或者是游戏/小说汉化,或者在处理任何"大量文本 + 严格格式"的任务,
希望这套思路有用。最难的不是翻译,是让一万行文本彼此保持一致——
而这件事,人和机器各管一半。*