ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

MacNativeGames 验证方法论:600 个负对照、46,587 项音频检查,以及如何做公平的性能 A/B 测试

MacNativeGames 验证方法论:600 个负对照、46,587 项音频检查,以及如何做公平的性能 A/B 测试

【免费下载链接】MacNativeGames

项目地址:https://gitcode.com/gh_mirrors/mac/MacNativeGames
点击查看免费下载

MacNativeGames 是一个开源项目,让《塞尔达传说 王国之泪》在 Apple 芯片的 Mac、iPhone 和 iPad 上原生运行,而不是用模拟器。它把"能不能跑对"当成一门科学:用600 个负对照确认代码改写没有跑偏,用46,587 项音频检查锁死混音精度,再用严格的A/B 交替窗口做公平的性能对比。这篇文章带你读懂它背后那套可以复现、可以证伪的验证方法论——哪怕你只是普通玩家,也能看懂"通过测试"和"真的对"之间那道关键的坎。

什么是"负对照":先证明测试本身抓得住错

新手最容易掉进的一个坑是:测试通过了,就等于功能对了。但"通过"可能只是因为你根本没设计出一个能让错误现形的检查。

打个比方:医院化验前,会把一批结果早已确定的标准样本一起送进机器。如果那条"已知有病"的样本被测成"没病",说明这台仪器本身不可信——再漂亮的报告也作废。

软件里这叫负对照(negative control):故意把某个地方改坏,然后确认测试一定会报红。只有当"故意弄坏的版本"被你的判据抓出来时,你才有资格相信"没弄坏的版本通过"是真的。

一句话记住:正例证明"它对",负对照证明"你的尺子量得出错"。只有两件事都成立,结论才站得住。

MacNativeGames 几乎每个子系统都配了对应的负对照,这正是它验证方法论的骨架。

600 个负对照:代码改写是怎么被"逐点等价"验证的

游戏原本是 Switch 的 ARM64 指令。Apple 芯片也是 ARM64,所以绝大部分指令可以原样跑;但有少数 macOS 不允许的写法(系统调用、平台寄存器、计时器寄存器),必须提前逐条改写成一段"做同样事情的短跳板"。

问题来了:改写点成千上万,怎么证明每一条"改完之后行为跟原来一模一样"?

项目的答案是逐点等价验证 + 变异自检,实现在 equiv.py 和总闸门 verify_rewrites.py:

  • 逐点等价:在同一个随机状态下,分别执行"原始指令"和"改写后的跳板",再比较寄存器、栈、内存写入、结束位置——两边必须完全一致。
  • 变异自检(负对照):随机抽出一批普通改写块,一半把那条指令改成空操作(nop),一半把跳板出口的跳转目标偏移 +4。这些"被人为弄坏"的块,必须全部被判出分歧;漏掉任何一个,整轮验证直接失败。

这里的600正好是三块代码加起来:主模块(main)抽 300 个、sdk抽 150 个、subsdk0抽 150 个,合计 600 个负对照。它验证的不是"结果碰巧对",而是判据本身有能力区分对错。

版本结构检查逐点等价站点有效试验负对照
1.2.154,640 个改写点54,540 个145,616 次600 个全部抓到
1.4.3三模块独立68,968 个语义站点184,378 次600 次破坏全部抓到

细节:负对照必须"被抓到",如果某个故意改坏的块没被判出分歧,verify_rewrites.py 会抛出Missed mutation controls并让整个验证失败。这条规则保证了 600 这个数字不是摆设,而是实打实的防线。完整记录见 v1.2.1 适配与测试记录 和 1.4.3 适配与测试记录。

46,587 项音频检查:把"听起来对"变成可复现的数字

音频是最难"自欺"的子系统:对白缺失、背景音乐中途安静、混响不对……这类问题往往"听起来好像没事",但其实是错的。

MacNativeGames 的做法是把混音拆成可数的检查项,并配上一份未修改的独立参考实现(Ryujinx.Audio)作标准答案:

  • 46,587 项生产混音器检查:跑通全部已知音效类型(1–9:延迟、混响、压缩器、双二阶滤波、环形缓冲、录音捕获等),覆盖 1.4.3 的浮点声音通道与 splitter。
  • 独立参考比对:24 组共 1,872,000 个样本与参考实现逐样本对比,最大误差 4.47e-08——这是"听起来对"背后真正可复现的那条数线。
  • 负对照:用开关TOTK_AUDIO_REV15_NEGATIVE=1故意破坏浮点路径、或用TOTK_AUDIO_STOP_RELEASE=0让"已停止的声音仍保留排队缓冲"。这两种情况下,检查必须失败,错误信息应为REV15 float voice and splitter samples。

