惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Engineering at Meta
Engineering at Meta
T
Threatpost
P
Palo Alto Networks Blog
NISL@THU
NISL@THU
O
OpenAI News
Project Zero
Project Zero
G
GRAHAM CLULEY
P
Privacy International News Feed
A
Arctic Wolf
Microsoft Azure Blog
Microsoft Azure Blog
H
Help Net Security
M
MIT News - Artificial intelligence
T
Threat Research - Cisco Blogs
S
Security @ Cisco Blogs
Google DeepMind News
Google DeepMind News
B
Blog RSS Feed
D
Docker
aimingoo的专栏
aimingoo的专栏
博客园 - 【当耐特】
N
Netflix TechBlog - Medium
云风的 BLOG
云风的 BLOG
雷峰网
雷峰网
W
WeLiveSecurity
P
Proofpoint News Feed
腾讯CDC
Cloudbric
Cloudbric
S
Secure Thoughts
C
Check Point Blog
博客园 - Franky
T
The Exploit Database - CXSecurity.com
T
Troy Hunt's Blog
GbyAI
GbyAI
Security Archives - TechRepublic
Security Archives - TechRepublic
Application and Cybersecurity Blog
Application and Cybersecurity Blog
月光博客
月光博客
C
Cyber Attacks, Cyber Crime and Cyber Security
I
Intezer
TaoSecurity Blog
TaoSecurity Blog
L
Lohrmann on Cybersecurity
V
Visual Studio Blog
F
Fortinet All Blogs
博客园 - 叶小钗
C
CXSECURITY Database RSS Feed - CXSecurity.com
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Recorded Future
Recorded Future
C
Cisco Blogs
博客园 - 司徒正美
Stack Overflow Blog
Stack Overflow Blog
Y
Y Combinator Blog
Apple Machine Learning Research
Apple Machine Learning Research

博客园 - SHARP-EYE

Processing在P2D模式下使用 tint() 方法的注意事项 · 只对 image() 和纹理有效 Processing 的 sketch.properties 机制以及主程序与文件夹解耦的具体细节 Processing P2D 模式鼠标约束 · 限制在窗口内 · 技术报告 Kimi Code CLI 系统指令的摸索 以及 开发实战经验分享 基于 Irrlicht 和 WASAPI 的 Simple Audio Visualization 技术开发报告 AI Coding越来越强,我们还有必要学Processing吗? · 创意编程 嵌入式脚本语言全解析:从Lua到Wren,游戏与IoT开发的未来选型指南 PixelMentor:一个开源网站 · 调用AI视觉能力分析图片 · 提供影视后期修改意见 基于 Vanilla JS 构建高性能可视化节点创意展示编辑器 (CNE) 的技术实践与深度解析 · Creative Node Editor 关于OpenClaw部署在Ubuntu上的经验小结 P3DE (Processing 3D Editor) 三维场景编辑器 · 软件白皮书 · 基于 v0.4.8 Windows 批量文件操作风险指南 · 不完整小结 [深度复盘] 构建高性能实时弹幕系统:Node.js + Socket.io 架构设计与生产环境部署实战 如何调用CMD实现多个同类文件合并的研究 · 二进制 · 依次 · 文本图像视频音频 Processing (Java) 中实现2D任意图形的鼠标悬停检测 · 2D射线检测 · 模拟按钮 · 点击事件 PowerShell实现全屏七彩渐变 · 呼吸 · 屏保 浅谈processing-java.exe应用程序的使用(与PowerShell的联合) 使用Windows任务计划程序实现每天更换一张Processing创意桌面壁纸 PowerShell开发小工具 · 四张照片拼成一张 CMD批处理脚本+VBScript脚本+Potplayer 实现文件夹内所有视频的截图任务(指定时间点) 批处理脚本(.bat)实现实时监测文件夹并执行命令 [假设有新文件则拷贝到远程文件夹内] PowerShell开发游戏 · 打蜜蜂 Powershell实现圆缩小放大 (实时刷新窗口)
开源重置 沙丘2 游戏 · Dune Legacy 中文本地化与渲染技术说明
SHARP-EYE · 2026-04-07 · via 博客园 - SHARP-EYE

