让译文直接写进游戏内存:LunaTranslator 内嵌翻译开启、乱码与卡顿一次讲清
【免费下载链接】LunaTranslator视觉小说翻译器 / Visual Novel Translator项目地址: https://gitcode.com/GitHub_Trending/lu/LunaTranslator
LunaTranslator 内嵌翻译(Embedded Translation)是这款视觉小说翻译器面向 Galgame 最硬核的功能:它不依赖翻译器自己的悬浮窗口,而是在游戏显示文字之前,直接把译文写回游戏进程的内存,让译文像原生文本一样出现在游戏画面里。效果是「沉浸感拉满」,代价是两点你需要提前知道:并非所有游戏都支持内嵌,且内嵌存在一定概率导致游戏崩溃。下文按「能不能用 → 怎么开 → 开了之后乱码/卡顿怎么办 → 还有哪些开关」的路径,把官方文档 docs/cht/embedtranslate.md 和 texthook.py 中的实现一次讲透。
一、内嵌翻译到底做了什么:一条「停住游戏」的内存改写链路
先分清两个概念:
- 外挂翻译:LunaTranslator 通过 Hook(钩子)截获游戏文本,只在翻译器窗口里展示译文,游戏进程完全不受影响;
- 内嵌翻译:游戏在渲染文字之前先「停下来」,等翻译器给出译文,把内存里的待显示文本替换成译文后再继续运行——玩家看到的就是译文本身。
从源码可以还原出完整链路(均在 src/LunaTranslator/textio/textsource/texthook.py):
- 标记可内嵌的 Hook 点:
newhookinsert(第 553-564 行)检查当前 Hook 代码是否在该游戏的embedablehook(可内嵌 Hook 列表)中,命中就调用Luna_UseEmbed(tp, True)把这条线程标记为内嵌模式。 - 暂停游戏线程:游戏显示文字前触发内嵌回调,待显示文本经
EmbedCallback(第 260 行注册的getembedtext)进入 Python 侧,此时游戏线程处于阻塞状态。 - 取译文:
getembedtext内部调用waitfortranslation(text)(第 579 行)等待翻译结果。 - 完整性校验:
__safechecktransresult(第 566-573 行)会比对原文与译文中的[...]、{...}等占位标记,一旦译文弄丢了游戏文本结构标记,本次译文直接作废(写空串),防止破坏游戏文本。 - 写回内存:处理后的译文经
Luna_EmbedCallback(第 590 行)写回,游戏继续执行并显示译文。
这就是内嵌翻译卡顿的根源:第 2~4 步期间游戏线程是被停住的。你的翻译引擎如果是远程 API 或本地大模型,返回慢一点,游戏画面就「冻住」一点——这不是 bug,是内嵌的固有机制。后文会用「翻译等待时间」开关来给这种等待设上限。
二、先判断你的游戏能不能用,再决定怎么开
2.1 「选择文字」里有没有「内嵌」栏,是唯一的判断标准
没有「内嵌」这一栏 = 该条目不支持内嵌,无需尝试。这个标记来自 Hook 发现机制:onnewhook(第 674 行起)的签名里带有isembedable参数,宿主进程在发现新 Hook 点时会告知 Python 侧该点是否可内嵌,并同步反映在选择文字的对话框中。
2.2 「显示」与「内嵌」可以任意组合
对支持内嵌的条目,三个组合各有用途:
| 组合 | 效果 |
|---|---|
| 只开「显示」 | 常规外挂模式,译文显示在翻译器窗口 |
| 只开「内嵌」 | 译文只写进游戏画面,翻译器窗口不显示任何内容 |
| 两者同开 | 游戏内嵌入译文,窗口里还能额外展示读音、双语对照等学习内容 |
2.3 内嵌配置:全局一份,还是每个游戏各调各的
embedconfig属性(第 113-125 行)实现了两级作用域:
embed_follow_default为 True 时,读取全局配置globalconfig["embedded"];- 关闭「跟随默认」后,读取该游戏私有的
embed_setting_private,没单独设置的项会自动回落到全局默认值。
对应界面入口在游戏管理器的「内嵌翻译」页签(setting.py 第 1370-1395 行),那里还维护着「已激活的」可内嵌 Hook 列表,可以对特定 Hook 点单独禁用内嵌。换句话说:不同引擎、不同编码的游戏可以各存一套互不干扰的内嵌参数,排障时建议就用这个能力,把问题隔离在单个游戏内。
三、内嵌翻译乱码排查:先分清是「字符集」还是「字体」
这是玩家问得最多的问题。官方文档给了一条核心原则:乱码一般分字符集和字体两类,大多数情况是字体问题。按引擎年代和语言对号入座即可:
- 英文游戏(及部分 Unicode 新引擎游戏)→ 大概率缺中文字体。这类游戏自带字体不含中文字形,译文写进去就渲染成方块。解法:开启「修改游戏字体」(源码对应
changefont开关 +changefont_font字体名),选一款系统已安装、支持中文的字体(宋体、微软雅黑等)。 - 古早日式 Galgame → Shift_JIS 字符集问题。老游戏用自建的 Shift_JIS 字符集处理文本,根本编码不了中文字符,换字体无效。解法:开启「将汉字转换成繁体/日式汉字」,对应
trans_kanji(第 584-585 行),处理链路是zhconv.convert(trans, "zh-tw")先转繁体,再经 kanjitrans.py 中的kanjichs2ja映射表(约 469 条,如「谈→談」「挂→掛」)替换为日式汉字写法,从而避开与 Shift_JIS 的冲突。若你的游戏不开这个选项就能正常显示简体中文,那就不用开。 - Unicode 引擎(KiriKiri 吉里吉里、Ren'Py、TyranoScript、RPG Maker MV 等)→ 基本是字体问题。这些引擎用 UTF-8 / UTF-16,字符集能装下中文,出现乱码时按「修改游戏字体」处理即可。
- Unity 引擎 → 多一步 SDF 字体的特殊处理。当引擎是 Unity 且开启了「修改游戏字体」时,
find_unity_font_dir(第 646-651 行)会自动遍历游戏目录、定位包含arialuni_sdf_u字体资源的目录并回传宿主,用于正确处理 Unity 的 SDF 动态字体。玩 Unity 游戏时若内嵌译文显示异常,优先确认字体设置是否真正生效。
四、配置速查表:七项内嵌开关的默认值与适用场景
所有设置项通过embedconfig读取,并由set_settings_ex(第 614-644 行)统一打包下发到宿主进程:
| 配置项 | 参数名 | 默认值 | 什么时候用它 |
|---|---|---|---|
| 显示模式 | displaymode | 0 | 默认不在译文与原文之间加换行;若游戏能容纳多行,可在「翻译优化 → 翻译结果修正」里加一条正则,在译文前插入换行实现分行 |
| 翻译等待时间 | timeout_translate | 2 秒 | 限制阻塞等待的上限(下发时 ×1000 转毫秒);慢翻译引擎建议调低,高速本地翻译可适当调高 |
| 汉字转繁体/日式汉字 | trans_kanji | 关 | 兼容古早日式游戏的 Shift_JIS,减少乱码 |
| 限制每行字数 | limittextlength_use+limittextlength_length | 关 / 40 字符 | 防止长译文溢出文本框。splitembedlines(第 592-612 行)按目标语言分隔符(中文逐字、英文按空格)切词重排,保证每行不超宽 |
| 修改游戏字体 | changefont+changefont_font | 关 | 解决缺中文字体导致的方块/乱码 |
| 字体相对大小 | changefontsize_use+changefontsize | 关 / 1.0 | 换字体后等比缩放字号,修正过大溢出或过小难读 |
| 清除原文 | clearText | 关 | 把游戏内原文清空,三个典型场景见下 |
关于「清除原文」,官方文档列了三种经典玩法:
- 伪装内嵌:字符集/字体实在救不回来的游戏,清掉原文后把翻译器窗口拖到原文字区域上方覆盖,视觉上等于内嵌;
- 避免遮挡:外挂窗口放在文字区会重叠原文、放在别处又挡画面,不如直接清原文,窗口爱摆哪摆哪;
- 纯学习模式:只学日文时清掉原文,窗口里留下的读音、双语对照更干净。
五、风险与日常排障清单
- 崩溃是已知风险:内嵌涉及对游戏进程内存的「暂停-改写-恢复」,个别游戏/引擎可能因此崩溃。内嵌不稳定的游戏退回外挂模式即可,不必强求。
- 卡顿属正常现象:慢翻译 = 游戏冻屏。缓解手段就是调低「翻译等待时间」,超时后本次内嵌直接放弃(游戏继续跑,显示原文),换来流畅度。
- 译文被莫名清空:多半是原文带
[...]、{...}一类标记,而翻译引擎把它们弄丢了,被__safechecktransresult兜底拦下——这是保护机制在工作,可检查译文里的标记是否完整。 - 多游戏各自为政:用「跟随默认」开关 + 私有配置,为每个引擎/编码的游戏单独调参,排障时先固定变量,再逐个开关试验。
延伸阅读
- Hook 与文字提取设置:特殊码与可内嵌 Hook 的判定机制
- 翻译优化与翻译结果修正:用正则给译文加换行的具体写法
- 文本处理流程:译文后处理管线
- 模拟器游戏支持:模拟器环境下内嵌的额外注意事项
- 常见问题 FAQ:更多内嵌翻译排错经验
【免费下载链接】LunaTranslator视觉小说翻译器 / Visual Novel Translator项目地址: https://gitcode.com/GitHub_Trending/lu/LunaTranslator
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考