赛博朋克双语字幕模组(附加英文)

赛博朋克双语字幕模组(附加英文)

这个模组将游戏中除英语外的所有语言的本地化文本都附加上了英语。最终效果是,你可以获得双语字幕,同时游戏界面本身也是双语的,包括游戏中的可交互电脑、扫描、游戏内电话、百科、角色界面等等。

赛博朋克2077 双语字幕模组(英文追加版)

最新更新 (1.4.3):

1.4.2 的后续更新。有用户反映中文字幕中的英文字幕缺少带重音符号的字母——比如 Capitán 显示成了 Capit n,重音符号的位置变成了空洞。经查实,这是字体问题而非文本问题,并且在排查过程中还发现了其他一些显示问题。现已全部修复:

  • 重音字母显示为空白—— é、á、ō、è 等。游戏为每种语言都配备了不同的字体,其中有几种字体根本没有这些字母的字形,导致它们无法显示。中文、日文、韩文和阿拉伯文都受到影响,各有不同的表现形式。现在英文部分在对应语言字体无法绘制重音字母时会使用普通字母替代。
  • 中文中撇号后面看起来像多了一个空格—— 显示为 Wasn' t 而非 Wasn't。同一个根源,不同症状:中文字体将弯引号绘制为全角宽度,因为它同时也用作中文引号。
  • 扫描敌人时显示多余字符—— 显示为 건달 ₩nThug 而非 건달 Thug。该组件不支持换行,因此把换行符本身打印了出来。在韩文中显示为韩元符号,因为韩文字体将反斜杠绘制为该符号。
  • 角色面板(公司人、等级、街头声望、最高等级)和专长界面(需要、技术能力)上标签重叠,以及快速破解状态图标被截断。
  • 电台重复打印频率—— 92.9 夜氏 FM / 92.9 Night FM 现在只显示一个。

重音修复是比较有意思的部分。该版本不再猜测需要替换哪些字母,而是直接读取游戏自带的字体文件,精确计算出每种语言可以绘制和不能绘制哪些字符。这意味着每种语言只会失去它本来就无法显示的带重音字母——俄语和泰语显示正常,因此完全不受影响;日语保留其 á 而失去 è,因为其字体实际包含的正是这些字符。此外还新增了一项检查,如果任何语言出现了其字体无法渲染的文本,模组将拒绝打包。

特别感谢 KB52 的原始报告和截图——这个问题从外面完全看不出来,没有这些截图的话,我可能会认为是文本损坏了而不是字体不完整。

上一个版本 (1.4.2)

修复了五个单独的问题:任务字幕中英文显示两次、说话人标签和NPC姓名重复打印(如 小麦克 Tiny Mike: 小麦克 Tiny Mike:)、男性V被称呼为女性V、游戏内部的 <kiroshi><mothertongue> 标记直接显示在屏幕上,以及名字被拆成两行。其中只有第一个是1.4.1中新增的问题——其余的在1.4或更早版本中就已存在。再次感谢 Mayonaka193saejimasanlerufus86hughswordsTASKFORCCEWINDYToricly 的报告。

如果你仍在使用1.4或1.4.1版本,请务必更新——尤其是1.4版本,它比看起来的问题更严重,它包含了1.4.2中三个问题的更严重形式。

如果你想了解这些问题的具体原因,请查看底部的“详情/经验教训”部分。

我是一名业余语言爱好者,经常学习韩语。当《往日之影》发布时,我再次沉浸到赛博朋克2077中,一直想着如果游戏能有类似 Language Reactor 那样的双语字幕就好了。所以我研究了一番并制作了这个模组。

我该下载哪个版本?

有两个文件:

  • Dual Language Subtitles English Appended(双语字幕英文追加版) —— 字幕 游戏界面(电脑、扫描、电话、数据库、菜单、物品名称等)均包含。这是完整体验,也是大多数人所需要的。
  • Dual Language Subtitles Only English Appended(仅双语字幕英文追加版) —— 仅字幕,界面保持为你选择的语言。如果你只关心对话,或者觉得界面文本重复过于杂乱,请选择这个。

只需要下载其中一个,不需要两个都装。

如何安装和使用?

就像其他模组一样,把它放到游戏模组目录中的 mods 文件夹里并启用模组。然后在游戏设置中进行2项操作即可(注意:有玩家说放到 archive/pc/mod 文件夹也可以,似乎不需要 redmod)。

将字幕语言设置设置为英语以外的任何语言,所有非英语语言都将在其后追加英文。

如果你还希望游戏界面(电脑、眼睛扫描、电话、物品名称、菜单等)也具有同样效果,还需要将界面语言更改为英语以外的任何语言,这将加载界面本地化。

注意:这两项设置需要在主菜单中完成,不能在加载存档后进行,否则选项将不会显示。

祝学习愉快!

注意: UnforgivenWar 在评论中向我推荐了这个暂停模组,它与本模组配合得很好。你可以通过 CyberEngineTweaks 和 Pause 模组绑定一个按键来随时暂停时间,这样在需要时就可以有充足的时间阅读较长的对话。