开源重置 沙丘2 游戏 · Dune Legacy 中文本地化与渲染技术说明


搜索开源游戏源码学习,无意间找到了这个项目---- Dune Legacy[An open-source remake of Dune II · 沙丘2的开源重置版],但是没有中文本地化。本文档说明在本项目(及官方 Dune Legacy 同源架构)下,如何将界面与文本翻译为简体中文,以及中文能否正确显示所依赖的引擎机制、配置文件与常见排错步骤。适用于维护 locale/Chinese.zh.po、配置游戏与理解源码行为。注意,本文涉及到的内容借助了AI生成和汇总。
游戏介绍和下载地址:https://dunelegacy.com/
仓库地址:https://github.com/henricj/dunelegacy
游戏下载(已集成中文汉化):https://wwasp.lanzn.com/iDIeJ3mnks1i

成果展示:

微信截图_20260407141037
微信截图_20260407141113
微信截图_20260407141056


一、总体架构

Dune Legacy 使用 GNU gettext 风格的 .po 文件 存储可翻译字符串,运行时通过类似 _() 的宏将 msgid(通常为英文) 映射为 msgstr(目标语言)
渲染使用 SDL_ttf,对 UTF-8 字符串调用 TTF_RenderUTF8_Blended 等 API,因此编码层面支持中文;限制主要来自 字体文件是否包含汉字字形,而非“引擎不支持 Unicode”。

流程图(Mermaid):

graph LR Config[用户配置 Language zh] -->|读取| TextManager[TextManager 加载 zh po] TextManager -->|查表| Lookup[根据 msgid 获取 msgstr] Lookup -->|索引字符串| Post[postProcessString 读取 PAK 文本] Lookup -->|普通 UTF8 字符串| Direct[直接使用 msgstr] Post --> Font[FontManager 与 TTFFont] Direct --> Font Font -->|UTF8 渲染| Screen[屏幕显示]


二、翻译文件:.po 格式与命名

2.1 文件位置与命名

  • 语言文件放在游戏数据目录下的 locale/ 中(与 LEGACY.PAK 等资源同级或可搜索路径内)。
  • 命名需与 语言代码 一致:配置里 General.Language = zh 时,引擎按 *.zh.po 匹配(例如 Chinese.zh.po)。
  • 模板/汇总文件常见名:dunelegacy.pot(仅 msgid,供生成各语言 po)。

