跳转至

安装器

一个公开版本,将玩家自己的游戏文件转换为可玩的 TotK 文件夹。该版本不携带任何游戏数据,也不包含任何源自游戏的代码:安装器在玩家机器上构建游戏。安装后的文件夹仅包含游戏本体;安装器及其工具位于其外部。

玩家操作

  1. 从 GitHub Releases 下载 TotK-Setup-<version>-windows.zip(目前尚未发布任何版本),将其解压到任意位置并启动 TotK-Setup.exe。
  2. 选择:
  3. 基本游戏(XCI 或 NSP)和 1.2.1 或 1.4.3 更新(NSP);
  4. 对应的 prod.keys;
  5. 游戏语言和安装文件夹。
  6. 等待安装完成,仅需一次。窗口会显示每个步骤及其进度。
  7. 从安装文件夹中运行 totk.exe。安装器和源 NSP 或 XCI 都可以删除。

安装文件夹(main.c 中的 portable_paths() 读取此布局;它保持可移植):

<install folder>/
  totk.exe, SDL3.dll, libopus-0.dll, totk_xlate.exe
  totk.ini                       language; the other keys as commented defaults (totk.ini.example)
  exefs/, romfs/                 extracted from the player's files
  profile/                       saves
  logs/                          totk.log of the last run, totk.1.log to totk.4.log of the runs before it
  shader and pipeline caches     prepared by the setup
  totk-install.json              what built this folder: release version, input hashes, finished steps

更新移植版

玩家在同一文件夹上运行较新的安装器。它会读取 totk-install.json,在检查 romfs/、exefs/、profile/ 和 totk.ini 的哈希后保留这些内容,重新构建 totk.exe 并重新准备着色器。如果较新版本没有更改任何源自游戏的内容,则跳过重新构建。

如果更新文件与记录的不同(例如先是 1.2.1,然后是 1.4.3),安装器会从中重新提取并构建,同时保留 profile/。存档双向兼容:1.4.3 在加载时转换 1.2.1 的存档,而 1.2.1 也能加载 1.4.3 写入的存档。

安装步骤

  1. 检查:在写入任何内容之前,确认文件能用密钥打开,更新是 1.2.1 或 1.4.3(通过哈希判断,如 tools/extract.py 所做),密钥对更新来说足够新,目标磁盘上有足够空间(首次安装高峰期约 36 GiB,之后为 20 GiB),CPU 支持 AVX2(-march=x86-64-v3),存在支持 Vulkan 1.3 的 GPU。每个失败都对应一条清晰的消息。
  2. 提取:将 ExeFS 和 RomFS 提取到安装文件夹,并验证哈希。
  3. 提升:将 ExeFS 提升为 C 代码(recomp/gen.py、recomp/patches-v121.txt 或 patches-v143.txt),存入安装器旁边的临时文件夹。
  4. 编译:编译生成的 C 代码、modules.c、romfs.c、patches.c 和 ov_zstd.c(它们将每次安装的布局、RomFS 哈希和游戏版本的补丁页固化进去),并与预构建的运行时库链接成 totk.exe(build_game.py --runtime-lib;在 24 核上约需 3 分钟)。
  5. 准备:在安装文件夹中准备 RomFS 补丁和着色器(tools/make_romfs_patches.py、tools/prepare_shaders.py、totk.exe --prepare-shaders)。
  6. 清理:清理临时文件夹(生成的 C 代码和对象文件,约 1.3 GB)。

取消或失败的安装会从最后一个已完成的步骤继续(totk-install.json)。

命令行

installer/(仅使用标准库;installer/layout.py 映射发布文件夹,以及在仓库中的开发工具链):

