这篇讲 Battle Notes 怎样把已经从画面上读到的事实,带着主体、时间和来源送进战斗分析。它从一个具体的漏用问题开始,到 10 月 15 日把整场减员接成时间线为止。

摘要

问题: 识别模块已经读出的数字,在后面的分析里常常没被用上:英雄攻击 +2 和生物攻击 19→21 同时发生,助手却没有把两者联系起来。继续加 OCR 样本之前,需要先找出已读事实在哪一步丢失或被误用。

做了什么: 10 月 11–14 日沿“图像读取 → 保存运输 → 规则输入 → 历史时序 → 界面展示”逐项排查,修复了裁图截断、阵营旗帜取样、法术等级拒识、技能前提漏传、费用强制归因、报价只留最后一次等问题,并让用户能在保存结果上仅重算、更正和回看原图。10 月 14–15 日进一步把整场减员接成时间线:按画面出现时间排序、用日志条件性解释减员、离开行动条的堆条件性记为全灭、把只靠数量牌猜兵种的“假兵堆”单列、阵营颜色配对投票、用结算画面核对终局。

结果(计数,不是准确率): 英雄 12→14、生物 19→21 现在被解释为“英雄贡献 +2、其它净变化 0”;一个面板数量字段 340/385 不再被读成 340/38,四张训练图 44 个面板字段由 43 对 1 错变为 44 对。整场层面:16:57 录像 14 堆的开局数量 14/14 与结算画面一致,净减员 8 堆一致、6 堆缺最后一下、0 堆对不上;四局共 29 个假兵堆全部单列、60 个真兵堆没有一个被误移;实时三局按画面时间排序后,魔法来回跳 68/3/20 次降到 1/0/0。

限制: 主要材料是已多次曝光的训练录像,标注是模型目视核对(不是人工确认);条件解释不等于唯一因果;十场独立实战、逐字段 95% 与实时整帧延迟都还没有完成。

1. 背景:已经看见的数字,为什么没被用上?

在《Heroes of Might and Magic: Olden Era》的战斗中,玩家可以打开英雄和生物面板,看到攻击、防御、数量、杀伤范围等属性。我们的 Battle Notes 助手应该记住这些已经看见的数字,在之后发生攻击、施法或属性变化时使用它们。

一个很直接的问题暴露了缺口:生物攻击从 19 变成 21,而英雄攻击恰好增加 2。英雄贡献本来就是生物总攻击的一项,助手却没有把两条历史接起来。继续增加 OCR 样本之前,我们需要先回答:已经读到的事实,到底在哪一步没有被用上?

10 月 11–14 日的工作沿着这条链逐项检查。发现的错误分布在图像几何、保存运输、规则输入、历史时序和界面展示。修复后,助手能保留更多已读事实并给出有来源的数值解释;完整实战准确率和所有机制覆盖仍没有完成。

2. 任务定义:输入、输出和不能做的事

项目 内容
输入 一局里按时间累积的观察:英雄栏、生物面板、行动条、数量牌、法术书、日志、攻击预览、准备页和结算画面的读数,每条带画面时间和原图来源;用户的人工更正
输出 双方英雄与生物的属性历史及其分解、每堆部队的减员时间线、敌我阵营、法术报价历史、与公开规则相符的条件解释,以及每条解释能回到的原图
怎样算做好 读到的事实都进入解释;每条解释说清前提;没有依据的不补;用户能找到依据并更正
刻意不提供 游戏的隐藏状态和对手构筑真值;“唯一原因”的认证;后面才看到的面板不能给更早时刻的实时结论使用

3. 数据:用了哪些材料?