详情/经验教训(供有兴趣者参考)

好的,我之前从未给赛博朋克做过模组,这算是一个比较小众的模组,但它是我非常想要的……所以我玩了一下模组工具,算是摸索出来了。我很懒,用ChatGPT写了最初的脚本,而最费力的部分则在于根据游戏处理这些东西的方式来判断什么有效什么无效。

对于1.4.2版本,我同时使用了 Claude Code 和 ChatGPT Codex 进行协作,说实话,这种搭配是这次发布能发现5个错误而非1个的唯一原因。它们一直在互相检查工作——Codex 追踪到了说话人姓名重复的根本原因,Claude 随后发现这不是1个模板而是28个模板;之后 Codex 审查了 Claude 的性别修复实现,提出了6个问题,全部正确。它们都无法单独做到这一点,我也不可能凭手工在18种我大多看不懂的语言中找到这些。

所以这个模组的工作方式是将英文追加到游戏中的其他语言字幕/界面本地化信息中,这样你就可以同时看到两种语言。

好的方面? 如果你正在学习另一种语言并且想要这个功能,它至少能满足你,只是偶尔有些小问题。

不好的方面? 有数千个 json 文件需要修改,在这些数千个文件中又有成千上万行文本。所以不可能在短时间内手动完成,必须使用脚本。话虽如此,我使用的追加文本的方法大多数情况下都能正常工作,但还是有些零碎的小问题。

主要的限制是有些文本框本身就不是为容纳那么多文本而设计的,会出现一些文本截断问题。作为学习其他语言的人,我可以完全无视这一点,因为大多数情况下我能获得我关心的功能,即同时显示两种语言。一个例子是按住V键选择载具的菜单,文本会拥挤在一起,但你仍然可以通过图片来参考选择载具。更新:我做了一些调整,部分解决了这个问题,我会继续尽可能修正这类问题。

我目前测试有限,因为这花了我一些时间来研究并制作完成,今后如果我发现还有可以优化的地方,我会继续去做。我懂英语和韩语,所以大部分测试都是用这两种语言进行的。对于其他语言,我很难验证,只能大致看一眼,从视觉上判断是否正常。

这也基本上就是1.4.1版本问题漏网的原因。重复字幕只影响部分语言而非全部,如果你恰好没有加载受影响语言的存档,看起来就完全正常。现在我已经添加了一个自动化检查,在打包前会扫描每种语言的每个文件,这比人工检查几个对话要可靠得多。

我是如何做到的

使用的工具: WolvenKit、PowerShell、Claude Code 和 ChatGPT Codex

如果有谁对这个方法感兴趣,也许是因为他们想要不同于“语言+英文”的其他语言组合,其原理如下。你需要一定程度的脚本知识(或者说,像我是知道如何正确向ChatGPT提问),以及对游戏模组工具的熟悉度。

游戏存档结构包含 base 和 ep1,base 是原版游戏,ep1 是《往日之影》资料片。其中包含本地化文件夹,这些文件夹下又有语言目录。进入语言目录后,可能会有许多子文件夹,取决于你是否安装了音频包,但与本模组相关的只有“onscreens”和“subtitles”。

如果提取这些文件夹(我使用的是 WolvenKit),你会得到许多 C2RW 格式的 .json 文件,这些文件需要(也通过 WolvenKit)转换为可以处理的真正的 json。

Onscreens JSON 示例: 这包含两个大文件,包含所有与界面相关的本地化,示例片段:

{
  "$type": "localizationPersistenceOnScreenEntry",
  "femaleVariant": "렐릭 소프트웨어 업그레이드 완료",
  "maleVariant": "",
  "primaryKey": "78477",
  "secondaryKey": "Story-ep1-quest-main_quests-q301-scenes-q301_03_crash-_localizedMessage"
}

Subtitles JSON 示例: 这包含许多子目录和较小的文件,基本上就是字面意思——游戏中对话时实际显示的字幕。示例片段:

{
  "$type": "localizationPersistenceSubtitleEntry",
  "femaleVariant": "아직도 떠나고 싶어?",
  "maleVariant": "",
  "stringId": "1764916827582873600"
}

你可能已经注意到 femaleVariant 和 maleVariant 属性,但 male 是空白的。这是因为在任何只有单个选项的情况下,femaleVariant 是默认填写的那个。这在追加英文时造成了一些麻烦,因为有些语言(例如日语)在女性/男性变体之间有相当多的细微差异,而英文则可能完全没有。因此我添加了一些额外的逻辑:当英文的 maleVariant 为空时,将英文的 femaleVariant 追加到 maleVariant 上。我还在两种语言之间加入了\n,这会产生换行,在大多数情况下能达到更整洁的效果(就我而言)。

然而,我发现的另一个奇怪问题是,在许多字幕显示中,角色名最终无法遵循\n换行,而会根据语言的不同显示一些奇怪的字符或\n。我唯一能用来与英文文件进行比较的属性是‘onscreens’文件中的 primarykey 或 secondaryKey,所以我尝试使用‘characters’和‘displayName’作为模式来识别并删除这些名字中的换行符,在我短暂的测试中看起来效果不错。

