个人游戏技术选型案例:本地化管线为什么要先处理字体和文本长度

一个个人叙事游戏在本地化技术管线、字体、文本长度、术语表和构建校验之间做技术选型的案例,详细讨论多语言发布前的真实工程问题。

写在前面:本地化不是把文本交给翻译

很多个人开发者谈本地化时,第一反应是:

把中文导出来。
找译者。
导回英文、日文、德文。
然后上线。

真正做过一次后才会发现,本地化首先是工程问题。

文本从哪里来?
字体能不能显示?
UI 是否会溢出?
术语是否一致?
构建时能不能发现缺翻译?
玩家切语言后存档、成就、教程提示会不会出错?

苏沅做过一款小型叙事经营游戏。
玩家经营一间夜间照相馆,为路过的客人拍摄证件照、遗照、纪念照,并从照片背后的留言里了解他们的故事。

游戏中文文本约 8 万字。
她计划首发中文和英文,发售后三个月加入日文。

最早她以为本地化只是内容工作。
后来在 Demo 测试时,英文版 UI 大面积溢出,部分字体缺字,存档里还保存了中文任务名,导致切换语言后任务列表混乱。

她最终重做了本地化技术管线。
这个决定让正式版多语言发布稳了很多。

一、先把文本从代码和场景里拿出来

项目早期,苏沅的文本分散在很多地方:

  • 对话脚本里有角色台词
  • UI Prefab 里写着按钮文字
  • 任务系统里保存任务名称
  • 教程提示写在触发器组件上
  • 成就描述写在平台后台
  • 图片里嵌着少量中文标题

这在单语言原型阶段很快。
但一旦多语言,就会变成灾难。

她做的第一步是建立文本 ID。

例如:

  • ui.confirm
  • ui.cancel
  • quest.photo_album_01.title
  • dialogue.mei.entrance.003
  • tutorial.camera.focus

游戏运行时不直接使用中文文本,而是通过 ID 查当前语言。

这带来一个重要变化:
存档不再保存“寻找旧相册”,而是保存 quest.photo_album_01 和任务状态。

语言切换后,任务名称由本地化表重新显示。

二、为什么不用散落的 JSON 文件

苏沅考虑过每种语言一个 JSON 文件。

比如:

  • zh-CN.json
  • en.json
  • ja.json

小项目这样可以。
但她的文本量不小,而且需要译者和校对一起工作。

JSON 对程序友好,但不适合非技术人员长期编辑。
换行、引号、逗号、转义字符,都容易出错。

她最后选择表格作为源数据,构建时生成游戏使用的 JSON。

表格字段包括:

  • id
  • context
  • speaker
  • zh_cn
  • en
  • ja
  • max_width
  • note
  • status

其中 contextnote 对翻译非常重要。

例如“冲洗”在照相馆里可能是冲洗照片,不是冲洗杯子。
如果不给上下文,译者很容易选错词。

三、字体方案要提前验证

本地化最容易被拖到后面的,是字体。

中文字体能显示中文,不代表能覆盖日文假名、日文汉字、拉丁扩展、标点和特殊符号。
英文字体漂亮,也不代表支持重音字符。

苏沅做了一个字符收集脚本。

它扫描所有语言文本,输出实际使用字符集合。
然后检查当前字体是否覆盖。

第一次检查时,她发现:

  • 英文译文里有弯引号和长破折号
  • 法语媒体引用里出现重音字符
  • 日文测试文本里有几个字体缺字
  • UI 图标字体缺少手柄按键符号

这些问题如果发售后才出现,就会变成玩家截图里的方块字。

她最终方案是:

  • 中文使用一套 CJK 字体子集
  • 英文使用单独拉丁字体
  • 日文首发前生成日文子集
  • 图标符号使用独立 sprite atlas
  • 构建时检查缺字

字体子集让包体可控。
构建检查让缺字不会混进发布包。

四、文本长度不是 UI 的小问题

英文通常比中文长。
德文可能更长。
日文有时短,但换行规则不同。

苏沅在英文 Demo 里遇到最明显的问题:

“开始营业”变成 “Open for the Night”,按钮直接溢出。
“查看相册”变成 “Review Photo Album”,菜单布局被撑开。

她没有要求译者硬压短每一句。

而是从 UI 方案上处理:

  • 按钮给出最小宽度和最大宽度
  • 长文本允许换行
  • 部分 UI 使用图标加短标签
  • 任务描述区域改成可滚动
  • 对话框按语言调整行高
  • 构建时检测超出 max_width 的文本

表格里的 max_width 字段就是给校验用的。

如果某条翻译超过指定宽度,构建脚本会报 warning,并截图标记对应 UI。

个人游戏不一定能做完整自动截图测试。
但至少要在导入阶段知道哪些文本可能溢出。

五、术语表比后期校对更便宜

照相馆游戏里有很多固定词:

  • 底片
  • 暗房
  • 显影液
  • 证件照
  • 遗照
  • 相纸
  • 预约单

苏沅一开始让译者自由处理。
结果同一个“底片”在不同地方出现了 negative、film、plate 三种译法。

不是译者水平差。
而是没有术语表。

她后来建立 terms 表:

  • 中文词
  • 英文固定译法
  • 日文固定译法
  • 使用场景
  • 禁用译法
  • 备注

导入脚本不会强制替换术语,但会扫描译文,发现禁用词或疑似不一致时提示。

这对叙事游戏很有用。

术语一致会让世界观显得稳定。
术语混乱会让小项目显得粗糙。

六、图片文本尽量减少

苏沅早期有一些美术图直接写中文:

  • 店门招牌
  • 相册封面
  • 旧报纸标题
  • 教程示意图

这些很有氛围,但多语言成本高。

她没有全部删掉。
而是分三类处理:

第一类是世界内固定文字,比如店名。
保留中文,作为美术风格的一部分。

第二类是玩家必须理解的信息,比如教程图。
改成可本地化 UI 文字。

第三类是可选氛围文本,比如旧报纸。
如果重要,就做多语言贴图;如果不重要,就避免玩家必须阅读。

这个取舍避免了大量重复美术资产。

个人游戏做本地化时,不要随手把关键信息烘进图片。
后期会非常贵。

七、构建校验是最后一道线

苏沅的构建脚本会检查:

  • 是否有缺失 ID
  • 是否有重复 ID
  • 当前发布语言是否缺翻译
  • 字体是否缺字
  • 是否有超宽文本 warning
  • 是否存在未本地化的 UI 文本
  • 是否有存档字段直接保存显示文本

构建失败不一定阻止所有 warning。
但正式发布包不能有 error。

这让本地化问题从“玩家发现”提前到“开发者构建时发现”。

结语:多语言发布靠的是管线,不是临时加班

苏沅的最终方案并不复杂:

  • 文本 ID 化
  • 表格作为源数据
  • 构建时生成 JSON
  • 字符集扫描和字体子集
  • UI 文本长度校验
  • 术语表
  • 图片文本分类处理
  • 存档只保存 ID 和状态

它花了两周时间搭建。

但这两周避免了发售前一个月的混乱。

个人游戏做本地化,最重要的不是一开始支持十种语言。
而是从第一种外语开始,就让文本、字体、UI、存档和构建流程站在正确的位置。

翻译可以外包。
本地化管线必须由开发者负责。

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页