材料 用途
两段用户选定的训练录像(10 月 10 日 16:57、01:39)保存的 58 / 49 帧观察 10 月 11–14 日属性、费用和保存回看的修前修后对照
更早的官方 AI 对战资料(10 月 9 日 08:38) 英雄 12→14、生物 19→21 的原始例子;10 月 15 日的整场回放
三段录像的离线回放保存请求(16:57 261 帧、01:39 554 帧、08:38 246 帧) 减员时间线、假兵堆、结算核对
用户 10 月 14–15 日用安装版实时玩的三局 帧顺序问题;23:58 局 600–780 秒有逐帧参考
行动条与结算画面金标准 判断兵堆真假、核对终局

所有参考都是模型对照原图写的(MODEL_VISUAL_CHECKED),不是用户在审核页确认的(REVIEWED 为 0)。录像都已参与开发,本轮没有打开冻结的留出数据。

4. 方法:一个事实从画面走到解释,要过哪几关?

4.1 一张面板要经过哪些步骤?

Perception 是图像读取层,负责报告画面上看见的内容。State Estimation,简称 SE,是状态估计层:它把不同时间的观察联系起来,判断主体、历史和条件。Simulator 提供可执行的游戏规则查询。Battle Notes 负责输入、保存、显示和人工修正。

flowchart LR
 A[Visible panels and logs] --> B[Perception observations]
 B --> C[Saved source and time]
 C --> D[SE history and conditions]
 D --> E[Public rule queries]
 E --> F[Explanation and source review]

图中的每个箭头都可能出错。比如图像已经读出攻击预览,保存请求却没有运输该任务;或者技能已经保存,调用规则时只传了一部分技能,计算自然无法解释面板。

我们把“曾经观察到”“属于哪个主体”“当前是否仍有效”和“已经通过规则验证”分开。这样既能利用历史,也能保留它的条件。缺少当前截图,不意味着过去观察从未存在;过去读到一个值,也不意味着它可以永久沿用。

4.2 为什么数字读对了,结果里仍然没有?

一个生物数量字段的完整文字是 340/385。整图 OCR 已经读到了它,但固定的局部框截掉末位,两次局部读取都高分地给出 340/38。完整文字又因没有完全落在框内,被交叉检查丢弃。

修复只在位置合法、文字唯一、完整分数字面可解析且没有竞争文字时,有界地保全右端。它仍要求局部读取一致,不直接抄整图答案。四张已曝光训练图的 44 个面板字段由 43 对、1 错变为 44 对;这个小样本不能代表所有面板或所有布局。

另一个例子发生在敌方英雄栏。两张图的攻击、防御、法强和法力都已读对,但用于判断阵营的旗帜颜色框混入阴影,整侧字段被拒绝。收窄取样位置后恢复了输出,原颜色阈值保持不变。恢复的英雄攻击 9→8、防御 16→15,随后成为解释生物变化的重要输入。

还有一个法术等级 4,被其中一次局部读取的低分拒绝。我们只为等级裁图复制 4 像素边缘,保留数值范围、阈值和冲突检查,恢复了该读数。等级、名称、费用的来源仍分别保存;目录中的基础费用也不冒充当前规则计算。

这些例子说明,可靠性取决于整条读取路径。反过来,不能因为某一行正文好读,就放松其它字段的合同。一条反击日志在局部诊断中读出动作和生物名称,但玩家文字仍冲突,因此完整事件仍保持未知。这项诊断已关闭为未修复。

4.3 把英雄贡献和其它变化分开

对同一生物的两个可比较面板,最基本的解释是:

Creature change = Hero change + Other net change

在已有官方 AI 对战材料中,英雄攻击 12→14、生物攻击 19→21。现在 SE 会利用这两个历史端点,给出“英雄贡献 +2、其它净变化 0”的条件解释,而不把变化随意归因到附近出现的状态名称。

这里仍有两个限制。第一,主体与时间关联必须成立。用户确认原生游戏同一方同一兵种唯一,因此可作为历史关联前提;显式的不同实例或生命周期变化仍要隔开。第二,其它净变化 0 不证明没有隐藏效果,因为正负修正可能抵消。

