LunaTranslator 内嵌翻译(Embedded Translation)完全指南:工作原理、使用流程与乱码排查实战
2026/9/15 17:34:20 网站建设 项目流程

LunaTranslator 内嵌翻译(Embedded Translation)完全指南:工作原理、使用流程与乱码排查实战

【免费下载链接】LunaTranslator视觉小说翻译器 / Visual Novel Translator项目地址: https://gitcode.com/GitHub_Trending/lu/LunaTranslator

内嵌翻译是 LunaTranslator 中一种特殊的文本输出方式:它不是把译文显示在翻译器自己的窗口里,而是直接修改游戏进程内存中的文本,让译文“内嵌”到游戏画面原本显示原文的位置,实现接近原生汉化的效果。本篇指南以仓库内 内嵌翻译文档(英文版见 docs/en/embedtranslate.md)为主线,结合 texthook.py 与 textinput.py 的源码实现,系统讲解内嵌翻译的支持性判断、启用方法、全部设置项参数,以及最常见的乱码问题的排查与修复思路。读完本文,你将能独立完成从“选择内嵌文本条目”到“调整字体与编码解决乱码”的完整实战流程。

内嵌翻译是什么:从源码看它的工作原理

在深入操作之前,先理解内嵌翻译的底层机制,有助于你判断它为什么会出现卡顿、乱码等现象。根据 texthook.py 中getembedtext的实现,内嵌翻译的完整流程可以概括为:

  1. 游戏暂停:LunaHost 注入游戏后,会在游戏准备显示文本的某个函数处停住游戏线程,把即将显示的原文通过EmbedCallback回调(源码中注册为self.getembedtext)发送给翻译器主程序;
  2. 等待翻译:主程序调用waitfortranslation(text)把文本交给翻译引擎,并阻塞等待翻译完成返回;
  3. 结果校验:源码中的__safechecktransresult会检查原文与译文中的方括号[...]、花括号{...}标记是否一一对应,若不一致则丢弃翻译结果,避免把游戏自身的控制符破坏掉;
  4. 写入内存:翻译完成后调用Luna_EmbedCallback(tp, text, trans),把译文写回游戏进程内存中该文本对应的位置,随后放行游戏继续运行,游戏画面便直接显示出译文。

因为游戏在这整个过程中是“停住等你翻译”的,所以文档中强调了一个关键结论:当使用的翻译速度较慢时,一定会导致游戏卡顿。这也是“翻译等待时间”这一设置存在的根本原因(详见下文设置详解)。

此外,从 selecthook.py 可以看到,是否对某个文本条目启用内嵌,是通过Luna_UseEmbed(tp, use)这个 DLL 接口动态切换的,而不是固定配置——这也解释了为什么你可以在运行中随时打开/关闭某个条目的内嵌开关。

支持性判断与启用方法

不是所有游戏都支持内嵌

文档开篇就给出了两个明确警告:

  • 不是所有游戏都支持内嵌。内嵌翻译依赖对游戏特定显示函数的 HOOK 和内存修改,只有被 LunaHook 识别为“可内嵌”的文本线程才具备该能力;
  • 内嵌有一定概率导致游戏崩溃。修改游戏内存本身带有风险,使用时应有心理预期,必要时先存档。

判断方法很直观:在选中文本时,如果条目右键菜单(或对应面板)中没有“内嵌”这一行选项,就说明该游戏不支持内嵌。这与源码中的embedablehook机制对应——只有被标记为可内嵌的 HOOK 线程才会在界面中渲染出内嵌开关(参见 selecthook.py 中对embedablenum与内嵌开关的动态增减逻辑)。

显示与内嵌:两种开关的自由组合

对于支持内嵌的文本条目,“显示”和“内嵌”是两个相互独立的开关,可以随意组合:

组合方式效果
同时开启“显示”+“内嵌”游戏画面内内嵌译文,同时翻译器软件窗口也正常显示翻译内容(原文/译文列表等),信息量最大
只开启“内嵌”仅在游戏内显示译文,软件窗口不显示任何内容,画面最干净

这种设计让你可以根据个人习惯选择:想要对照学习可以两者都开,追求沉浸式体验可以只开内嵌。

启用步骤

  1. 启动游戏并让 LunaTranslator 完成 HOOK(参见 HOOK 设置文档);
  2. 选中支持内嵌的文本条目,确认其菜单中存在“内嵌”选项;
  3. 激活“内嵌”开关,必要时同时激活“显示”;
  4. 观察游戏画面内是否出现译文,按需进入下方“内嵌翻译设置”调整细节。

乱码问题排查:字符集问题还是字体问题

开始内嵌翻译后,最常遇到的现象就是乱码。根据文档,游戏乱码一般只来自两种原因:字符集(编码)问题字体问题。排查思路可以按游戏类型快速分类。

