摘要
在游戏里,生物的攻击/防御面板数值 = 生物基础值 + 英雄的攻击/防御 + 其他效果(技能、宝物、状态等)。所以当同一兵种的面板数值在两次截图之间变化时,第一步应当看看英雄的数值是不是也变了。用户发现:SE(状态估计:把读到的观察累积成对局状态和对手构筑的推断)在解释“生物攻击 19→21”时,完全没有使用已经从战斗 HUD 读出的英雄属性历史,而且也没有任何测试覆盖这种基本情况。
本实验先写场景测试复现问题,再让 SE 的历史解释消费已有的英雄 HUD 读数,分别给出“生物变化 = 英雄变化 + 其他净变化”。在一局对电脑录像的已保存输入上,修复后的说明变为“英雄攻击 12→14(+2);生物攻击变化 +2 = 英雄 +2 + 其他 0”,并清楚标出其中一端用了“回溯假设”。
说明:本实验目录只有重放和显示脚本;报告写在 state_estimation 模块的文档里,本文据此整理。
要回答的问题
- 生物属性历史解释为什么没有用上英雄 HUD?这是缺测试还是实现漏了?
- 怎样在不看未来、不挑数值凑答案的前提下,为两个面板时点各选一个英雄读数?
数据与来源
- 场景测试:通过公开 SE 入口构造的合成场景(下表)。
- 真实回放:一局用户对官方电脑 AI 的训练录像(10 月 9 日 08:38)中,已保存的 8 帧自动视觉结果。没有手工改数、没有加入用户参考答案、没有重新 OCR。
| 媒体时刻 | 已保存自动观察 |
|---|---|
| 76.18 秒 | 准备页英雄攻击 11 |
| 92.2 秒 | 真菌伊利亚德攻击 19、防御 17;这一帧没有英雄 HUD(战术布阵阶段,画面上本来就没有) |
| 98.40 秒 | 英雄攻击 12、防御 6 |
| 223.8 秒 | 同帧英雄 14/6、生物 21/17;资料基础 6/11 |
方法
根因: 不仅是缺测试——历史算法只比较生物面板,没有消费已读出的英雄 HUD 历史;已有的“我方英雄变化”字段只表示准备页与首次 HUD 的比较,不能代替战斗中的历史。
修改: 从已有的战场英雄主体收集属性历史,按我方/敌方传给历史解释器;对同方同兵种的相邻面板,分别解释攻击/防御的“生物变化、英雄变化、其他净变化”。只沿用已有的“基础 + 英雄”口径,不新增伤害公式或规则。输出仍是已有推断栏里的条件说明,请求/结果格式、原始观察、攻击条件、技能候选都不变。
英雄读数的选择顺序(固定,不以拟合为目标):
- 早面板先用同帧值;否则用此前最近的可读 HUD,标为“延续假设”。
- 没有此前读数时,可用早面板之后、晚面板之前的第一条 HUD,标为“回溯假设”。
- 晚面板优先同帧;否则只用两面板之间的最新读数。
- 不用晚面板之后的未来读数,不把晚面板值同时填两端,不从准备页补战场属性。
- 两端英雄身份必须已读且一致;区间内读到另一个英雄身份就阻断分解。
- 两端实际选到同一条中间 HUD 时,不输出看似两次独立观察的数值分解。
设置
测试用单进程、限 8 核运行;Qt 界面在离屏模式下串行验证。
结果
先复现: 最先加入的 13 项场景测试,旧实现 12 项失败、1 项通过。
| 场景 | 应有行为 |
|---|---|
| 英雄 +2、生物 +2 | 英雄 +2,其他净变化 0 |
| 英雄 +2、生物 +3 | 剩 +1,不能全部归英雄 |
| 英雄不变、生物 +2 | 剩 +2 |
| 英雄 +2、生物不变 | 其他净变化 −2 |
| 防御变化 | 用英雄防御,不串攻击字段 |
| 两种己方生物分别 +2 | 分别关联,不串面板 |
| 缺同帧 HUD | 明示回溯/延续,不改观察 |
| 先后 HUD 10、12,12 更吻合 | 仍按顺序选第一条,不挑值 |
| 区间内读到不同英雄 | 阻断 |
| 两端锚点是同一条 HUD | 不输出数值分解 |
修复后相关五个 SE 测试文件 119 项通过;按审阅建议补“单 HUD 保护”和“基础属性不同”的负例后,同样五个文件 121 项通过(是后一次的总数,不与 119 相加)。App 攻击证据和敌方证据两组测试共 45 个用例点通过。
真实回放: 修复前后用公开入口重放同一个 8 帧请求,只有推断栏里的同一条历史说明改变;原始观察、8 条攻击记录及其条件、其他推断完全不变。修复后的说明:
- 英雄攻击 12→14(+2);生物攻击变化 +2 = 英雄变化 +2 + 其他净变化 0;
- 英雄来源是 98.40 秒 → 223.8 秒;回溯假设:98.40 秒的英雄攻击 12 在 92.2 秒也成立(那一帧没有读到)。
单次 SE 重放 1.709 秒(不是视频处理速度或整帧 p95)。App 已有的攻击证据页直接显示新的分解和假设,离屏截图已核对可读。
失败与负结果
- 修复初测时有 2 项测试的文本断言自相矛盾,修正为“禁止数值分解,但不禁止明确的缺失提示”。
- 第一次离屏渲染缺字体,脚本显式加载已有 Windows 字体后通过,没有改 App 字体或安装依赖。
- 用户随后纠正:准备页已有的英雄基线不应因“没有同帧 HUD”就丢弃。这一点由后续另一个修复处理,本页保留这一轮的测量。
局限
- 截图序列没有秒级时长或有效期,非同帧读数只是假设成立,不是已认证有效。
- “其他净变化为 0”不代表没有其他效果,增益与减益可能抵消;算法没有把变化归给任何具体状态(如“升华”)。
- 用户说“英雄 +2 导致生物 +2”只是用户陈述,算法没有把它当证据读取。
- 用户手工对象绑定尚未被这条路径消费,不能声称会自动检出绑定冲突。
- 软件测试不表示真实识别准确率;没有安装或启动用户 App,旧保存结果不会自动重算。
结论与下一步
修复让 SE 用上了已经读到的英雄 HUD 历史,并把每一处时序假设写在说明里。外部审阅认为根因必须同时承认实现漏消费和测试缺失;补充的两项保护已实现。下一步建议(当时尚未实施):用户回看已有分析时,可以显式让旧保存截图用当前 SE 重算,同时保留当时版本对照,不处理更多视频。
Comments