进一步,SE 已经会查询某些技能组件,却曾在生成历史说明之后才计算它们。我们调整消费顺序,让同一次请求中的组件参考进入变化分解:

Creature change = Hero change + Skill reference change + Other net change

一次凤凰攻击 52→54 的案例还暴露了规则输入遗漏:准备页已读到战斗魔法、相关子技能和秘术,但查询只传了战斗魔法。补入合法且已读的主技能前提后,公开规则的攻击参考由 15 变为 17,能够在明确条件下解释增加的 2。早先 11→12 的参考来自漏传前提,不能继续当成最终结果。

保存观察 现在可以做的解释 仍不能推出
英雄 +2、生物 +2 英雄贡献 +2,其它净变化 0 没有任何隐藏增益或减益
英雄不变、技能参考 +2、生物 +2 已读技能联动参考可以解释变化 唯一真实因果已认证
英雄 −1、生物 −6,状态图标候选变化 内在光辉基础参考 −5 可作条件对照 具体变体、缩放、消失原因全部已知

同样的原则也用于攻击预览。某条下行范围 845–1267,在已有攻击、杀伤、数量、等待和近战特长条件下与公开规则相符。但目标防御来自后面才打开的面板,所以完整回顾可以显示这个假设,只读到较早位置的程序不能使用它。面板总攻击也不能再加一次英雄攻击。

4.4 书上写的价格,不一定是这次支付

法术费用出现过另一类错误:程序看到少了 2 点,就强制推断某件装备或技能。用合法构筑和真正执行的施法动作检查后,德鲁伊相关减耗也能产生这样的价格,原来的来源清单不完整。

另一个高级奇术例子实际支付 11→16,旧跨次公式却把它判为专家。问题在于把第一发的全部差额当成第二发共享的固定项。修复保留“两次施法”的证据,撤掉没有成立依据的档位锁定。

此后费用分析开始使用更多已读上下文:同次效果块支持的法术等级、此前完整技能装备页、每张书页之前的固定减耗来源。未知槽位不当空槽;部分已知来源只作小计;后来装备不倒灌早先报价。全部数学继续使用公开规则出口。

最新变化是保留同一法术的多次报价,而不只展示最后一次:

法术 保存的报价变化
审判 28→42→28→42→56
力量之歌 4→6→4→6→8

这批共有 11 条法术历史说明,每个端点有自己的直接读数和来源。未知等级仍未知,身份冲突或外来书页将历史分段,当前值不会被旧历史覆盖。

但报价不是支付。两张旧图中,审判显示 28 和 42,英雄法力为 250 和 222;后图还处于敌方回合并有冷却覆盖。我们可以确认两类画面读数,不能仅凭净差 28 就认证唯一一次施法支付。最后一页的一组报价在已读配置下仍没有一致的合法施法费用解释,原因尚未确认。

4.5 让用户找到依据,比多一段推断更重要

算法修好之后,导入旧结果如果仍只显示旧推断,用户就无法验证进步。保存工作流因此补上了三个实际能力:

  1. 显式点击“仅重算 SE 解释”,复用已有观察计算并另存,不重新 OCR。
  2. 对已有数字做人工更正或撤销,保留原始读取尝试和更正来源,计算成功后一起发布新快照。
  3. 从可核对的原始读取结果中恢复旧请求遗漏的攻击预览;已有任务不覆盖。

“仅重算”并非永远字节不变地提交旧请求:第三项允许恢复已经保存但运输遗漏的观察,需要单独回执。它仍不重新处理视频。

属性对照和攻击摘要现在优先显示已读值、变化分解、命中条件和缺口,再让用户选择明确来源帧查看原图。曾经把我方正差或敌方负差过滤成“无变化”的显示错误也已修复。

这里必须区分三个版本:开发源码、冻结安装包和另存分析结果。冻结本地预览 2026.10.13-1 能导入新结果,并不意味着它的实时算法已经包含随后所有修复。最新历史报价仍先以另存结果供核对。