字体问题:英文游戏的主流原因

对于英文游戏,乱码通常是因为游戏缺少中文字体。游戏字体表里没有中文字形,自然无法渲染译文中的汉字。此时需要:

  1. 激活“修改游戏字体”设置项;
  2. 选择一个包含中文字形的合适字体(如常见的宋体、黑体类字体);
  3. 字体修改完成后,中文即可正常显示。

需要说明的是,即使游戏本身使用 UTF-8 等 Unicode 编码,只要缺字体依然会乱码——字体缺失与编码是否正确是两个独立维度

字符集问题:古早日系 Galgame 的特殊情况

对于许多古早日本 Galgame,它们使用自己内置的Shift-JIS 字符集处理文本,无法正确处理中文字符,此时可以尝试开启“将汉字转换成繁体/日式汉字”来减少乱码出现——繁体/日式汉字与 Shift-JIS 字符集的兼容性通常更好,能显著降低乱码比例。

现代引擎:优先怀疑字体

对于较新的游戏引擎和大部分英文游戏,一般使用 UTF-8 或 UTF-16 等 Unicode 字符集,常见的如:

  • KiriKiri(吉里吉里)
  • Renpy
  • TyranoScript
  • RPGMakerMV

这类游戏即使出现乱码,一般也是字体问题而不是字符集问题,优先按“修改游戏字体”的思路处理。

简体中文显示异常的补充手段

“将汉字转换成繁体/日式汉字”这个开关默认是关闭的,关闭状态下可以正常显示简体中文。但对于部分无法正常显示简体中文的游戏,可以尝试激活该选项,看能否恢复为正常显示——也就是说,这个开关既可能用来解决 Shift-JIS 乱码,也可以作为简体中文显示异常的备选方案。

内嵌翻译设置详解:逐项参数与源码对照

内嵌翻译的设置项在界面中集中呈现,其界面定义位于 gethookgrid_em。这些设置既可以在全局配置中修改,也可以针对单个游戏/条目单独覆盖(配置存储机制见下文“配置存储结构”一节)。下面逐项说明,并附上源码中的参数范围与默认值。

1. 显示模式

由于游戏能显示的文本行数有限,默认情况下翻译与原文之间不会插入换行(即默认只显示译文本身)。如果确认游戏文本区域有足够空间容纳多行,可以通过“翻译优化翻译结果修正”添加一条正则表达式,在翻译前面插入一个换行来实现分行显示。

该设置对应源码中的displaymode参数,可选值有三种:

取值含义
0仅翻译
1原文_翻译(原文在上,译文在下)
2翻译_原文(译文在上,原文在下)

默认值为0。关于“翻译结果修正”的完整用法(如何添加正则、替换规则等),可参考 翻译优化文档 及其实现 transerrorfix.py。

2. 翻译等待时间

这是内嵌翻译最重要的防卡顿参数。如“工作原理”一节所述,内嵌翻译会让游戏暂停等待翻译结果,因此翻译越慢,游戏卡顿越久。通过限制等待时间上限,可以避免翻译过慢导致长时间卡顿:当等待超时后,游戏会放弃本次内嵌并继续运行。

  • 源码参数名:timeout_translate
  • 取值范围:0~30(秒),支持小数
  • 默认值:2(秒)
  • 底层实现:该值在 set_settings_ex 中会被乘以1000转换为毫秒,通过Luna_SettingsEx传入 LunaHost,由宿主 DLL 控制超时逻辑。

如果你的翻译引擎(尤其是大模型类引擎)响应较慢,建议根据实际体验适当调大该值,但要接受游戏卡顿时间随之变长的代价。

3. 将汉字转换成繁体/日式汉字

即文档与源码中反复提到的trans_kanji开关,默认关闭。开启后,译文会先通过zhconv.convert(trans, "zh-tw")转换为繁体中文,再经过kanjitrans进一步转换为日式汉字(参见 getembedtext 与 kanjitrans.py)。

适用场景已在“乱码排查”一节详述:主要用于 Shift-JIS 字符集的古早日系游戏,也可作为简体中文显示异常的备选方案。注意该转换是在译文上进行的,不影响原文显示。

4. 限制每行字数

有些游戏每行能显示的字符数是有限的,超出长度的内容会显示到文本框右侧更外边而无法看到。该设置通过手动分行来避免这一情况。

  • 开关参数名:limittextlength_use,默认关闭
  • 长度参数名:limittextlength_length,取值范围0~1000,默认40

其分行算法实现在 splitembedlines 中:先按原文语言的空格规则切分单词,再按长度限制重新拼接换行,对于无空格分隔的语言(如中日文)则按字符长度直接截断。该处理作用于译文文本,在写回游戏内存前完成。

5. 修改游戏字体

