Work / Game Companion Tool
黑流树海记牌器 明日方舟集成战略的战斗情报悬浮窗
只读游戏画面的置顶悬浮窗:进关前给出这一关的出怪情报,战斗中倒计时下一波从哪个口来什么,战后记下漏怪。
- Role
- 个人项目
- Year
- 2026
- Tech
- C# / .NET · WPF · OCR(ONNX) · 解包数据
- Status
- 开发中
演示实录,约 3 分 20 秒,无声:右侧窄窗是记牌器,左侧是游戏窗口。这里是压缩到 720p 的版本。
概览
明日方舟 PC 端集成战略「沉沦者的黑流树海」的置顶悬浮窗。它只看游戏画面,自动记下藏品、资源和走过的节点;更重要的是战斗情报——进关前告诉你这一关会来什么,战斗中告诉你下一波什么时候、从哪个口、来什么,打完记下漏了谁。
集成战略里一场战斗翻车,整局就白打了。社区已经有解决“地图怎么走”的工具,这个项目解决的是另一半:这一仗怎么不翻车。
设计原则:只给信息,不给打法
这类工具最容易越界,所以先把边界定死:
- 只读画面:用
PrintWindow截取游戏窗口。不读内存、不抓包、不注入,也不向游戏发送任何输入 - 只给信息,不给打法:不推荐部署位置,不代打。“哪里该放谁”仍然是玩家自己的判断
- 低占用:玩家开着它打游戏,它不能把游戏拖慢
第三条决定了很多技术选择:非战斗时画面静止才做整图识别;进入战斗后只以 5 fps 读几个小区域;OCR 限 2 个线程并关掉忙等。
战前情报
在地图上点开一个作战节点,记牌器识别出关卡名,自动切到“情报”页:
- 敌人总数(有随机组时给出区间)、波次数
- 地形缩略图:高台、地面、出怪口、保护点
- 需要注意的敌人:精英、不可阻挡、飞行、隐匿等特性,首次出现的波次、时间和入口,数值按保密等级与藏品换算
- 普通 / 紧急作战的差异,以及条件出现的敌人
- 打过的关卡还会显示我自己的记录:打过几次、输过几次、平均掉几点生命、通常漏在哪一波
![]()
战斗中:出怪条
进入战斗自动切换成一条出怪条:当前波次、击杀计数、下一批敌人的倒计时与入口;同一组敌人间隔出现时显示“每 N 秒 1 个”和剩余数量;宝物怪和精英会提前提示。
![]()
难点:从截图里读出游戏内时间
倒计时要准,前提是知道“游戏里现在是第几秒”。但游戏会暂停、会开 2 倍速、拿起干员卡时会进入慢动作,现实时间完全不可用。
我找到的时钟是费用条:费用按游戏时间自然回复,费用条的进度随游戏时间连续增长。
- 只用进度的增量:部署扣费、技能回费、先锋产费都是跳变,不影响连续的那一部分;异常读数直接剔除
- 费用到 99 封顶后进度条不动了,就改看倍速按钮(1X / 2X / 无字样即选人慢动作)按倍速外推,并在界面上给出误差上限
- 波次用击杀计数推进,同一读数连续两帧才采信;关卡用战前识别到的关卡名加战斗首帧的敌人总数相互核对
实测:在 180 秒的脚本(1X、暂停、2X、费用封顶)里,5 fps 实时跟踪的时钟误差不超过 0.35 秒;按 2 秒间隔回放三段录像,误差在 ±2 秒内。
战后复盘与个人关卡档案
战斗结束后记下这一场:关卡、胜负、掉了几点生命、漏怪发生在第几波第几秒,以及推测漏的是谁。这些记录累积成个人关卡档案,下一次进同一关时出现在战前情报里,情报页还会列出“鬼图榜”。
![]()
记牌
非战斗时它也在记:目标生命、护盾、希望、源石锭、行动力自动读取;239 件藏品按图鉴分类显示已获得和未出现;三条结局线的条件进度;所有变化写进本局时间线,可以删除、Ctrl+Z 撤销。
![]()
怎么做的
| 部分 | 做法 |
|---|---|
| 关卡数据 | 解析官方解包的 68 个关卡文件:地形、路线、波次与片段,含随机方案、条件组、分支、紧急版替换与倍率;302 名敌人的分等级数值与特性;保密等级与藏品对敌人的修正(解析官方说明文字) |
| 画面识别 | PP-OCRv5(ONNX)+ 固定区域读数;整图 OCR 关键字判断界面类型 |
| 应用 | C# / .NET,WPF 悬浮窗,可单文件发布 |
| 验证 | 每个阶段都写验收报告,首验不通过就返工再复验;实机端到端测试记录在仓库里 |
开发按阶段推进:数据管线 → 战斗时钟 → 战前情报 → 出怪条 → 复盘与档案 → 打磨发布。计划里还有一个“在战场上画出怪口箭头和路线”的叠加层,因为格子投影需要更多实机标定,这一轮跳过了。
已知限制
- 只在 1918×1009 / 1920×1080 窗口验证过;其他分辨率按比例换算,未实测;不支持模拟器
- 第 2 层以后的关卡、紧急作战、领袖战还没有实机验证
- 漏怪来源只是推测:敌人受伤后退、被阻挡、技能位移都会改变抵达时间,离线无法精确预测
- 选人慢动作只在费用未封顶时能精确计时;封顶后按估计速率外推,界面会提示误差
- 保密等级需要手动设置一次