4.6 把整场减员接成时间线(10 月 14–15 日)

属性和费用都是“某一刻的解释”;减员要把整场连起来。用户决定先不读战场上飘起来的伤害数字,而在两次行动之间读每堆部队的数量。SE 以“一方 + 一个兵种”为一堆(用户确认同一方同一兵种只有一堆),按下面的顺序处理:

  1. 按画面时间排序。 实时模式下整帧主读取常常取到 15–37 秒前的画面,而行动条等旁路读数是新鲜的;按读取完成的顺序合并会让旧值冒充当前。现在所有截图和旁路读数都有画面时间时,按画面时间排序;缺一张就保持原顺序。
  2. 连数量。 行动条、数量牌、生物面板的数量按时间连起来,下降就是减员。中间孤立的一次不同读数单列为可疑读数,不算减员。
  3. 用日志条件性解释。 日志的伤害行写着受击前数量和死亡数。能从减员前一步步走到减员后的,标出日志依据(一行走完是直接对应,几行连起来是多次命中);日志“被摧毁”记为条件性降到 0;“复活”“召唤”解释回升。日志与画面的时钟没有对齐,所以只按兵种和数量序列匹配,是条件关联而不是认证。
  4. 离开行动条。 行动条没被占满(回合组 0–1 不到 12 张且读到回合分隔)时,下一回合的卡全部在条内;一堆在三次这样的完整读取里都不见了,就条件性记为全灭。
  5. 假兵堆单列。 只靠战场数量牌的兵种猜测、行动条上从未出现、阵营已经凑满的“堆”,移到可疑兵堆,不混进真部队。
  6. 阵营颜色配对投票。 每帧两侧读到两种不同颜色就为(左色, 右色)投一票,最后一次定下;头像环只有在识别模块确认了布局时才投票。
  7. 结算画面核对终局。 结算画面列出每堆的开局数量和总损失:开局与第一次读数比较,净减员与累计比较;最后一下之后来不及读到的损失由结算画面补上。

5. 实验设置:怎样判断修好了?

每项修复都用同一份已保存的输入跑修前和修后两遍,比较整份输出:预期的字段变化了,其它字段一字不变。规则相关的检查从合法构筑和真正执行的动作出发,经公开观察进入 SE,包括触发、去除来源后的对照和负例。界面相关的检查在真实 Qt 窗口里导入、另存、重开并点开原图。

整场减员的检查用三种参照:行动条金标准判断一堆是真是假;结算画面判断净减员是否一致(一致 / 缺最后一下 / 对不上 / 无法对应);实时局 600–780 秒的逐帧参考判断减员和魔法变化的真假。实时帧顺序的比较在同一份保存请求上分别按读取完成顺序和画面时间重算。“魔法来回跳”= 同一英雄魔法值出现 A→B→A 的次数。

6. 结果

6.1 已读事实进入解释(10 月 11–14 日)

修复 修前 修后
英雄贡献接入生物属性历史 英雄 12→14、生物 19→21 没有关联 英雄贡献 +2,其它净变化 0(条件解释)
面板数量裁框 340/385 读成 340/38 4 张训练图 44 个面板字段:43 对 1 错 → 44 对
技能联动前提补全 凤凰攻击 52→54 的魔法参考 15(漏传前提) 参考 17,在明确前提下解释增加的 2
同一法术多次报价 只显示最后一次 11 条历史说明,例如审判 28→42→28→42→56
己方日志扣蓝与书页报价对照 没有 58 帧保存输入只新增 2 行:审判实付 28,第 9 帧报价 28 相等、第 10 帧 42 不等;召唤星之子实付 27,第 24 帧报价 27 相等;其余结果不变

最后一行是 10 月 14 日原文“下一步”的实现:只把同英雄、同法术、在两次日志页之间读到的书页报价列在实付旁边,标明相等或不等,不替施法选价格,也不用英雄栏魔法差认证支付。

