P123 · 实时调度 · 实验记录与相关篇目
2026-10-15:按画面时间排序已接入 App;读取开销的两项修复(快速 JSON 编码、旁路不等主读取的后续工作)已实现,离线回放里排队等待 p95 约减半,实时里尚未实测。3 分钟实时真值是模型目视(MODEL_VISUAL_CHECKED)的已暴露开发数据,不是准确率。
摘要
Battle Notes 是我们为《Heroes of Might and Magic: Olden Era》做的观战助手:玩家打游戏时,它读屏幕上的行动条、英雄数字、法术书、生物面板和伤害预览,再由状态估计(State Estimation,下称 SE)整理成减员、魔法变化等记录。实时模式下,这些读取都要排进同一个读取进程,一次只能做一件事。
2026-10-14 夜里用户用安装版实时玩了三局,第一局的简报里同一条“我方魔法 +43(147→190)”重复了 6 次。原因不是读错数字,而是顺序:整帧的“主读取”排在快速的“旁路读取”后面,取到的是 15–37 秒以前的画面,旧画面的读数被插在新读数之后,SE 便看到魔法 147→190→147 来回跳。我们改为按画面出现的时间排序;在同一局 600–780 秒逐帧标注的三层真值上,段内魔法净变化从 14 行(10 行假、4 行重复)变成 1 行真变化,魔法来回跳从 25 次变成 0 次,两次真实减员两种顺序都找到了。
同一份真值也说明了剩下的问题不在“读对”而在“读到”和“读得及时”:App 读出的 HUD 数字 280/280、行动条数量 116/117 都对(1 个未读),但 47 个画面区间只采到 21 个,有的信息页读数在画面出现几百秒后才存好。我们查到主读取后 App 自己的处理随对局变长而变慢,期间读取进程有 43% 的时间空着却拿不到任务;修了 JSON 编码和旁路放行两处,离线回放里各类排队等待的 p95 约减半,实时效果还没测。
1. 实时模式在做什么,为什么会排队?
这个游戏的战斗是回合制:双方各有最多七堆生物,画面上方的行动条按行动顺序排着每堆的卡片,卡下写着这堆还剩几只;左右上角的英雄信息区写着攻击、防御、法术强度和魔法值。每当一堆生物行动完,行动条整条左移一格。下图是一局实时对局的行动条,按录像时间(图中 v 后面的数字,单位秒)排列:

图 1:10-14 23:58 那局。602.2 秒我方英雄放连锁闪电,天使从 12 只变成 6 只(第 5 张卡);607 秒凤凰行动结束,整条左移,原来排在条外看不见的活化盔甲(25)露了出来。图上每行左上角的英文标注是帧号和录像秒,由实验脚本加上。
用户希望“玩的时候几乎实时地拿到所有能分析的信息”。我们因此在两次行动之间读行动条来算减员,在鼠标悬停出现伤害预览时读预览,在玩家打开法术书或生物面板时读那一页。这些读取都交给同一个读取进程(代码里叫 router,路由):它常驻在后台,装着文字识别和图标匹配模型,App 每次发一个请求,它读完一张图再接下一个。所以实时模式的核心问题是一个调度问题:谁先读、谁后读,读完的结果按什么顺序交给 SE。
2. 任务定义:什么叫“实时地读对、用对”?
输入:游戏画面的实时帧流(原生 2560×1440),以及 App 内各个触发器给出的“现在值得读”信号。
输出:一串读数,每条带上它对应的画面时间(媒体秒),交给 SE;SE 据此给出减员时间线、魔法净变化等简报行。
成功标准分三层:
- L1 采到:画面上出现的每个值得读的区间(一次行动后稳定的行动条、一次预览、一次打开的法术书或面板),App 至少读了其中一帧;
- L2 读对:读出的每个字段与画面相符;
- L3 用对:SE 给出的减员、魔法变化与真实发生的事一致,没有多出来的假变化。
另外关心延迟:从画面出现到读数存好要多久。实时里玩家不会等,一张信息页如果几分钟后才读到,对当时的判断就没有帮助了。
故意不用的信息:不暂停游戏、不读游戏内存,只看屏幕;不在用户玩的时候抢 CPU(App 及其子进程被限制在一组逻辑处理器上、低优先级)。
3. 数据:三局实时对局与一段逐帧真值
- 三局实时对局:用户 10-14 23:58 起用安装版
battle-notes-2026.10.14-1实时玩的三局(会话名 23:58、00:35、00:44)。只读,没有改动会话。这三局整局没有真值。 - 3 分钟三层真值:23:58 那局录像 600–780 秒(标注时放宽到 598–782 秒)。用户同意作开发数据,所以它是已暴露的回归基线,不是独立准确率。标注等级 MODEL_VISUAL_CHECKED:助手按每秒 2 帧看原尺寸画面写的,预览和换手处用每秒 5–10 帧补看;标注按画面写,不按 App 结果改。没有运行文字识别或模型,只用视频解码、看图和现有 SE。
- 离线回放:用户选定的训练录像 10-10 16:57(前 23 分钟)在 App 离线视频回放(与菜单“离线视频”同一入口)上的多轮端到端运行,用来比较改动前后。离线回放会等旁路读完,比实时宽松。
时间对齐:App 记录的画面时间(media_seconds)用的是 App 自己的时钟。把会话里第 22–45 张整帧截图和录像在 ±2.5 秒内逐帧比灰度差,7 张有唯一最小值,偏移 0.89–1.31 秒,中位 +1.21 秒(录像秒 = App 秒 + 1.21);其余 17 张画面静止,最小值不唯一但都落在 0.61–1.32 秒内。相邻两张截图之间就差 0.25 秒,是 App 时钟的逐帧抖动,所以不确定度按 ±0.35 秒计。
4. 方法
4.1 一个读取进程,两类读取
App 发给读取进程的请求分两类:
| 类别 | 什么时候发 | 读什么 | 实时耗时(23:58 局,中位 / p95) |
|---|---|---|---|
| 主读取 | 关键帧服务选出的整帧截图(每个场景有固定间隔,例如战斗中 40 秒) | 整帧所有能读的内容;每局最多 58 次(保存格式上限 64) | 约 5 秒一张 |
| 旁路:行动条 | 行动条左移后静止 0.5 秒(一次行动结束),或英雄魔法框变化 2 秒后 | 只读行动条卡片的兵种、颜色、数量 | 1.2 / 1.7 秒 |
| 旁路:攻击预览 | 每 0.5 秒检查一次预览线索,确认出现 | 预览框里的伤害、击杀范围 | 0.6 / 0.9 秒 |
| 旁路:信息页 | 场景线索发现法术书、面板等(法术书和日志等画面静止) | 那一页 | 1.1 / 1.5 秒 |
旁路读取不占主读取的 58 次额度,结果存在会话的 action-strips/ 里,作为额外的帧交给 SE。读取进程空闲时的取件顺序是:行动条 → 预览 → 信息页 → 普通关键帧。理由是行动条和预览转瞬即逝,而战斗中关键帧本来就 40 秒一张,晚几秒无妨。待读信息页最多排 16 个,满了挤掉最旧的。
flowchart LR
K[Keyframe service] --> Q[App request queue]
T[Turn strip watcher] --> Q
P[Preview cue at 2 Hz] --> Q
C[Scene cue for pages] --> Q
Q -->|one request at a time| R[Router process]
R --> S[Readings with media time]
S --> O[Sort by media time]
O --> E[State Estimation]
图 2:所有读取排进一个队列,由一个读取进程逐个处理。本文的两项修复分别作用在“排队”(4.4 节)和“交给 SE 之前的排序”(4.3 节)。
这些触发器是此前在离线回放上做出来的。例如行动条:每秒 10 帧取行动条区域、缩成 64×8 的灰度签名,签名明显变化后再静止 0.5 秒就记一次行动结束;在 16:57 录像 390–600 秒的 16 次实际行动里检出 15 次,漏掉的是一次只交换前两张卡的“等待”(不改数量)。离线回放 e2e-08 里,行动结束到读完中位 2.38 秒、p95 5.53 秒,读完到 SE 存好中位 1.05 秒。
4.2 为什么旧画面会让 SE 看到假变化?
主读取一张约 5 秒,旁路一张约 1 秒,而旁路优先。战斗中旁路几乎不停,主读取只能在空隙里做:23:58 那局里,主读取的结果大约每 13 秒一张,取的却是队列里 15–37 秒以前的画面(例如日志里 741.7 秒取走的是 705.9 秒的帧),而且不总按时间先后取。
App 原来给 SE 的顺序是“截取顺序”:会话截图按截取先后排,旁路读数插在“当时已有的截图”之后。于是会出现这样一串:
- 旁路行动条读数(新画面):我方魔法 147;
- 主读取截图(30 秒前的旧画面):我方魔法还是 190;
- 下一条旁路读数(新画面):147。
SE 按顺序看,就是 147→190→147:先“回升”43,再下降。简报里“【魔法净变化】我方 +43(147→190)”就是这样来的。下图是这段时间英雄信息区的真实变化:

图 3:23:58 局 598–607 秒,左边是双方英雄攻击/防御/法术强度和魔法(我方红框 4/8/18,敌方蓝框 12/10/21)。我方两次施法:190→168(花 22)、168→147(花 21);183、158 是数字滚动中的中间帧。真实的魔法只降不升,“+43”是顺序造成的。
4.3 修复一:按画面时间排序
- 每张关键帧截图提交时,把它的画面时间(媒体秒)记在会话的
capture-media-seconds.json。旁路读数本来就带自己的画面时间。 - 组 SE 请求时,如果所有截图和旁路读数都有画面时间,就按画面时间排序;只要有一张没有(旧会话、手动截图、文件夹导入),就保持原来的顺序。保存过的旧请求不变。
这一改动不让任何读取变快,只保证 SE 看到的历史是按画面发生的顺序排的。旧画面晚到时,它会被插回正确的位置,而不是压在新读数后面。
4.4 修复二:主读取之后 App 在忙什么?
主读取取到的画面为什么那么旧?我们把 23:58 那局的 58 次主读取逐次还原了时间线(文件时间加日志),发现一个主读取周期从开局约 6 秒拉长到第 46–58 次的约 17 秒,其中读取进程自己做主读取只占约 1 秒。
| 主读取序号 | 处理(取帧→接受) | 读取进程自报 | 接受→投影提交 | 快照→下一次取帧 | 画面落后 |
|---|---|---|---|---|---|
| 1–12 | 1.73 秒 | 0.68 秒 | 1.17 秒 | 2.14 秒 | – |
| 13–30 | 3.64 秒 | 1.05 秒 | 2.94 秒 | 3.01 秒 | 9.5 秒 |
| 31–45 | 4.04 秒 | 1.05 秒 | 3.84 秒 | 3.94 秒 | 29.1 秒 |
| 46–58 | 4.67 秒 | 0.93 秒 | 4.78 秒 | 3.97 秒 | 35.5 秒 |
(各列为中位数;只列出主要几段,完整分段见证据。)
增长来自主读取被接受之后 UI 线程上的工作:每次都把本局全部读取重新组装、编码、校验、写盘好几遍(投影请求约 0.8 MB、投影缓存约 2 MB)。离线重放同一段代码,第 11 次 0.73 秒、第 31 次 1.44 秒、第 58 次 2.53 秒;性能剖析里最大的一项是纯 Python 写的 JSON 编码器(占 47%),其次是深拷贝(25%)和投影校验(21%)。更糟的是,App 在这段时间里不给读取进程派任何活:原来的规则要求“没有投影任务、没有待接受读取”时才发主读取,也才发旁路读取。主读取那段时间里,读取进程有 43%(335/775 秒) 空着;行动条从待发到发出的等待中位 8.1 秒,其中 68% 是在这个空档里等的。
两项修改(审阅后实施):
- 快速紧凑编码:对类型合格的值改用标准库的 C 实现编码(
json.dumps,紧凑分隔符),输出字节与原编码器完全相同;不合格的值(超长整数、NaN、非字符串键、元组、深度超过 32、孤立代理字符)仍走原编码器,错误原因不变。离线测量 2.3 MB 的编码从 0.145 秒降到 0.019 秒。 - 旁路不等主读取的后续工作:只要读取进程上没有主读取(只剩视图投影、接受已保存读取这类 App 端工作),就允许发旁路读取;主读取仍按原规则。旁路读取只写
action-strips/并刷新 SE,不碰视图存储。
第三项“发布时不再整局重新组装”(离线再省约 0.2 秒)没有做。
5. 实验设置:怎样数“采到、读对、用对”
- 顺序对比(三局实时会话):同一份保存的 SE 请求,截图时间取自会话日志的
submitted记录,分别按原顺序和按画面时间跑 SE。数简报行、魔法净变化行、“魔法来回跳”(同一英雄 HUD 魔法 A→B→A 的次数)、减员段、回升段、“可疑读数”(前后相同、中间单独不同、不算减员的读数)。这三局没有真值,所以只比较 SE 输出,不判断哪个对。 - L1 采到:真值里 47 个画面区间(行动后稳定的行动条、预览、法术书、生物面板、英雄页、日志、英勇攻击提示)。“主读取读到”= 会话截图帧落在区间内;“旁路读到”= 旁路记录的画面时间落在区间内;两者都有算主读取。落在 ±0.35 秒不确定度边上的记为“边界”。
- L2 读对:段内 37 个读数(主读取 16、信息页 15、行动条 4、预览 2)逐字段比对;屏上有行动条但请求只读 HUD 的情况另记“未尝试”,不算未读。
- L3 用对:保存的 SE 请求(268 帧)只留画面时间不超过 780.79 秒的 74 帧,两种顺序各跑一次 SE,与真值的减员和魔法时间线比较。
- 离线回放对比(e2e-16 与 e2e-17):同一段 16:57 训练录像,e2e-17 加上两项开销修复,比较各类旁路“排队等待”和“发出到结果”的 p95。两次回放时机器负载不同,只算指示性对比。
6. 结果
6.1 按画面时间排序:三局实时对局的 SE 输出
| 局 | 帧 | 顺序 | 简报行 | 魔法净变化行 | 魔法来回跳 | 减员段 | 回升段 | 可疑读数 | 减员合计 |
|---|---|---|---|---|---|---|---|---|---|
| 23:58 | 268 | 截取顺序 | 169 | 59 | 68 | 35 | 7 | 28 | 633 |
| 画面时间 | 77 | 13 | 1 | 31 | 1 | 3 | 483 | ||
| 00:35 | 20 | 截取顺序 | 14 | 3 | 3 | 3 | 0 | 13 | 193 |
| 画面时间 | 10 | 1 | 0 | 15 | 0 | 1 | 696 | ||
| 00:44 | 96 | 截取顺序 | 31 | 11 | 20 | 19 | 3 | 9 | 146 |
| 画面时间 | 9 | 0 | 0 | 18 | 0 | 1 | 119 |
顺序错乱的影响不是单向的:23:58 那局的来回跳让减员多算(633),00:35 那局反而把真实减员当成“可疑读数”藏掉了(3 段变 15 段)。这些只是 SE 输出的对比,三局整局没有真值,哪个减员合计正确无法判断。23:58 那局按画面时间排序后剩下的唯一一次来回跳(我方魔法 137→123→137,约 1446–1547 秒),抽看录像确认是真变化:先花 14、后来又回了 14。
6.2 开销修复:离线回放里排队约减半
| 旁路(p95) | e2e-16:排队 / 发出到结果 | e2e-17:排队 / 发出到结果 |
|---|---|---|
| 行动条 | 4.48 / 6.68 秒 | 2.77 / 3.66 秒 |
| 预览 | 5.57 / 2.65 秒 | 2.58 / 1.55 秒 |
| 信息页 | 5.16 / 4.89 秒 | 2.43 / 3.08 秒 |
| 整次回放墙钟 | 2264 秒 | 1577 秒 |
两次回放所有页面的采集计数完全相同(生物面板 23/24、法术书 22/22、日志 9/9、预览 51/55、结算 1/1),说明修复没有让任何页面漏读。编码修复在真实会话的 58 个回看快照等文件上逐字节一致。e2e-16 前段与另一段录像的回放并行,e2e-17 时有其它后台任务,所以这只是指示性对比;离线回放会等旁路读完,实时里的收益要在下一次实玩时测。
6.3 3 分钟三层真值
这一段发生的事(录像秒):602.2 我方英雄放连锁闪电(22 魔),天使 12→6,弹到活化盔甲 52→25(它当时是行动条第 14 张,看不见);605.3 又放一个群体法术(21 魔,无减员);607.0 凤凰结束行动;之后对手一堆圣骑兵想了 142 秒(608–750),用户在这期间反复开法术书、生物面板、英雄页;750.0 圣骑兵等待,750.6 我方魔法 147→149、敌方 170→168 同时变;756.4 妖精巨龙等待;770.0 修道院长等待。
L1 采到:47 个区间,App 读到 21 个(另 1 个落在边界上读到)
| 类型 | 区间 | 主读取读到 | 旁路读到 | 采到没读出 | 边界 | 漏 |
|---|---|---|---|---|---|---|
| 行动后行动条稳定 | 5 | 2 | 1 | 1 | – | 1 |
| 攻击/法术预览 | 3 | – | 1 | – | – | 2 |
| 法术书 | 14 | 3 | 6 | – | 1 未读 | 4 |
| 生物面板 | 16 | 2 | 3 | 2 | 1 未读 | 8 |
| 英雄页 | 6 | 2 | 1 | – | 1 读到 | 2 |
| 日志 | 1 | – | – | 1 | – | – |
| 其它(英勇攻击提示) | 2 | – | – | – | – | 2 |
延迟(区间开始 → App 取到那一帧 / → 读数存好):行动条 1.2–4.2 秒取到、11.1–18.5 秒存好;唯一读到的预览 0.3 秒取到、43.1 秒存好(排队 39 秒);主读取 0.2–2.3 秒取帧、15.7–48.5 秒存好;旁路信息页的帧在区间开始后 0.2–4.1 秒就存下了,读数却要 117–517 秒才存好——段内 15 个信息页读数都是在画面出现 114–523 秒后才从队列取出去读,其中 12 个是在主读取的 58 次额度用完后才轮到。
L2 读对:App 读出的值没有错,错在战场数量牌
| 字段 | 对 | 错 | 未读 | 不计分 |
|---|---|---|---|---|
| HUD 攻/防/法强(两方) | 210 | 0 | 0 | |
| HUD 魔法(两方) | 70 | 0 | 0 | 没有读数落在数字滚动期 |
| 行动条卡数量 | 116 | 0 | 1 | |
| 行动条卡颜色 | 117 | 0 | 0 | |
| 行动条卡兵种 | 63 | 0 | 0 | 54(这段没开面板,名称核不了) |
| 战场数量牌数量(主读取) | 170 | 2 | 5 | |
| 战场数量牌兵种(身体候选) | 94 | 2 | 6 | 68 |
| 生物面板 数量/攻/防 | 15 | 0 | 3 个面板页被拒 | |
| 预览 两行数字+目标兵种/颜色/数量 | 5 | 0 | 0 |
另有 26 个读数(主读取 12、信息页 14)屏上有行动条但只读了 HUD,记“未尝试”。
L3 用对:减员两种顺序都对,魔法净变化只有按画面时间排才对
| 截取顺序 | 画面时间顺序 | |
|---|---|---|
| 真实减员找到 | 2/2(天使 12→6;活化盔甲 52→25) | 2/2 |
| 漏掉减员 / 假减员 / 假回升 | 0 / 0 / 0 | 0 / 0 / 0 |
| 错数量读数 | 2(判官 126),正确地列为可疑读数,不算减员 | 同左 |
| 假兵种序列 | 3(各只有 1 次读数) | 同左 |
| 段内魔法净变化行 | 14 行:我方 +43(147→190)×6、+21(147→168)×1、敌方 +2(168→170)×3 是假的;我方 +2(147→149)×4 是真变化的重复 | 1 行:我方 +2(147→149),真 |
| 敌方魔法下降 170→168 | 找到 ×2(重复) | 找到 ×1 |
| 段内魔法来回跳 | 25 次 | 0 次 |
减员区间偏宽:天使的区间从 599.1 秒到 613.6 秒,因为 609.2 秒那次行动条读数里天使的数量没读出;活化盔甲从约 547 秒到 609.2 秒,因为 602 秒时它是看不见的第 14 张卡。真实的 147→149(750.6 秒)SE 最早在 759.7 秒那帧看到,比实际晚 9 秒,换算成墙钟到存好晚 23 秒。我方两次花魔不会出现在净变化行里:SE 只列我方回升和敌方下降,这是设计,不算漏。
7. 失败与分析:漏读和错读从哪里来?
漏读主要是调度问题,不是识别问题。 查每个漏掉区间里 App 的触发记录:
- 8 个区间(6 个生物面板、1 个法术书、1 个日志)的触发记录是排进了信息页队列,后来被挤掉:队列满 16 个时挤掉最旧的。这一段用户在对手长考的 142 秒里频繁开页面。
- 7 个区间(3 个法术书、2 个英雄页、2 个生物面板)没有任何触发记录。原因没有逐个核实;离线回放里见过的一种情况是 0.5 秒一次的场景线索只采到淡入淡出帧。
- 一次行动后的行动条(圣骑兵等待后 751–756 秒)没有记下“行动结束”,只在 756.6 秒记了魔法变化,下一次读行动条是 759.7 秒。原因未核实;离线回放里已知的一类漏检是“等待”只交换前两张卡、整条签名变化小,可能是同一类。
- 两个预览(754.2–754.8 秒)没有触发预览线索。另有一次假触发(703.1 秒敌方回合,屏上没有预览),读数正确地被拒。
- 23:58 那局整局预览读了 67 次,29 次是“没找到预览牌”(每次约 0.6 秒);预览原图读完即删,无法再核对。
错读集中在战场数量牌。 两次把判官的数量牌 26 读成 126:牌左边的白色标记被读成了“1”。