我一直在一边识别这些情况一边进行清理,但这可能比较棘手,因为它们不一定总有好的 secondaryKey 属性可以用来匹配,所以需要一些创造性的变通方法。

1.4.2 更新: 这被证明是人们报告的名字问题的根源。这些条目中有很大一部分的 secondaryKey 完全是空的,所以根本没有任何键可以进行模式匹配——用‘characters’和‘displayName’来匹配根本看不到它们。我现在的做法是查看英文文本本身:如果它很短且不是完整句子,就加空格;如果较长或读起来像文章,就保留换行。这是基于判断而非精确规则,所以可能仍然会有个别情况出错,但它修复了那些明显断裂的名字、物品名称和饮料名称。

我在这里犯的另一个错误: 一些 onscreens 条目根本不是文本,而是格式模板——比如 {NAME}: 这种游戏在运行时才会填充的内容。我把英文追加到了模板上,所以游戏忠实地填充了两份,结果出现说话人的名字两次。这类模板有28个,现在已完全跳过。识别方法是:如果去除大括号内的所有内容后,没有任何字母或数字剩余,就是一个干净的规则,无需判断——因此与上面的名字问题不同,如果这些模板被修改了,构建会直接失败。

关于标记标签: <kiroshi><mothertongue> 是整行指令,而非内联格式。标签必须是整个行——这正是 b= 和 a= 属性的用途,文本不需要放在标签之外。在其后追加内容会产生游戏从未见过的东西,所以它就直接打印标签。现在这些标签会被合并为一个包含两种语言的标签,而不是拼接。我之前通过删除标签来处理这个问题,但那样会删除句子所围绕的未翻译的外来词,留下“Rot in hell, .”这样的结果——其中约一半在没有它的情况下是不符合语法规则的。

1.4.2 新增功能: 整个构建现在是一个脚本。它直接从已安装的游戏中提取新的文件,转换所有内容,追加文本,再转换回去,并打包两个版本的模组,完全不需要我操作 WolvenKit 的界面。关键是全新提取——旧流程会复用之前构建的文件作为起点,这正是英文最终被添加两次的原因。现在没有什么可重复的,因为它总是从未经修改的游戏文件开始。

最后,因为我决定超越最初的范围,导致工作量大幅增加。我最初只做了韩语和英语,因为那是我需要的……我原本只打算上传那个……直到我想到可能有人在学习其他语言,也想拥有这个功能,内心感到愧疚。所以4天后我们就在这里了。

对于原版游戏,我处理了 58,653 个文件,资料片还需要处理 13,623 个文件,以覆盖所有非英语语言+英语的组合。总共有 72,276 个文件,而且自从我最初写这个文档以来这个数字还在增长——原版游戏随补丁新增了约 800 个文件,而《往日之影》没有变化。我做了大量工作来实现并行化,至少要同时处理多个语言目录,但即使全部用 PowerShell 脚本化,由于需要全面扫描所有内容,我的CPU和内存占用还是相当高。坚持我最初只做韩语的决定对我来说会轻松得多,那样只需1天就能回到游戏!

已知问题

  • 游戏中的一些文本框设计时从未考虑要容纳两种语言的文本,所以你会偶尔看到文本被截断或拥挤在一起。载具选择菜单通常是最明显的例子。
  • 少数简短的界面描述可能会显示在一行,而分成两行会更好看。这属于外观问题,而且我宁愿出现这种情况,也不希望名字再被拆开。
  • 我自己真正能确认的只有英文和韩文,所以如果你的语言中有什么看起来不对劲的地方,请在评论区说明——这个页面上的报告正是发现这些问题的途径。

最后的想法

抱歉写了这么多,但如果你读到了这里,谢谢你的关注!我希望能尽可能详细地描述这个过程供其他人参考。对于这种事情我愿意付出的努力是有限的(一个主要在业余时间做的个人使用模组)。我相信除了英文之外,人们还会想要其他语言组合,但我无法预测所有情况。而且由于英语往往是很多人作为第二语言学习的最常见语言之一,作为英语母语者,我认为以英语为目标是最合理的。

另外,由于这个方法本质上就是将英文文本附加到游戏文件中的其他语言本地化数据上,我并没有一种机制来注入不同的组合而不创建单独的模组。要制作不同的组合需要新建模组项目等。

那位制作《巫师3》模组的人写了一个 python 脚本,允许输入两种语言,脚本会调用一些外部工具来完成组合并准备好。我不确定在赛博朋克中是否容易实现,因为模组制作方式差别很大。也许用 WolvenKit CLI 可以做些什么,但要完成需要相当大的工作量。

2026年底更新 - 当我觉得1.4.2和1.4.3版本中的大部分错误已经成功清除后,我在考虑重新审视这个想法,让需要更不常见语言组合的用户能够自行操作。组合太多了,我无法全部生成(会有数百种)。就目前而言,我认为这并非不切实际,只是由于需要消耗的令牌量,需要分阶段进行:)

无论如何,希望这个模组对想要这个功能的用户有帮助。

谢谢 - Alan