6.2 这些检查证明了什么?(10 月 11–14 日)

主要真实材料是用户选择、已经多次曝光的两段训练录像所产生的 49/58 帧保存观察,以及更早的官方 AI 对战资料。本轮整理没有重新扫描视频。少量定点旧图重读、保存 JSON 重放、软件合法动作和界面导入检查具有不同作用:

检查 可以支持 不能支持
旧图与直接读数核对 具体字段和错误根因 独立泛化准确率
合法动作→公开观察→SE 已知条件的消费、触发、来源去除和负例保护 商业游戏全部规则已认证
同输入修前/修后比较 哪些输出发生变化,是否污染无关字段 全部实战分布都正确
Qt 导入、另存、重开和原图点击 用户能访问这份保存结果 用户实时游玩路径已全面验收

最新报价历史相关 XML 记录 372 个软件检查通过、12 个权限原因跳过;不是 372 场真实战斗,也不能与以前重叠的批次相加。

性能同样保留失败:初版报价历史在 21 次后台刷新后仍未完成。定位到重复来源查询后,改为只在本请求内复用同一主体与来源页,随后两次都在第 4 刷新完成,约 13.1–13.3 秒,包含启动和 58 帧历史输入。这修掉了具体停滞,仍不能宣称热单帧 95 分位延迟小于 3 秒。

十场独立实战、逐字段 95% 与实时整帧延迟仍是目标。现阶段没有一个可信的总体准确率数字。

6.3 整场减员(10 月 14–15 日)

检查 材料 结果
减员与日志的条件关联 16:57 一次回放的 30 个减员区间 一行日志直接走完 13、几行连起来 2、没有可用日志 15;21 行死亡日志用上 20 行
结算核对 16:57(参考结算读数) 开局 14/14 一致;净减员一致 8、缺最后一下 6、对不上 0
结算核对 + 离开行动条 01:39(真实结算读数) 一致 2 → 12,缺最后一下 11 → 1,无法对应 1
结算核对 + 准备页与阵营修复 08:38 官方 AI 局 14 张全部无法对应 → 一致 12、无法对应 2(两堆开局都是 52,按数量分不开)
假兵堆单列 四局共 60 个真堆、29 个假堆 29 个全部单列,0 个真堆被误移,0 个假堆留下
实时帧顺序 三局实时会话 魔法来回跳 68/3/20 → 1/0/0;可疑读数 28/13/9 → 3/1/1

实时 23:58 局有参考的 180 秒里,两次真实减员(天使 12→6、活化盔甲 52→25)在两种顺序下都被找到,没有假减员;按读取完成顺序时魔法净变化有 14 行,大多是假的,按画面时间只剩 1 行且是真的。

7. 失败与分析:哪里还会出错?

  • 强制归因。 费用少了 2 点,程序曾直接推断某件装备;合法构筑检查显示德鲁伊相关减耗也能产生这个价格。教训是:候选来源清单不完整时,不能“看到差值就定来源”。
  • 规则输入只传了一部分。 技能已经读到,查询规则时却只传了战斗魔法;漏传前提得到的 11→12 参考不能再当作结果。
  • 未确认的观察被当成结论。 官方 AI 对战没有玩家头像环,两侧都读成红色;SE 原来用它逐帧覆盖英雄栏颜色,把我方部队记成敌方。改为配对投票、未确认不投票。
  • 一个字段让整页作废。 准备页读对了一个八月游戏更新后新增的子技能,App 的笔记目录缺这一行,就把整页拒收,SE 因此不知道哪边是我方。现在只对这一类身份放行该槽并按未知处理。
  • 结算画面的兵种大多不敢认。 稳定帧上卡片被红骷髅挡住,门槛下 126 张卡只认出 15 张;改为借同一次出现的第一帧(头像还干净)的兵种,两次不一致就都不用。
  • 已知但未修好。 判官数量牌 26 被读成 126(牌左边的白色标记),一个白色笔画检查能挡住它但很脆弱,没有合入;交接记录写着表格数量重新认兵种会把召唤物改错(星之子 66 被认成狮鹫 66),修复进行中,本文未核实结果;最后一组报价在已读配置下仍没有一致的合法费用解释,原因未确认。