这三条命令在 Makefile 的probe-audio目标里被连起来:先正常跑一遍,再用负对照跑一遍,负对照若"意外通过"就立刻退出报错。这样,音频的每一次改动都能被同一把尺子重新量一遍。详见 音频排障与验证说明。

负对照无处不在:从存档、软键盘到 2K 输出

如果你以为 600 和 46,587 只是两个孤立的大数字,那就太小看这套方法论了。负对照散布在几乎每个探针里——很多就在 Makefile 里以TOTK_PROBE_NEGATIVE=<编号>的形式存在:

  • 存档:负对照 23 让"提交操作不结束保存",探针必须因此失败。
  • 软件键盘:负对照 22 故意无视游戏最大长度,探针必须失败。
  • 输入:负对照 20 验证"参考系积分"能被姿态检查识别。
  • 自动读档:关掉自动读档却仍期望读到按键——必须失败。
  • 内存池索引:pool_index/probe.c 带两个负对照(不走回溯、不维护前缀最大值),两者都必须被抓住。
  • 纹理布局:故意把块高错一级再解,结果必须不再逐字节相等、且 PSNR 低于 22 dB,证明判据能分辨错误排布(见 贴图测试说明)。
  • 60 FPS 控制器:未打补丁的原版控制器本身就是负对照——它"绝不能低于 2",见 verify_fps60_patch.py。

这种密度意味着:你几乎不可能在某个子系统里悄悄埋一个"测试看不见的 bug"。

如何做一场公平的性能 A/B 测试

"性能"是另一头最容易自欺的领域:一张截图上的 120 FPS,不代表整局稳定 120。MacNativeGames 把性能对比写成了一条条硬规则,集中在 Mac 性能待做与复测方法。

交替窗口:至少 8 × 30 秒,且要 A/B/B/A

  • 每个性能候选,至少跑8 个 30 秒窗口,按 A/B/B/A/B/A/A/B 交替,而不是先跑完 A 再跑完 B。
  • 交替是为了消除机器温度、后台负载随时间漂移带来的偏差——如果 A 全在前、B 全在后,你测的可能是"时间"而不是"改动"。
  • 同一二进制、同一存档、同一镜头、同一缓存状态;禁止两份游戏或 GPU 探针并行,用独立 profile 和唯一 game-slot 隔离。

记完整分布,别只报平均

  • 报告完整帧分布的 p50 / p95 / p99 / 最大值,以及超预算的比例,并保留所有慢帧。
  • 不要把各分组分位数先平均再当合并结果;不要把重叠的 CPU/GPU 时间相加。
  • 截图 FPS、固定镜头平均帧、补帧数,都不能单独证明"稳定 30/60 帧"。

移动负对照:用"故意改慢"证明尺子量得出

这是整个 A/B 方法论里最漂亮的一笔,同样用了负对照:

在约 78.2 FPS 时故意把时间步长固定为 16.667 ms(相当于强行锁死 60 FPS),同样的输入,角色移动13.1015 m,比默认情况的 10.478 m多了 25.04%。

这说明"距离检查"这把尺子确实量得出明显的速度错误——如果它量不出来,那上面那些"速度没变"的结论就都不可信了。同时项目也如实记下:用TOTK_REALTIME=0的尝试实际仍被显示节拍卡在 60 FPS(位移 10.4284 m),不能拿它去否定高帧率补丁的必要性。

通过、无收益、未覆盖、负对照失败、被中断的测试,分别记录;绝不为了好看而删掉卡顿或异常。这条写进了最低记录要求,也是这套方法论最诚实的部分。

这套方法论教会我们的事

把 MacNativeGames 的做法抽象一下,其实就是三句话,任何做项目的人都能直接搬走:

  1. 先证伪,再证真:每个判据都配一个"故意弄坏必须失败"的负对照,否则"通过"没有意义。
  2. 把感觉变数字:混音、速度、帧分布,凡是能被量化的,就别用"看起来不错"糊弄过去。
  3. 对照要公平:A/B 交替、同机同二进制、记录完整分布,并为判据本身安排一次"自我破坏测试"。

下次有人说"我测过了,没问题",你可以礼貌地问一句:"你的负对照在哪?"——这就是 MacNativeGames 用 600 个负对照和 46,587 项音频检查,悄悄教会我们的一件事。

【免费下载链接】MacNativeGames

项目地址:https://gitcode.com/gh_mirrors/mac/MacNativeGames
点击查看免费下载

相关推荐

上一篇:Revezone 国际化架构解析:如何实现多语言支持的优雅方案
下一篇:fuel-core Ignition 网络链配置快照全解析:PoA 密钥、共识参数与 forkless-upgrade 测试应用

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进