MaaAssistantArknights 战斗流程协议(Copilot JSON)字段详解与源码实现解析
【免费下载链接】MaaAssistantArknights《明日方舟》小助手,全日常一键长草!| A one-click tool for the daily tasks of Arknights, supporting all clients.项目地址: https://gitcode.com/GitHub_Trending/ma/MaaAssistantArknights
MaaAssistantArknights(MAA 明日方舟小助手)的“作战协议”(Copilot)是一套以 JSON 文件描述的关卡自动战斗流程:作者把一份作业(攻略)翻译成“编队要求 + 按顺序执行的操作列表”,放到resource/copilot/目录下,小助手即可自动编队、按条件时机部署干员、开技能、撤退、变速,直至战斗结束。本文基于协议文档 docs/zh-tw/protocol/copilot-schema.md 与核心解析源码 CopilotConfig.cpp,完整覆盖协议的每个字段、默认值与取值范围,并结合仓库内真实作业文件 OF-1_credit_fight.json 给出可运行的示例解读,帮助你读懂、校验乃至编写自己的作战协议。
需要特别注意:JSON 文件本身不支持注释。协议文档中的注释仅为字段说明,实际提交的作业文件中不能包含//注释,否则会导致解析失败。
一、协议文件的存放位置与任务入口
作战协议文件统一放在resource/copilot/目录下(按关卡名称建子目录归档,仓库中已内置了多套保全派驻作业,例如 SSS_施佩尔山脚_逻各斯+圣聆初雪+浊心斯卡蒂_冷爆机.json)。
从源码结构看,协议由 CopilotTask.cpp 统一入口加载:任务参数支持copilot_file指定单个协议文件名,也支持copilot_list传入多个文件名以启用多作业插件MultiCopilotTaskPlugin连续执行。解析工作则全部委托给单例配置类 CopilotConfig,其parse()依次调用三个静态解析函数:
parse_basic_info():解析stage_name与doc描述信息;parse_groups():解析opers(单个干员列表)与groups(干员分组);parse_actions():解析有序动作列表actions。
解析失败(如干员名在干员数据中不存在且配置了非法练度要求)时parse_groups()返回空,整个协议加载即视为失败——这解释了为什么作业中干员名称必须与游戏内数据严格一致。
二、顶层字段一览
一份完整的协议文件顶层结构如下(注释为说明,实际文件不可带注释):
{ "stage_name": "暴君", // 关卡名称,必填。关卡中文名、code、stageId、levelId 等,只要能唯一识别均可 "opers": [ // 指定干员(与 groups 二选一或并用) { "name": "重岳", "role": "guard", // 职业,选填,用于区分同名干员,填英文职业名,大小写不限 "skill": 3, // 技能序号,选填,默认 0,取值范围 [0, 3] "skill_usage": 2, // 技能用法,选填,默认 0,含义见下文 "skill_times": 5, // 技能使用次数,选填,默认 1 "requirements": { // 练度要求,自动编队时验证,选填 "elite": 2, // 精英化等级,选填,默认 -1 即不作要求 "level": 90, // 干员等级,选填,默认 -1 "skill_level": 10, // 技能等级,选填,默认 -1 "module": 1, // 模组编号,选填,默认 -1;0 表示不使用模组,1-4 对应不同编号的模组 "module_level": 3, // 模组等级,暂不支援 "potential": 1 // 潜能要求,暂不支援 } } ], "groups": [ { "name": "任意正常群奶", // 分组名称,必填 "opers": [ // 组内干员任选其一,无顺序要求,优先选练度高的 { "name": "夜莺", "skill": 3, "skill_usage": 2 }, { "name": "白面鸮", "skill": 2, "skill_usage": 2 } ] } ], "actions": [ /* 有序动作列表,必填,见下文各节 */ ], "minimum_required": "v4.0", // 最低要求 MAA 版本号,必填 "doc": { // 描述信息,选填,用于界面展示 "title": "低练度高成功率作业", "title_color": "dark", "details": "对练度要求很低……", // 建议写上作者名称、参考的视频攻略出处 "details_color": "dark" }, "difficulty": 0 // 作业对应难度,选填,默认 0 }字段要点:
stage_name:必填,是作业在界面上展示与匹配的关卡标识,中文名、code、stageId、levelId 均可,保证唯一即可。parse_basic_info()中通过json.at("stage_name")强取该字段,缺失会直接抛异常;minimum_required:必填,声明该作业要求的最低 MAA 版本,用于提醒用户当前客户端版本是否兼容;doc:title/title_color/details/details_color四个字段全部选填,仅在协议预览界面展示,不影响战斗逻辑;difficulty:选填,默认 0,取值 0 未设置 / 1 支援普通难度 / 2 支援突袭难度 / 3 普通与突袭均支援。
三、干员用法字段:opers 与 groups
3.1 单个干员条目
name必填。role选填,填英文职业名(如guard),用于区分同名干员;解析时大小写不敏感,AsstBattleDef.h 中get_role_type()同时兼容Guard/GUARD/近卫等写法并归一到Role::Warrior等枚举。
skill选填,默认 0,取值[0, 3],0 表示使用默认技能或上次编队技能。源码在parse_oper_usage()中做了一道稀有度兼容性校验:
- 稀有度低于 6 星的干员填
skill: 3(非阿米娅)会被强制改回 0; - 稀有度低于 4 星填
skill: 2会被强制改回 0; - 稀有度低于 3 星填
skill: 1会被强制改回 0。
这是为兼容古早作业中“超规格”技能编号的兜底逻辑,运行时会在日志中打印错误说明。
skill_usage选填,默认 0,对应枚举SkillUsage:
| 取值 | 枚举 | 含义 | 典型例子 |
|---|---|---|---|
| 0 | NotUse | 不自动使用,完全依赖actions中的“技能”动作 | 全自动触发技能填 0 |
| 1 | Possibly | 好了就用,有多少次用多少次 | 棘刺 3 技能、桃金娘 1 技能 |
| 2 | Times | 使用 X 次,次数由skill_times控制 | 山 2 技能用 1 次、重岳 3 技能用 5 次 |
| 3 | InTime | 自动判断使用时机(画饼,尚未落地) | — |
skill_times选填,默认 1,仅在skill_usage: 2时决定实际释放次数。
3.2 练度要求 requirements
requirements全部选填,默认 -1(不作要求):elite(精英化)、level(等级)、skill_level(技能等级)、module(-1 无要求 / 0 不使用模组 / 1-4 对应不同编号的模组)、module_level与potential暂不支援。
parse_oper_usage()中还有两条推断规则值得注意:
skill_level > 7(即要求专精)时,精英化要求至少提升到 2;skill_level > 4时至少为 1;module > 0(要求携带模组)时,精英化要求至少提升到 2(模组系统仅精二开放);- 若显式指定的
elite低于上述推断值,解析会记录错误并整体拒绝该干员(返回nullopt),避免编队阶段出现“等级够了但技能等级永远达不到”的死锁。
3.3 分组 groups:自动在多个候选干员中择一
groups用于表达“任意一个都可以”的岗位,例如“夜莺或白面鸮任一作为群奶”。每个组必须有name(组名),opers列出候选干员(字段与 3.1 完全一致)。自动编队时会在组内优先选择练度高的干员;组名随后直接作为actions中name字段的引用值(如"name": "任意正常群奶")。
从源码看,parse_groups()会为每个组计算elite_min/level_min(取组内最低精英化/等级门槛,精一 80 级、精二 70 级的经验下限参与比较),供编队界面展示与筛选。另外,顶层opers数组中的单个干员会被自动包装为以干员名命名的组,因此在动作引用层,单个干员与分组是统一处理的——actions里的name既可以是干员名,也可以是组名。
四、actions:动作类型全表
actions是协议的核心:有序数组,执行完前一条才会开始处理下一条。每个动作的type选填,默认"Deploy";中英文写法效果相同。完整的字符串到ActionType枚举的映射定义在parse_actions()的ActionTypeMapping表中,摘录如下:
| 枚举 | 英文写法 | 中文写法 | 行为说明 |
|---|---|---|---|
| Deploy | Deploy | 部署 | 部署干员;费用不足时一直等待(直到 timeout) |
| UseSkill | Skill | 技能 | 开技能;CD 未转好时一直等待(直到 timeout) |
| Retreat | Retreat | 撤退 | 撤退干员/召唤物 |
| SwitchSpeed | SpeedUp | 二倍速 | 可切换:第一次使用进入二倍速,再次使用回到一倍速 |
| BulletTime | BulletTime | 子弹时间 | 点击任意干员后的 1/5 速度,后续任意 action 恢复正常速度 |
| SkillUsage | SkillUsage | 技能用法 | 运行时修改某干员的技能用法 |
| Output | Output | 输出/打印 | 不执行任何操作,仅输出doc内容(可作字幕) |
| SkillDaemon | SkillDaemon | 摆完挂机/开摆 | 只做“好了就用”的开技能,其余不做,直到战斗结束 |
| ResetStopwatch | ResetStopwatch | 重置全局计时器 | 重置全局计时器(实验性功能,见 elapsed_time) |
| MoveCamera | MoveCamera | 移动镜头 | 用于「引航者试炼」模式,需填distance |
未知type会打印Unknown action type警告并跳过该条动作(不中断后续流程),编写时务必核对拼写。此外源码中还存在DrawCard(抽卡/调配干员)与CheckIfStartOver(检查重开)两个类型,从源码结构看它们是保全派驻(SSS)专用扩展,配合resource/copilot/下大量SSS_*.json作业使用,普通关卡作业不需要。
子弹时间(BulletTime)的使用细则
name或location必填一项,表示点击哪个干员进入 1/5 速度,战场已部署与待部署区的干员均可(自动判断);- 若下一条动作是“技能”或“撤退”,需填与下一条动作相同的
name/location; - 若下一条动作是“部署”,随便填谁都可以,但不建议填待部署的那位——头像被点击会影响后续头像辨识。
技能用法(SkillUsage)的典型场景
配合skill_usage/skill_times字段使用:例如刚下场的桃金娘需要普攻打几个怪,不能自动开技能;中后期阵型平稳后改为自动开技能,则可在对应时刻插入一条"type": "技能用法"的动作将其改为 1。
移动镜头(MoveCamera)
仅「引航者试炼」模式需要,必填distance字段:[x 移动格子数, y 移动格子数],可为小数、可为负;x 为正表示镜头右移,y 为正表示镜头上移。例如"distance": [-1, 1]配合"location": [5, 6],实际部署落点会是[6, 7]——即坐标是移动后的相对结果。
五、actions:触发条件字段(与的关系)
一条动作可以带多个触发条件,当前全部条件之间是逻辑与(&&)关系,全部满足才执行该动作;未满足则持续轮询等待。源码中五个条件字段的默认值如下:
| 字段 | 默认值 | 说明 |
|---|---|---|
kills | 0(直接执行) | 击倒数条件,未达标则一直等待 |
costs | 0(直接执行) | 部署费用条件;费用受潜能等影响可能不完全准确,仅适合对时间轴要求不严格的战斗。另外仅两位数费用辨识较准,三位数费用可能辨识错,不推荐 |
cost_changes | 0(直接执行) | 费用变化量条件,从本动作开始执行时(即上一动作结束时的费用)作为基准起算,支援负数(如“孑”等吸费干员使费用下降)。同样仅两位数辨识可靠 |
cooling | -1(不辨识) | CD 中(再部署冷却)干员数量条件 |
elapsed_time | 0(直接执行) | 毫秒级全局计时条件;使用前必须先执行过ResetStopwatch动作重置计时器,否则该条件无法满足会卡住 |
对费用精确敏感的作业建议优先用cost_changes(增量辨识)而非costs(绝对值辨识)。文档中亦保留了condition_type(0 且 / 1 或)的 TODO 规划,尚未实装,编写时不要引用。
六、actions:目标与位置字段
name:干员名或组名。“部署”时必填;“技能”“撤退”时选填;role:职业,选填,用于区分同名干员;location:[x, y]格子坐标。“部署”时必填;“技能”“撤退”时选填。推荐用法:- 技能:仅推荐给场地自动装置一类不填
name、用location点击开启的场景;正常部署的干员推荐用name开技能; - 撤退:仅推荐给存在多个同名召唤物时需要按位置区分撤退的场景;正常干员推荐用
name撤退。 - 坐标可在地图工具中将「座标展示」切换为「MAA」后读取,即为 MAA 使用的坐标体系;
- 技能:仅推荐给场地自动装置一类不填
direction:部署朝向,“部署”时必填,"Left" | "Right" | "Up" | "Down" | "None"(或中文 左/右/上/下/无),缺省时默认Right(见string_to_direction()的兜底返回值)。无人机等无方向单位用None。
七、actions:时序控制字段
pre_delay:前置延时,选填,默认 0,毫秒。所有条件满足后开始计时,计时结束后才执行动作;post_delay:后置延时,选填,默认 0,毫秒。动作执行完成后计时,结束后再进入下一动作。源码还兼容历史遗留字段rear_delay(当post_delay不存在时回退读取);timeout:超时时间,选填,默认 -1 即不限制,毫秒。条件与pre_delay完成后开始计时,等待超时则放弃当前动作直接进入下一个;值为 0 时只检查一次不等待。旧的skip_if_not_ready字段已弃用——源码中检测到它会打印 DEPRECATED 警告并映射为timeout: 0;若同时设置timeout则整条动作被忽略,新作业请直接写timeout。
一个典型组合是:部署动作费用不足时默认无限等待;给高费用干员部署加"timeout": 30000,可在 30 秒内费用不达标时放弃该步骤继续后续流程,提升作业容错。
八、真实作业解读:OF-1 信用战斗
仓库内置的 OF-1_credit_fight.json 是一份麻雀虽小五脏俱全的协议,完整体现了各字段的协作:
{ "minimum_required": "v4.0.0", "stage_name": "OF-1", "opers": [], "groups": [ { "name": "先锋", "opers": [ { "name": "推进之王", "skill": 2 }, { "name": "风笛", "skill": 2 }, { "name": "凛御银灰", "skill": 3, "skill_usage": 1 }, { "name": "德克萨斯", "skill": 2, "skill_usage": 1 }, { "name": "焰尾" }, { "name": "凛冬" }, { "name": "贾维" }, { "name": "清道夫" }, { "name": "讯使" }, { "name": "芬" }, { "name": "香草" } ] } ], "actions": [ { "type": "SpeedUp" }, { "type": "Deploy", "name": "先锋", "location": [5, 3], "direction": "Right" }, { "type": "SkillDaemon" } ], "doc": { "title": "OF-1 Credit Fight", "details": "OF-1 Credit Fight" } }解读:
groups定义了名为“先锋”的岗位,11 名回费型先锋任选其一(自动选练度最高者),skill: 2指定 2 技能,凛御银灰与德克萨斯额外标注skill_usage: 1(好了就用);- 动作时间轴共三步:先
SpeedUp切二倍速,再在费用足够时(Deploy 默认无限等待费用)把选出的“先锋”部署到[5, 3]、朝右,最后SkillDaemon进入挂机模式——之后只剩“好了就用”的技能自动释放,直到战斗结束。整个过程仅用 3 条 action,是“低练度、低操作”作业的标准范式。
九、界面展示字段:doc 与 doc_color
每条 action 可选填doc(描述文字)与doc_color(文字颜色,如"orange"、"red",默认灰色),仅在协议预览/执行界面展示,无战斗逻辑作用;type: "Output"的动作则专门用于输出doc内容本身(界面不显示该步骤),常被用来做字幕或解说。顶层doc中的details建议写上作者署名与参考攻略出处,方便使用者追溯与致谢。
十、编写与提交协议的注意事项汇总
- JSON 不带注释:文档中的注释仅供阅读,复制模板时必须手工删除;
stage_name、groups[].name(当使用分组时)、部署动作的location/direction、minimum_required是硬性必填项,缺失会导致解析失败或运行时卡死;- 干员名必须与仓库干员数据(
resource/battle_data.json一类数据源,由BattleData配置加载)中的名字一致,否则parse_oper_usage()会告警并降级处理 requirements; - 技能序号受稀有度约束(3 技能需 6 星、2 技能需 4 星+、1 技能需 3 星+),超规格会被静默重置为 0;
elapsed_time必须配合前置的ResetStopwatch动作,否则等待条件永远无法满足;- 三位数部署费用辨识不可靠,费用条件尽量选
cost_changes或避免依赖费用; - 动作顺序即时间轴顺序,
SkillDaemon/摆完挂机一般应放在末尾; - 协议文件放入
resource/copilot/后,通过ParadoxCopilotTask类任务(参数copilot_file或copilot_list)执行;保全派驻场景另有 SSS 专属动作类型(DrawCard、CheckIfStartOver)与SSS_前缀的作业命名惯例可参照。
以上字段与行为均可在 CopilotConfig.cpp 的解析函数与 AsstBattleDef.h 的OperUsage/Action/ActionType定义中逐一对照验证,建议将这份“文档 + 源码 + 真实作业”三者对照作为编写新作业的标准流程。
【免费下载链接】MaaAssistantArknights《明日方舟》小助手,全日常一键长草!| A one-click tool for the daily tasks of Arknights, supporting all clients.项目地址: https://gitcode.com/GitHub_Trending/ma/MaaAssistantArknights
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考