核心模型与原则
静态重编译到底在做什么
它不是把整个 Switch 变成一台虚拟机,也不是把游戏改写成跨平台源码。典型路径是:
因此性能上限很高:游戏代码不经过 CPU 指令解释;但兼容性责任也更集中。模拟器可以用统一的虚拟硬件 把差异藏起来,静态重编译必须逐项重建游戏已经依赖的语义。
工程上还要把系统拆成四层:游戏特化 profile/生成器、通用 runtime、图形后端、平台外壳。用户提供的游戏资料经过 版本校验后生成独立 game library;APK 或桌面程序本身只负责加载 runtime、资源和工具。这个边界让地址表、shader 事实和游戏 patch 不会污染下一款游戏,也让 Android 的解包、SAF、后台构建与 Mac 的窗口生命周期各自可测试。
三个必须分开的契约
游戏契约
包括 title ID、NSO build ID、patch site、模块布局、shader 表、资源格式、内存请求、存档路径和输入状态。 它们必须进入 profile 或案例,不得散落在通用 runtime 中。
平台契约
包括 AArch64 ABI、TLS/x18、线程调度、页粒度、mmap 权限、Horizon SVC/IPC、文件系统、窗口、GPU API 和驱动能力。 同一个游戏在 Mac 和 Android 上的主要差别通常在这里。
图形契约
包括 NVN 对象生命周期、command buffer 录制语义、shader stage IO、descriptor/binding、纹理 layout/swizzle、 render target、同步和 present。画面“能出一帧”只证明最小链路,不证明这些契约整体正确。
最重要的判断规则
- 先判定在哪一层失败,再改代码。 黑屏可能是 guest 停止、draw 没发生、target 没写、合成丢失或 present 错误。
- 一个可见变化不等于根因。 强制红色、固定窗口 texture、关闭深度测试都可能只是诊断证据。
- 优先修通用语义。
QueryMemory、对象代际、UBO 内容、线程等待和 Vulkan layout 比某个 shader hash 的特判更值得修。 - 游戏特例必须有来源。 每个固定地址、容量、shader hash 或 patch 都要记录 build ID 和反汇编依据。
- 实验需要可回滚。 临时开关、设备文件和 trace 结束后清理;失败实验也要归档。
- 性能优化晚于正确性。 先获得正确画面和稳定状态,再测帧时间、GPU 利用率、内存带宽和 pipeline miss。
- 构建产物必须可追溯。 game library 的 build ID、generator/compiler 版本、flags、patch hash 和 profile hash 必须能从日志或 manifest 还原;可恢复构建优先于“重新跑一遍”。
什么算真正突破
真正突破必须同时满足:
- 现象边界发生稳定、可重复的变化;
- 有证据说明哪个契约不满足;
- 修复不依赖未记录的时序巧合;
- 修复后的行为能进入回归测试或手册;
- 明确哪些部分仍未解决。
“这次没有崩”但没有截图、日志或对照,不算完成;“画面变亮”但不知道为什么,也只能算诊断结果。