.po 头部 msgid ""msgstr 中含元数据,对中文建议至少包含:

  • Language: zh_CN(或 zh
  • Content-Type: text/plain; charset=UTF-8
  • Plural-Forms: nplurals=1; plural=0;(简体中文通常无复数形态区分)

2.3 与原版 Dune II 数据的关系:LanguageFileExtensionLanguagePakFiles

每个 .po 中通常包含两条特殊条目(与 English.en.po / German.de.po 等一致):

msgid 英语示例 含义
LanguageFileExtension ENG / GER / FRE 决定从 PAK 里读 TEXTH.*TEXTA.*MESSAGE.* 等文件时使用的语言后缀
LanguagePakFiles ENGLISH.PAK,...GERMAN.PAK 需要加载的语言相关 PAK 列表
  • 德语/法语:有官方 GERMAN.PAK / FRENCH.PAK,简报等可从 PAK 中取对应语言。
  • 简体中文不存在官方中文 PAK。实践中 LanguageFileExtension 仍设为 ENGLanguagePakFiles 与英语一致,战役与 Mentat 等仍从英文资源索引;若要在界面显示中文,需在 .po 里把对应条目的 msgstr 写成完整中文,且不要@ 引用英文索引(见下文 @ 机制)。

三、翻译策略:两类字符串

3.1 普通 UI 字符串

形式msgid "Upgrade"msgstr "升级"

特点:无 @ 前缀,msgstr 即为最终显示文本。菜单、按钮、选项、部分提示等多属此类。

3.2 带 @ 的“索引字符串”(与 PAK 联动)

形式示例

msgid "@MESSAGE.ENG|10#Windtrap: Windtrap supplies..."
msgstr "@MESSAGE.ENG|10"

引擎逻辑(概念上):

  1. 先得到本地化后的字符串(此处仍为 @MESSAGE.ENG|10)。
  2. 若以 @ 开头,则 postProcessString 解析 文件名|索引|可选替换规则#注释,从已加载的 索引文本(来自 MESSAGE.ENG 等)中取出英文正文显示;# 后多为开发用注释。

因此:

  • msgstr "@MESSAGE.ENG|10" → 实际显示的是 ENGLISH.PAK 里 MESSAGE 第 10 条英文,不是 msgid# 后面的说明文字。
  • 要显示中文:应把 msgstr 改为不含 @ 开头的纯中文,例如:
    msgstr "捕风站:为基地供电。没有电力时建筑会随时间损坏。"
    这样不会走 PAK 索引,直接显示中文。

法语/德语 常见写法是 msgstr "@TEXTH.FRE|4",从 FRENCH.PAK 取法文;中文无中文 PAK 时,不能照搬 @TEXTH.CHN|…,除非自制 PAK(一般不现实)。

3.3 战役简报(TEXTH / TEXTA / TEXTO)

  • 大量条目的 msgid 仅为占位,如 Description of Atreides mission 1真正长文存在 PAK 的 TEXTH/TEXTA/TEXTO 英文表中
  • msgstr 仍为 @TEXTA.ENG|4 等,游戏中简报仍为英文
  • 全文中文化:需为每条任务撰写中文 msgstr(纯文本),工作量很大,通常按战役分批完成。

3.4 机器翻译 + 人工校对(本仓库采用过)

  • 可用 German.de.podunelegacy.pot 为源,对@ 的 UImsgid(英文) 批量机翻,再人工修正术语(如 Carryall→运载机、Harvester→采集车)。
  • @ 类条目:机翻 msgid 无效;要么保持 @…ENG… 继续英文,要么改为手写中文 msgstr

四、中文渲染:字体与配置(核心)

4.1 引擎侧(源码层面)

  • 字体由 FontManager 加载,实际实现为 TTFFont,使用 SDL_ttf
    • TTF_RenderUTF8_Blended
    • TTF_SizeUTF8
  • 结论:字符串为 UTF-8 即可;缺字是因为 TTF 文件不包含 CJK 字形,常见表现为空白、方框或完全不画字

4.2 默认字体

发行版数据里默认常使用 Philosopher-Bold.ttf(西文标题向),不含中文。仅当 msgstr 为拉丁字母时仍能显示;中文需要换成含简中的 TTF/OTC/TTC

4.3 配置项:Video.Typeface

Dune Legacy.ini[Video] 节中:

Typeface = default

或指定字体:

Typeface = C:/Windows/Fonts/simhei.ttf
Typeface = C:/Windows/Fonts/msyh.ttc

行为要点(与常见开源分支一致):

  • default 或空:使用内置默认(多为 Philosopher-Bold.ttf)。
  • 绝对路径FileManager::openFile绝对路径 直接用 SDL_RWFromFile 打开,可指向系统字体
  • 相对文件名:在游戏数据搜索路径下查找同名文件。

注意

  • .ttc(字体集合) 在部分 SDL_ttf/FreeType 组合下可能出现兼容问题;若异常可换 单面 .ttf(如 simhei.ttf)。
  • INI 解析若对路径中字符敏感,可尝试 正斜杠 C:/Windows/...

4.4 用户目录覆盖同名字体(高级)

搜索路径通常包含:

  1. 游戏安装数据目录
  2. 用户配置目录下的 data/(如 %AppData%\Roaming\dunelegacy\data\

若某分支实现为:同名文件先被安装目录占用,则仅把字体放在用户 data 可能无法覆盖;若安装目录没有散文件 Philosopher-Bold.ttf(只在 PAK 内),则用户 data\Philosopher-Bold.ttf 可能被优先命中——视具体版本 CaseInsensitiveFilesystemCache 合并顺序 而定。
最稳妥仍是使用 Typeface 绝对路径 指向中文字体。

4.5 源码级自动选择 CJK 字体(可选开发项)

若在自编译分支的 main.cpp 中实现:当 Languagezh 开头且 Typefacedefault 时,依次尝试:

  • 数据目录下的 NotoSansSC-Regular.otf 等;
  • Windows:C:\Windows\Fonts\msyh.ttcsimhei.ttf 等;
  • Linux/macOS:常见 Noto CJK / 系统黑体路径;

找不到则回退默认西文字体并打日志警告。这样可减少用户手改 ini。


五、配置与文件路径(Windows 示例)

用途 路径
用户主配置 %AppData%\Roaming\dunelegacy\Dune Legacy.ini
用户数据(可放字体覆盖等) %AppData%\Roaming\dunelegacy\data\
安装目录模板配置 <安装目录>\config\Dune Legacy.ini

语言

[General]
Language = zh

字体(示例):

[Video]
Typeface = C:/Windows/Fonts/simhei.ttf

修改后需重启游戏;若从安装目录复制 config 模板,注意实际生效的是用户目录下的 ini(若已生成)。


六、主菜单“只有英文有字、中文空白”的现象

  • 早期曾将主菜单 msgstr 译为中文,但默认字体无汉字 → 按钮看似空白
  • MODS 等仍为英文 msgid 时可能仍可见。

解决

  1. 先配置 含中文的 Typeface(或覆盖/替换字体方案);
  2. 再使用中文 msgstr;或暂时保留主菜单英文以保证可点选。

七、检查清单(落地步骤)

  1. locale/Chinese.zh.po:UTF-8,头部 LanguagePlural-Forms 正确。
  2. LanguageFileExtension = ENGLanguagePakFiles 与英语一致(无中文 PAK 时)。
  3. 需要中文显示的条目:msgstr 不要用仅 @…ENG…(除非接受英文);建筑说明等应改为纯中文
  4. Dune Legacy.iniLanguage = zhTypeface 指向中文字体或使用支持中文的默认逻辑。
  5. Chinese.zh.po 放到游戏实际读取的 locale 目录。
  6. 重启游戏验证;若仍缺字,换字体或检查路径/.ttc 兼容性。
  7. 若是迁移到新机器后出现中文异常,优先执行项目根目录的 fix-chinese-display.ps1(详见“第九章 9.6 一键修复脚本”)。

八、参考:引擎内关键符号(便于对照源码)

概念 说明
_() / getLocalized() .po 映射
getLocalized@ 开头 进入 postProcessString,从 PAK 索引取字
TTFFont::createTextSurface TTF_RenderUTF8_Blended
FontManager Typeface 指定或默认 TTF 加载
FileManager::openFile 支持绝对路径打开字体文件

(具体类名、函数名以你所使用的源码分支为准,如 henricj/dunelegacy 等。)


九、本次新机器排查与修复实录(Windows)

本节记录一次真实迁移场景:把可用的 Dune Legacy 中文项目拷到新机器后,出现“中文显示异常(主菜单中文不显示/空白)”的问题,并完成修复。

9.1 现场症状

  • General.Language = zh 已设置;
  • locale/Chinese.zh.po 存在且为 UTF-8;
  • 菜单中英文项(如 MODS)可见,但中文项异常或不显示。

该现象与第六章一致,优先怀疑字体链路。

9.2 排查过程(按优先级)

  1. 确认实际生效配置文件

    • 安装目录模板:<安装目录>\config\Dune Legacy.ini
    • 实际生效:%AppData%\Roaming\dunelegacy\Dune Legacy.ini
    • 结论:应以用户目录 ini 为准,模板不一定实时生效。
  2. 确认语言文件可用性

    • locale/Chinese.zh.po 存在;
    • Header 中 Language: zh_CNcharset=UTF-8Plural-Forms 正常;
    • LanguageFileExtension = ENGLanguagePakFiles 与英语一致(符合“无中文 PAK”的实践)。
  3. 确认字体路径是否在新机有效

    • 原配置常见写法:Typeface = C:/Windows/Fonts/simhei.ttf
    • 新机器可能不存在同名字体,或字体路径/兼容性差异导致加载失败。

9.3 根因结论

此次问题根因是:跨机器后字体路径与字体可用性不稳定,导致 Typeface 指向的字体不可用或不含完整中文字形,进而出现中文空白/缺字。

9.4 最终修复方案(稳定版)

采用“用户目录字体兜底 + 显式绝对路径”:

  1. 创建用户数据目录:
    • %AppData%\Roaming\dunelegacy\data\
  2. 复制可用中文字体到该目录,并统一命名为:
    • Philosopher-Bold.ttf
  3. 修改用户配置(不是模板):
[General]
Language = zh

[Video]
Typeface = C:/Users/<用户名>/AppData/Roaming/dunelegacy/data/Philosopher-Bold.ttf

这样可以避免不同机器 C:\Windows\Fonts\ 中字体文件名、是否安装、字体兼容性差异带来的风险。

9.5 手工修复命令(PowerShell)

New-Item -ItemType Directory -Force -Path "$env:APPDATA\dunelegacy\data"
Copy-Item -Force "C:\Windows\Fonts\simhei.ttf" "$env:APPDATA\dunelegacy\data\Philosopher-Bold.ttf"

然后编辑 %AppData%\Roaming\dunelegacy\Dune Legacy.ini,将 Typeface 指向上述目标路径(建议使用 /)。

simhei.ttf 不存在,可换 simsun.ttcDeng.ttf 等本机可用中文字体。

9.6 一键修复脚本(已加入项目)

为减少重复操作,项目根目录已新增:

  • fix-chinese-display.ps1

脚本会自动完成:

  • 检测并选择本机可用中文字体(优先 simhei.ttf);
  • 复制到 %AppData%\Roaming\dunelegacy\data\Philosopher-Bold.ttf
  • 自动备份 %AppData%\Roaming\dunelegacy\Dune Legacy.ini
  • 自动写入 Language = zhTypeface = <用户目录字体路径>

运行方式:

.\fix-chinese-display.ps1

不希望脚本结束时停顿:

.\fix-chinese-display.ps1 -NoPause

9.7 验证与回归

  1. 完全退出游戏并重新启动;
  2. 验证主菜单、设置、任务说明是否显示中文;
  3. 若仍异常,检查日志与字体兼容:
    • 更换 .ttf 字体优先;
    • 保持 Language=zh
    • 保证 Chinese.zh.po 被游戏实际读取目录命中。

9.8 回滚方法

  • Typeface 改回 default 或旧路径;
  • 删除(可选)%AppData%\Roaming\dunelegacy\data\Philosopher-Bold.ttf
  • 使用备份 ini(脚本生成的 .bak-时间戳)恢复原配置。

十、总结

目前的 AI 已经完全能胜任翻译的工作,进行本地化适配任务。这次我用了Cursor IDE 配合 Auto 智能模式 做了本次翻译适配尝试。它主动提出要查看英文、德文等其他语言的原文本进行参考再结合故事设定,综合翻译出最适合的文本。其实AI还提供了另外的解决方案,有一种是直接改动源码,修改渲染底层。
有了AI的加持,以后的本地化工作就非常简单容易了,即使官方没有给出汉化,我们也可以自己翻译做适配。