python -m installer --base FILE --update FILE --keys FILE --lang CODE --dest DIR [--root DIR] [--temp DIR] [--verify]
  • 在包含 totk-install.json 的文件夹上,只需提供 --dest;只有在必须重新执行提取时才需要游戏文件。
  • stdout:每行一个 JSON 事件,类型包括 start、plan、step(started、done、skipped)、progress(step、phase、done/total/unit)、space(安装磁盘和临时磁盘上需要的字节数和可用字节数)、warning、error、end(installer/events.py)。消息是带参数的 id;installer/text/en.json 存放其英文文本。人类可读的日志写入 <temp>/logs/。
  • 退出码:0 完成,1 失败,2 命令行错误,3 取消。窗口通过向安装器的进程组发送 Ctrl+Break 来取消。
  • 每个步骤都会在输入上记录一个键(runner.py)。如果某个步骤已有记录的键且输出完好,则跳过该步骤,因此恢复和更新遵循同一条规则;从其他版本保留的输出会先重新计算哈希。
  • 安装磁盘上的峰值空间约为 36 GiB,而不是 22:提取过程会将两个 Program NCA(16.3 GiB)复制到合并后的 RomFS(15.9 GiB)旁边,然后将其删除。检查会计算出精确数值。
  • 窗口(python -m installer.gui,installer/gui.py 负责绘制,installer/guilogic.py 负责决策):表单、带进度的步骤列表、空间行、可折叠日志、取消(向 CLI 的进程组发送 Ctrl+Break,然后等待其退出)、带“打开文件夹”的完成界面。支持英语或俄语,根据 Windows 显示语言选择,并可在窗口内切换;每个句子都是 installer/text/<en|ru>.json 中的一个 id。包含 totk-install.json 的文件夹只需指定该文件夹。--selftest [--shots DIR] 会以两种语言构建每个界面并自行关闭。
  • tests/installer_gui_test.py:事件模型、表单、目录、取消、自关闭窗口,以及 CLI 在 --verify 模式下的一次端到端运行(需要 build/install-test 和 build/extracted/v121;参见其 docstring)。
  • tests/installer_test.py:使用假步骤测试记录逻辑。tests/installer_e2e.py:使用 config.local.toml 中的文件进行开发模式运行。

发布布局

解包后的发布内容;tools/make_release.py 组装它,--zip 打包它:

TotK-Setup.exe        starts python/pythonw.exe -m installer.gui (installer/launcher/launcher.c, no console)
installer/            the installer: steps, CLI, window, en/ru text catalog
python/               Python 3.14.9 embeddable + numpy, lz4, cryptography, cffi, pycparser (+ tkinter for the window)
recomp/, tools/       the lifter and the build, extraction and shader scripts the steps run (copied from the repo)
llvm/                 llvm-mingw, x86_64-only subset (Apache-2.0 with LLVM exception; mingw-w64 parts permissive)
runtime/              libtotkrt.a and the headers the generated code and modules.c/romfs.c/patches.c include
bin/                  totk_xlate.exe, hactool.exe, SDL3.dll, libopus-0.dll, ninja.exe
data/                 shader_list.tsv (MacNativeGames, MIT)
THIRD_PARTY_NOTICES.md
totk.ini.example, VERSION  the default ini; the release string (the repository's VERSION plus the commit)
  • SDL3 来自上游发布版本,而非 MSYS2:MSYS2 的 DLL 导入了 LGPL 的 libiconv。
  • 每个捆绑的第三方组件都会在 THIRD_PARTY_NOTICES.md 中占有一行。
  • 发布内容不包含任何衍生自游戏的内容;make_release.py 在完成前会对文件夹运行 tools/check_content.py。

约束

  • 安装程序的步骤中不包含任何 Win32 调用:Linux 使用自己的编译器和相同的步骤。
  • 密钥文件路径会传递给工具;密钥值绝不会出现在 UI、日志或文件中。
  • 窗口是 CLI 的前端(python -m installer --base ... --update ... --keys ... --lang ... --dest ...),它每行输出一个 JSON 进度事件。测试和 CI 使用 CLI。
  • 路径可以包含任意 Unicode 字符(例如西里尔字母用户名会使其下的临时文件夹和安装文件夹带上该用户名)。安装程序运行或构建的每个 exe 都会通过 activeCodePage manifest 将参数和路径按 UTF-8 读取:hactool(我们的补丁,building.md)、totk.exe(runtime/totk.rc)、ninja(上游)。Python 步骤以 UTF-8 写入文件和日志,build_game.py 会在其 Ninja 命令行中为含空格的路径添加引号。
  • 如果游戏文件的数据未通过哈希校验或提前结束,安装程序会以 check.input_damaged 停止,该错误会指明文件并提示重新复制(extract.DamagedFile)。合并失败时,仅检查基础 Program NCA 即可判断哪个文件已损坏。
  • 未签名的 exe:SmartScreen 会在首次启动时发出警告。

后续

  • 在移动安装位置、更换 GPU 或驱动程序后,启动时重新预热驱动缓存。
  • NSZ 和 XCZ 输入。Linux 发布版。

本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 to/totk-pc-recomp