8. 局限:这些结果不能证明什么?

  • 条件解释不等于唯一因果;其它净变化 0 也可能是正负修正相互抵消。
  • 日志与画面的时钟没有对齐,减员与日志的关联只按兵种和数量序列。
  • 所有检查都在少数已曝光的训练录像上;实时只有一段 180 秒有参考。
  • 软件检查数(例如报价历史批次的 372 个通过)不是战斗场次,也不是识别准确率。
  • 安装版 battle-notes-2026.10.14-1 构建于提交 2cf1fe775;10 月 15 日的帧顺序、准备页、阵营和假兵堆修复都在它之后,只在开发源码和离线回放中验证。

9. 结论与下一步

这几天的修复让我们更清楚地看到:识别助手不只要读出数字,还要让每个数字带着主体、时间和来源走到最终解释。只有用户能回到原图核对,软件内部的一次“匹配”才开始具有实际价值。到 10 月 15 日,这条链已经从单个面板延伸到整场减员,结算画面给了它一个可以核对的终点。

下一步:在实时游戏里检查按画面时间排序和读取开销修复后的效果;修完召唤物被重新认兵种的问题;把实时局的逐帧参考扩大到更多片段;最终仍是十场来源隔离的独立实战。

10 月 14 日写下的下一步:只打通已有报价与支付候选(已实现,见 6.1)

最有价值的下一项,是复用已有合法 Logs 扣蓝—施法配对,和历史书页报价作有来源的对照。同一英雄、法术、时序和配对都成立时比较;缺条件时保留各自观察。它尚未实现,也不需要恢复已经暂停的飘字扩建或再造费用公式。

这几天的修复让我们更清楚地看到:识别助手不只要读出数字,还要让每个数字带着主体、时间和来源走到最终解释。只有用户能回到原图核对,软件内部的一次“匹配”才开始具有实际价值。

附录

证据(olden-era 项目相对路径与提交)

内容 路径 / 提交
10 月 11–14 日的总交接 docs/handoff/2026-10-14-se-perception-battle-app-handoff/README.md
英雄贡献与生物属性历史 state_estimation/docs/hero-creature-delta-2026-10-13.md
面板数量裁框 perception/experiments/2026-10-13-panel-quantity-crop/RESULTS.md
技能联动前提 state_estimation/experiments/2026-10-13-panel-skill-prerequisites/README.md
同一法术报价历史 state_estimation/experiments/2026-10-14-spell-cost-source-history/README.md
己方日志扣蓝与书页报价对照 提交 9ed23f902
保存结果仅重算、人工更正 battle_app/docs/saved-se-refresh-2026-10-13.md、battle_app/docs/saved-corrections-2026-10-13.md
减员与日志关联 state_estimation/experiments/2026-10-14-casualty-log-association/README.md
结算核对与 SE 请求规模 state_estimation/experiments/2026-10-14-battle-end-consistency/README.md
离开行动条 state_estimation/experiments/2026-10-15-left-strip/README.md
假兵堆单列 state_estimation/experiments/2026-10-15-fake-plate-stacks/README.md
阵营颜色配对 state_estimation/experiments/2026-10-15-side-colour/README.md
结算兵种借第一帧 state_estimation/experiments/2026-10-15-result-identity/README.md
准备页整页拒收 battle_app/experiments/2026-10-15-prep-identity/README.md
实时帧顺序 battle_app/experiments/2026-10-15-live-frame-order/README.md
实时局逐帧参考 perception/experiments/2026-10-15-live-ground-truth/README.md