图 4:632.2 秒与 707.1 秒两张主读取截图里的判官数量牌(放大裁图)。画面是 26,读取器读成 126。SE 因为前后读数都是 26,把这两次正确地列为可疑读数,没有算成减员。
另外两次是数量牌所属身体的兵种候选认错(例如把梅杜莎的牌连到妖精巨龙身上),SE 由此另建了三条只有一次读数的假兵种序列。这些是 App 自己标的第一候选,不是确认结果。牌子 126 的一个修复尝试因为太脆弱没有合入。
开销调查里有一部分没拆开:主读取“取帧→接受”里除读取进程自报和等前面旁路之外,还有 2–3 秒说不清是读取进程自身的墙钟还是 UI 线程忙,因为读取进程只自报计算时间、不含排队和读图。
8. 局限:这些结果不能证明什么?
- 真值只有一段 180 秒、一局,而且是已暴露的开发数据,标注是模型目视。区间边界按每秒 2 帧标,±0.5 秒;画面时间有 ±0.35 秒不确定度。数量牌只对“读出的牌”判对错,被遮挡没读出的牌不算未读;6 个兵种名这段没有面板可核,不计分。
- 三局整局没有真值:6.1 节只说明两种顺序的 SE 输出不同,不说明按画面时间排序后的减员合计就是对的。
- 开销修复没有在实时里测过:6.2 节是离线回放,机器负载两次不同;离线回放会等旁路读完。按离线测量和约 3–4 倍的实时减速推算,每个主读取周期约少 3–4 秒,这只是估计。
- 主读取取的画面仍然偏旧:排序修复只保证顺序,不让旧画面变新。实时模式下要不要让信息页只走旁路、或给主读取让路,是待定的取舍。
- 信息页队列与额度:16 个上限和 58 次主读取额度在长考、频繁开页时都会成为瓶颈,这次没有改。
- 测试通过和逐字节一致只说明修改没有改变保存格式与输出,不是识别准确率。
9. 结论与下一步
实时模式里,读对一个数字只是开始。所有读取挤在一个进程里,快的旁路优先、慢的主读取取旧画面,结果按截取顺序交给 SE,就会把正确的读数排成错误的历史。按画面时间排序以后,3 分钟真值段里 10 条假魔法变化和 4 条重复全部消失,只留下一条真的 +2;整局魔法来回跳在三局里从 68/3/20 次降到 1/0/0 次,剩下的那一次核实是真变化。同一段真值也显示,读出的 HUD 和行动条数字没有错,真正的缺口是采到(21/47)和及时(信息页读数晚到几百秒)。主读取后 App 自身的工作随对局变长,期间读取进程空着却拿不到活;快速编码和旁路放行两处修复在离线回放里把排队 p95 约减半。
下一步:
- 下一次实玩时测两项开销修复的实际效果,并在读取进程收到结果时记一条时间,把“其余 2–3 秒”拆开;
- 重新考虑信息页的排队:16 个上限与挤掉最旧的策略在长考时会丢掉大量页面;
- 对短暂页面复用视频帧流挑帧,而不只靠 0.5 秒一次的场景线索;
- 用另一段实时对局建第二份真值,避免只在一段已暴露的数据上调参。
附录
复现方式
以下路径相对于 olden-era 项目根目录;local_data/ 与 Videos/Captures/ 下是本机数据,不是公开网页。
- 顺序对比:
battle_app/experiments/2026-10-15-live-frame-order/run.py(同一请求,截图时间取自会话日志的submitted),结果在同目录results/。 - 读取开销:
battle_app/experiments/2026-10-15-read-overhead/中的timeline.py(还原每次主读取)、side_waits.py(旁路等待)、profile_steps.py、replay_read.py(按 App 顺序真实接受第 N+1 次读取,可加性能剖析)、encoder_check.py(新旧编码器逐字节比较)。全部经devtools/game_friendly_run.py --cores 2运行。 - 三层真值:
perception/experiments/2026-10-15-live-ground-truth/中的offset.py(对时)、app_readings.py、score.py(L1/L2)、se_compare.py(L3);标注labels.json,结果results/;2 帧每秒原尺寸帧与证据裁图在local_data/perception/2026-10-15-live-ground-truth/。 - 行动结束触发与旁路接入的离线回放:
perception/experiments/2026-10-14-turn-change-trigger/与battle_app/tools/review_offline_video.py。 - 采集计数(e2e-16、e2e-17):
perception/experiments/2026-10-14-capture-audit/的capture_metrics.py。
证据
- 按画面时间排序:
battle_app/experiments/2026-10-15-live-frame-order/README.md(提交9a5b41a6f) - 读取开销调查与修复:
battle_app/experiments/2026-10-15-read-overhead/README.md(调查7bd5989f4,实施b575e15f7) - 3 分钟三层真值:
perception/experiments/2026-10-15-live-ground-truth/README.md(提交50f2f606c) - 离线回放 e2e-16 / e2e-17:
perception/experiments/2026-10-14-capture-audit/README.md - 行动条触发、预览旁路、施法补读:
perception/experiments/2026-10-14-turn-change-trigger/README.md(提交279c2c60c、4a0b2a350等) - 图 1、3、4 来自
local_data/perception/2026-10-15-live-ground-truth/crops/的strip_a.jpg(前 5 行)、hud_a.jpg(前 11 行)、plate_126.jpg;原始会话与录像在Videos/Captures/HeroesOldenEra 2026-10-14 23-58-24-OBS…。
Comments