对应changefont开关(默认关闭)与changefont_font字体选择。开启后,LunaHost 在渲染内嵌文本时会强制替换游戏使用的字体,从而让缺少中文字形的游戏正确显示汉字。选择字体时,请挑选明确包含中文字形的字体。

特别地,对于Unity 引擎游戏,源码中有专门的逻辑:开启changefont后,set_settings_ex 会调用find_unity_font_dir尝试自动定位 Unity 的字体资源目录,并把该目录路径一并传给 LunaHost,以更可靠地完成字体替换;selecthook.py 中也有对应提示逻辑。

6. 修改游戏字体相对大小

当替换字体后,字号可能偏大或偏小、与原文排版不协调,可开启该设置微调。

  • 开关参数名:changefontsize_use,默认关闭
  • 缩放参数名:changefontsize,取值范围0.5~2,步进0.01,默认1.0(即不缩放)

该值通过Luna_SettingsEx传入宿主,由宿主在渲染时对字体大小做相对缩放。

7. 清除游戏内显示的文字

该开关对应源码中的clearText参数(默认关闭)。激活后,游戏内将要显示内嵌文本位置处的原文内容会被清空。文档给出了该选项可能满足的三类需求:

  1. 伪装内嵌效果:当内嵌翻译遇到无法解决的字符编码和字体显示问题时,开启该选项,然后把软件窗口覆盖到原本游戏中显示文字的位置,即可看起来像是内嵌翻译的效果(此时译文实际由软件窗口渲染);
  2. 外挂翻译的更优布局:当使用外挂翻译(窗口显示译文)时,若把窗口放在文字区会和原文本重叠、放在其他地方会遮挡画面,此时清空游戏原文后,把窗口放在文字区即可避免重叠;
  3. 日语学习场景:只想用游戏来学习日语,但游戏文本没有加注音或双语对照功能时,可以清空原文,再用软件窗口显示带注音或双语对照的内容。

本质上,该选项让你在“内嵌”与“外挂”两种形态之间获得更灵活的混合使用方式。

配置存储结构:全局默认与单条目私有配置

从源码 embedconfig 的实现可以看出,内嵌设置遵循“全局默认 + 条目私有覆盖”的两级结构,这与普通 HOOK 设置的hooksetting_follow_default机制一致:

  • 全局默认配置:存放在globalconfig["embedded"]中,即 defaultconfig/config.json 里的"embedded": {}字段(默认全为空,即全部使用界面上的内置默认值);
  • 条目私有配置:存放在 config.py 中定义的embed_setting_private: {}字段;
  • 开关embed_follow_default(默认True)控制当前条目是否跟随全局默认;关闭后启用私有配置,且私有配置中未显式设置的键会自动回落到全局值(源码中通过自定义 dict 的__getitem__实现);
  • 每个游戏记录中还维护embedablehook列表,用于标记该游戏下哪些 HOOK 线程支持内嵌。

这套设计意味着你既可以在全局设置里统一调优内嵌参数,也可以针对某个特定的卡顿/乱码条目单独覆盖设置,互不干扰。

实战建议与注意事项

综合文档与源码,给出几条实操建议:

  1. 先存档再开启内嵌:内嵌翻译有一定概率导致游戏崩溃,重要进度前先存档;
  2. 乱码先分类再动手:英文/现代引擎游戏优先查字体(开启“修改游戏字体”),古早日系 Shift-JIS 游戏优先尝试“转换繁体/日式汉字”;
  3. 慢翻译引擎务必设置等待时间上限:如果你用的是响应较慢的在线翻译或大模型翻译,timeout_translate是防止游戏长时间卡死的保命设置,建议从默认的 2 秒开始按体验调整;
  4. 多行显示依赖正则:默认译文与原文之间无换行,需要双语对照时,请在“翻译结果修正”中添加插入换行的正则,并确认游戏文本区域有足够空间;
  5. 善用“清除游戏内显示的文字”:遇到内嵌无法解决的编码/字体问题时,不要死磕,切换为“清除原文 + 软件窗口覆盖”的混合方案往往更省事;
  6. 单条目覆盖配置:某个特定条目的内嵌效果不理想时,优先尝试为其关闭embed_follow_default并单独设置,避免影响全局体验。

延伸阅读

  • 内嵌翻译官方文档(中文) / 英文 / 日文 / 韩文
  • HOOK 与文本线程选择:理解哪些线程可被 HOOK、如何选中目标文本
  • 翻译优化与翻译结果修正:添加正则实现译文换行、结果修正的完整方法
  • 文本处理相关配置:文本过滤、预处理等与内嵌翻译联动的配置
  • 核心源码:texthook.py(内嵌流程与设置下发)、textinput.py(设置界面定义)、selecthook.py(内嵌开关交互)

【免费下载链接】LunaTranslator视觉小说翻译器 / Visual Novel Translator项目地址: https://gitcode.com/GitHub_Trending/lu/LunaTranslator

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询