摘要
一场战斗结束时,游戏弹出结算页:标题写“胜利”或“战败”,双方各有一排卡片,每张卡是一种兵,显示兵种头像、出战数量,以及(稍后出现的)一行损失数。结算页能直接告诉我们双方各损失了多少,对状态估计(SE)核对整局减员很有价值。
结算页读取器之前只用合成像素和假的 OCR/匹配器测试过。本实验把三局真实训练录像中的结算帧交给生产路由进程(router,把截图分给各读取器的程序),用真实 OCR 模型和游戏知识模块的兵种匹配器读,再与前一天实验中模型目视核对的参考逐卡比较。
结果:所有面板帧都正确识别为结算页,数量和损失在稳定帧上全部一致,兵种在现有门槛下没有错但大多拒认。两个事先担心的风险都没有在面板显示期间出现。
要回答的问题
- 在真实帧上,生产路由读结算页的标题、旗子颜色、数量、损失和兵种是否正确?
- 风险 (a):面板出现后有闪白动画,会不会在某张卡的损失行还没画出时就被判为“稳定”,把它错填为“无损失(0)”?
- 风险 (b):认兵种应该用第一帧(头像干净)还是稳定帧(头像上可能叠了骷髅标记)?
数据与来源
三局训练录像的结算页,每局 7 对 7 张卡:
| 局 | 结果 | 选用的帧 |
|---|---|---|
| 10 月 10 日 16:57 | 胜利 | 面板第一帧 + 出现后 0.23、0.53、1.90 秒三张稳定帧 |
| 10 月 10 日 01:39 | 胜利 | 第一帧 + 0.20、0.50、1.23 秒 |
| 10 月 9 日 08:38 | 战败 | 第一帧 + 0.63、2.34、3.84 秒(本局没有 0.5 秒内的已存稳定帧) |
另外每局取面板出现前一帧作对照(应判为“不是结算页”),16:57 第一帧重复读一次(看耗时和可重复性),以及 01:39 面板关闭后的两帧加载画面。参考是模型目视核对(MODEL_VISUAL_CHECKED),不是人工审核;42 张不同的卡,样本很小。
方法
- 生产路由检查:按 App 的方式启动路由子进程,逐条发送结算页请求,原样保存返回;每张找到的卡按左上角位置(30 像素内)对应到参考卡位,再对每条返回做一次严格的结果校验。
- 风险 (a) 的逐帧探针:把三段录像从面板出现到消失的每一帧交给生产的结算页读取器,但文字读取器和匹配器是假的(标题/按钮一致,数字永远不一致)。“是否稳定”和“没有损失行”这两个判断不依赖 OCR,所以这就是生产在每一帧上的判断。
- 不修改生产代码,兵种门槛(分数 0.80、领先 0.03)不变。
设置
GPU(默认设备),限 8 个逻辑处理器、低优先级;游戏没有运行,但另有两个 App 回放和其他助手在跑。
结果
16 条主返回:路由状态与读数状态一致,严格校验全部接受;12 张面板帧都读到(READ),3 张对照帧都是“不是结算页”,没有失败或错误。标题 12/12 对,旗子颜色 24/24 对,缺卡和多卡在所有帧都是 0。
每格为 对 / 错 / 未读:
| 局 | 帧 | 卡 | 数量 | 损失 | 兵种(门槛下) | 兵种第一名(不设门槛,仅分析) |
|---|---|---|---|---|---|---|
| 16:57 | 第一帧 | 14 | 14/0/0 | 0/0/14 | 4/0/10 | 14 对 / 0 错 |
| 16:57 | 3 张稳定帧 | 42 | 42/0/0 | 42/0/0 | 3/0/39 | 26 / 16 |
| 01:39 | 第一帧 | 14 | 14/0/0 | 0/0/14 | 4/0/10 | 14 / 0 |
| 01:39 | 3 张稳定帧 | 42 | 42/0/0 | 42/0/0 | 0/0/42 | 20 / 22 |
| 08:38 | 第一帧 | 14 | 14/0/0 | 0/0/14 | 7/0/7 | 14 / 0 |
| 08:38 | 3 张稳定帧 | 42 | 42/0/0 | 42/0/0 | 12/0/30 | 34 / 8 |
| 合计 | 第一帧 | 42 | 42/0/0 | 0/0/42 | 15/0/27 | 42 / 0 |
| 合计 | 稳定帧 | 126 | 126/0/0 | 126/0/0 | 15/0/111 | 80 / 46 |
- 第一帧上损失全部“未读”,原因是损失行还没出现,读取器正确地不填。
- 稳定帧的损失:120 次读到数字,6 次是“没有损失行”的 0(两种兵各 3 帧,参考也是 0)。
- 稳定帧的兵种:头像上没有骷髅标记的 30 张卡,门槛下 14 对、16 未读,第一名 30/30 对;有骷髅的 96 张卡,门槛下 1 对、95 未读,第一名 50 对、46 错。不设门槛时的错误全在带骷髅的卡上;门槛下没有错。
- 热读同一帧,除耗时外结果完全相同。
风险 (a):逐帧 232 帧
| 局 | 面板期间帧数 | 判稳定 | 最早稳定 | 稳定且有损失的卡被记 0 | 稳定但有卡位没找到 |
|---|---|---|---|---|---|
| 16:57 | 62 | 58 | +0.133 秒 | 0 | 6 帧 |
| 01:39 | 48 | 45 | +0.100 秒 | 0(面板内) | 9 帧 |
| 08:38 | 122 | 117 | +0.167 秒 | 0 | 10 帧 |
面板显示期间没有发现风险 (a)。01:39 面板关闭后的加载画面上,探针记了 7 帧“稳定且某卡为 0”,但这是探针的假标题读取器总说“胜利”造成的;这两帧加载画面经生产路由,都判为“不是结算页”(没有标题或按钮文字),不会产生错误的 0。
面板刚出现 0.13–0.33 秒内有几帧部分卡找不到;找不到的卡只是缺,不会被记 0,但只看一帧的话会少几张卡。这几帧没有逐个目视原因。
风险 (b):第一帧还是稳定帧认兵种
126 对“稳定帧卡 vs 同局第一帧同一卡位”:两边都认出且相同 15、只有第一帧认出 30、两边都没认出 81、只有稳定帧认出 0、两边不同 0。按不同的卡算,第一帧认出 15 张,稳定帧认出 6 张且都是第一帧已认出的。所以用第一帧认兵种是对的;但即使第一帧,门槛下也只认出 42 张中的 15 张(第一名 42/42 对),门槛偏严。
耗时
- 路由进程启动到就绪 0.37 秒(模型在第一次请求时加载)。
- 第一次请求 42.95 秒,其中读取 5.71 秒,其余约 37 秒是加载 OCR 模型和兵种匹配器。
- 之后 11 次面板读取 4.32–5.89 秒,中位 4.84 秒;非结算页 0.13–0.20 秒。(报告审阅时更正了最小值的笔误。)
- 前一天在 CPU 上每帧约 22–39 秒;用户玩游戏时 App 走 CPU,这次没有测 CPU 路径。
失败与负结果
没有运行失败。探针在加载画面上的 7 个标记帧是探针假设造成的假阳性,保留备查。兵种门槛下的低识别率(15/126)是已知问题在生产中的再现。
局限
- 只有 3 局、都是 7 对 7,没见过少于 7 堆的排法。
- 参考是模型目视核对,不是人工审核;计数不是准确率。
- 没有验证 CPU 上的生产路由,也没有验证 App 端结算帧采样和 SE 消费的回放。
- 兵种门槛没有改,也没有独立数据来定新门槛。
结论与下一步
真实帧上,生产路由读结算页的标题、颜色、数量和损失都与参考一致,没有发现“提前判稳定导致错记 0”的问题;认兵种应该用面板第一帧。主要待解决的是兵种门槛偏严,以及 CPU 路径和 App/SE 端到端的验证。
Comments