跑过一阵子联机服的人应该都遇到过这种情况:装好 FastAsyncWorldEdit(后面我都叫它 FAWE),进游戏敲几条//set、//copy,控制台反馈过来的全是英文,或者干脆中英混杂,一句“已设置”后面跟着一段英文的坐标信息。插件本身能用,但作为给玩家开放的建筑工具,满屏英文提示确实影响体验。所以 zh-cn strings.json 中文汉化这件事,就成了很多服主绕不开的一道坎。
这篇文章不聊大道理,就讲清楚 FAWE 中文汉化文件是干什么的、怎么自己动手改一份、改完放哪里、出了故障怎么排查。内容围绕实际操作展开,里面有我从多次汉化维护里踩出来的坑和总结出来的习惯,适合正在给自己的联机服环境做本地化的服主,也适合刚接触 FAWE、想搞明白这套文本机制是怎么回事的玩家。
1. 这一份汉化文件到底在改什么东西
1.1 插件提示文本并不在代码里
先回答一个最基础的问题:FAWE 的命令反馈,为什么不是直接写死在一段程序代码里,而是跑去找一个 strings.json 文件?因为插件开发者把“界面语言”和“程序逻辑”拆开了。程序里需要向玩家显示文字时,它不直接输出句子,而是丢出一个键名,比如fawe.set.done,然后由语言文件里对应的内容来决定玩家实际看到什么。
你可以把语言文件想象成一本地图册:程序拿着门牌号(键名)去查地址,查到哪个地址,就把对应的文字贴出来。修改文案、把英文换成中文,完全不用动程序本身,只要改地图册上的内容就行。这份 zh-cn strings.json,就是专门给 FAWE 用的中文翻译地图册。
正因为这个机制存在,汉化工作才不会变成“改代码”,而是变成一件可以有流程、能被反复执行的体力活加细心活。搞清楚这个逻辑之后,你就明白为什么网上有人说“汉化文件坏了插件就起不来”这种话纯属夸张——最坏的情况也只是插件找不到某些文字,退回英文显示而已,不会把插件搞崩。
1.2 为什么官方中文显示总是不完整
很多服主会想:插件不是有官方中文吗?为什么我还要自己去汉化?这里有个“理想很丰满、现实很骨感”的问题。FAWE 作为世界编辑插件的一个分支,本身迭代非常快,每隔一段时间就可能新增命令、新增参数、新增错误提示。语言文件的条目是分社区模块维护的,新功能对应的翻译往往要等很久才能补齐。
另一方面,官方语言文件即使已经写明中文,质量也未必符合国内玩家习惯。比如某些命令反馈直译味道很重,读起来像说明书;又比如命令错误提示只有干巴巴一句话,玩家并不知道错在哪、下一步该干嘛。这些情况都促使服主自己去维护一份更顺手的中文文本。
1.3 汉化文件覆盖了哪些内容
一份完整的 FAWE 中文语言文件,覆盖范围其实挺广。通常包括:
- 核心命令的完成反馈,比如选区设置完成、方块替换完成、剪贴板复制成功;
- 选区工具的使用提示,比如“左键选择第一点、右键选择第二点”;
- 权限不足、指令使用错误、参数非法等异常提示;
- 命令帮助菜单里的描述文本;
- 异步任务、队列任务处理过程中的进度提示和完成提示。
这还只是大方向。实际操作中你会发现,不同版本的语言文件里,键名的命名规则、条目的数量差别不小。这也就是为什么汉化必须认准版本来做,不能随便从网上找一个版本号对不上的汉化文件就往服务器里塞。
2. 动手之前的准备:版本、解包与路径
2.1 先把插件版本锁死
汉化工作的第一步不是打开编辑器开始翻译,而是确认服务器上 FAWE 的版本。同一分支下,版本不同,语言文件里的键名可能差很多。我见过有服主拿一个旧版汉化文件硬塞给新版插件,结果汉化文件里一半的键名在插件里根本不存在,插件启动时报了一串“无法加载语言文件”的警告。
查看版本号的方法很简单:进服务器控制台,执行 FAWE 自带的版本查询指令,或者直接看 plugins 目录下 FAWE 插件文件的文件名。把版本号记下来,后续下载、修改、替换都围绕这个版本进行。这里顺便提一句,如果服务器用的是开发版构建,语言文件的结构变化会更频繁,汉化前最好做好“改一次以后跟着变一次”的心理准备。
2.2 从插件包里取出原始语言文件
FAWE 的语言文件默认打包在插件 jar 包内部。想拿到原始文件,不需要装任何特殊工具,用压缩软件打开 jar 包就行。具体步骤是:
- 先把服务器停掉,再把 plugins 目录下的 FAWE 插件文件完整复制一份出来做备份;
- 用支持 zip 格式的压缩软件打开这份 jar 包,注意是“打开查看”,不是“解压后修改再压回去”;
- 在弹出的目录树里找到存放语言文件的目录。不同版本的存放路径会有些变化,常见的有
lang/、languages/或assets/fawe/lang/,文件名一般是zh_cn.json或strings.json,还有可能按语言代码拆出多个子文件; - 把目标语言文件拖到本地文件夹里,用文本编辑器打开。
注意别用系统自带的那种“压缩文件夹”功能直接修改 jar 内部文件,容易造成 jar 结构损坏。正规做法是提取到本地、修改好、再拖回去覆盖。
2.3 搞清楚汉化文件到底该放哪
FAWE 读取语言文件有两种常见方式:一种是从插件 jar 内部读取打包好的语言文件,另一种是从插件外部的数据目录读取覆盖文件。不同版本对“外部覆盖”的支持程度不一样,最保险的方式永远是“直接修改 jar 包内部的文件”。
具体操作也很直接:用压缩软件打开 jar,在刚才找到语言文件的目录里,把本地改好的文件拖回去覆盖原文件,然后重新启动服务器。如果担心覆盖过程中文件损坏,可以先在本地把修改好的文件重新用 zip 压缩方式打包一个新 jar,再替换整个插件文件。不过整体替换 jar 的方式兼容性风险更高,我个人更推荐只覆盖内部语言文件,其他文件一律不要碰。
3. 完整汉化流程:从翻译到上线
3.1 先收集真实的使用场景,再动手翻译
拿到原始语言文件后,不要一上来就试图把每个条目都翻译一遍,那样既慢又容易脱离实际。更聪明的做法是:先把服务器跑起来,用 FAWE 的命令把高频场景挨个触发一遍,把屏幕上出现的英文原文和上下文记录下来,再回到语言文件里去查这些文本对应的键名。
比如你执行完一条//set指令,反馈里出现了一段描述设置效果的文字,就把这段文字复制下来,在语言文件里搜索,找到对应的键和值,然后你翻译的就只是这一条。这样做的最大好处是,你能保证每个翻译都对得上真实使用场景。有些条目藏在深层错误处理逻辑里,平时根本触发不到,优先级可以往后放。
3.2 翻译质量怎么把握
游戏内反馈文本和正经文档不一样,它需要在极短时间里让玩家看懂意思,所以翻译不能太书面化。我有几个自己坚持的标准:
- 短句优先。能说“没选区域”就不说“您尚未选择任何区域”;
- 保留占位符。很多文本里有
%s、{0}这类变量,翻译时必须原样保留,否则坐标、数量这些参数就显示不出来了; - 语气统一。权限不足这类提示,可以直白但别刻薄,比如“你没有权限这样做”就比“拒绝访问”更像人话;
- 标点符号不要乱换。JSON 里值用什么引号、什么逗号,都有严格语法要求,标点是语法的一部分,不能随手改成中文标点。
我挑几条典型文本做示例,你感受一下翻译尺度的差异:
| 英文原文(示例) | 直译风格 | 推荐风格 |
|---|---|---|
| Region set completed. | 区域设置已成功完成。 | 区域设置完成。 |
| You do not have permission. | 您没有执行此操作的权限。 | 没有权限做这个操作。 |
| Please select a region first. | 请首先选择一个区域。 | 请先框选一个区域。 |
游戏内的命令反馈属于高频、低阅读成本的信息,不追求辞藻,只追求“一眼懂”。
3.3 JSON 语法细节与校验
语言文件本质是 JSON 格式,JSON 的语法要求特别严格,一个标点错了整份文件都可能解析失败。修改时必须遵守几条红线:键名不能改,值里面的双引号和反斜杠必须转义,不允许加注释。占位符要原样保留。文件编码必须是 UTF-8,且不能带 BOM 头。
修改完成后一定要做格式校验。最简单的方式是打开一个支持 JSON 校验的编辑器,或者用命令行验证:
python -m json.tool zh_cn.json如果文件格式没有问题,命令会正常输出整个 JSON 内容;如果哪一行有语法错误,会直接指出行列位置。这一步千万别省,校验一次可能十几秒,但能省掉后面启动服务器后的排查时间。
3.4 放回服务器并应用
把校验通过的文件放回 jar 内部之后,重启服务器。走一遍你常用的命令,确认提示已经变成中文。这里有个容易忽略的点:FAWE 的部分配置可能需要热重载,但语言文件改了之后,最稳妥的还是完整重启一次服务端。重启之后如果发现个别条目还是英文,不要慌,先区分情况——有些条目可能本来就没被插件调用,有些则可能是键名不匹配。
4. 汉化不生效?问题排查实录
4.1 文件路径和文件名大小写
汉化不生效的第一个高频原因,是路径或文件名带大小写问题。插件对语言文件的识别通常区分大小写,zh_cn.json写成了zh-CN.json,或者目录层级差了一层,都会导致插件读不到文件。排查时对照原 jar 包里语言文件的实际路径,一个字母一个字母地比对,别偷懒。
4.2 编码问题导致的中文乱码或解析失败
第二个高频原因出在文件编码上。很多文本编辑器默认保存用了带 BOM 的 UTF-8 或者干脆存成了系统默认编码,插件读取时就可能无法正确解析,表现在游戏里就是整条提示变成乱码,或者插件启动日志里出现parse error、Failed to load language file这类字样。
解决办法:用支持编码选择的编辑器打开文件,另存为时明确选择“UTF-8 无 BOM”格式。保存之后再用校验命令确认一次。
4.3 版本升级导致的汉化文件失效
维护汉化文件最烦的场景,不是第一次翻译,而是版本升级。FAWE 更新之后,语言文件里可能新增了一批键名,你的汉化文件里没有这些键,对应的提示自然就变成了英文;反过来,旧版本里存在、新版本里已经删除的键名,留着也不会生效,但会干扰你查找其他条目。
我的处理方法是每次升级之前,把官方新版语言文件解压出来,和自己维护的汉化文件做一个对比,找出新增键名,只翻译这些新增条目即可。这个过程用可视化对比工具最方便,能直接把两侧差异列出来,看得清清楚楚。
4.4 快速排查速查表
把常见的“汉化不生效”问题整理成一张表,排查的时候照着顺序过一遍,能省很多时间:
| 表现 | 可能原因 | 处理方式 |
|---|---|---|
| 完全没反应,全是英文 | 文件路径放错或大小写不对 | 对照 jar 内原路径重新放置 |
| 部分条目是英文 | 版本不匹配,缺新增键名 | 用新版语言文件补上缺失条目 |
| 中文显示乱码 | 文件编码不是 UTF-8 无 BOM | 另存为 UTF-8 无 BOM 并重新校验 |
| 插件启动日志报解析错误 | JSON 标点或引号错误 | 用 JSON 校验工具检查错误行 |
| 翻译内容替换了但游戏里没变 | 没有重启服务器只做了热重载 | 完整重启一次服务端 |
5. 维护一份属于自己的汉化包
5.1 用 Git 管理翻译进度
汉化文件不是一次性的活,而是一个长期维护的过程。我自己坚持把汉化文件放到代码仓库里管理,每修改一批文本就提交一次,这样每次插件升级、条目变更,都能清楚地看到自己改过什么、什么时候改的、为什么这么改。
哪怕是一个人的项目,版本管理也能带来很大的安全感。某次改崩了,直接回滚上一个提交就行,不用再费劲回忆原本内容是什么。
5.2 简单脚本辅助差异对比
如果插件升级频繁,手动对比两个 json 文件会变得很痛苦。有个小技巧:写个简短的脚本,提取两个文件里的键集合,对比一下就能快速列出新增和删除的键名。思路非常简单,核心就是用程序读取 json 文件,然后把键数组转换成集合做比较。
import json with open("strings_old.json", encoding="utf-8") as f: old = json.load(f) with open("strings_new.json", encoding="utf-8") as f: new = json.load(f) old_keys = set(old.keys()) new_keys = set(new.keys()) print("新增条目:", len(new_keys - old_keys)) for key in sorted(new_keys - old_keys): print(key)这样每次升级后,把新旧语言文件分别放好,脚本一跑,缺哪些条目一目了然。翻译新增条目时,也不用再担心漏掉哪个犄角旮旯的功能提示。
5.3 自己动手汉化过程中的几点经验
最后分享几个实际操作中的小体会。
第一,不要试图一次把上千条全部翻译完。很多条目只有在很冷门的命令里才会出现,翻译它们性价比太低。我习惯优先保证高频命令、错误提示、权限反馈这些核心内容的翻译质量,冷门条目先用机器翻译顶一下,等真遇到了再回去精修。
第二,命令帮助菜单的翻译值得重视。玩家对命令的认知基本来自帮助菜单,那些“describe”字段如果完全是英文,玩家根本猜不到命令的使用方式,这直接关系到 FAWE 能不能被玩家真正用起来。
第三,频繁备份。改汉化文件这个操作本身不危险,但手滑删掉半个括号、改错一个键名这种事,谁都会遇到。备份一份原始语言文件在本地,就算改烂了也能瞬间恢复,不慌。
说实话,FAWE 的汉化工作技术上并不难,真正考验人的是耐心和持续维护。只要第一次把流程跑通,建立了自己的汉化文件管理习惯,每次插件升级后花十几分钟收尾一点,后面的维护成本会越来越低。这些看起来琐碎的文本调整,对服务器里普通玩家的体验提升,其实是立竿见影的。