news 2026/10/7 16:15:02

MAA 基建换班三种模式的决策链路与自定义排班 JSON 字段行为

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
MAA 基建换班三种模式的决策链路与自定义排班 JSON 字段行为

MAA 基建换班三种模式的决策链路与自定义排班 JSON 字段行为

【免费下载链接】MaaAssistantArknights《明日方舟》小助手,全日常一键长草!| A one-click tool for the daily tasks of Arknights, supporting all clients.项目地址: https://gitcode.com/GitHub_Trending/ma/MaaAssistantArknights

MAA(《明日方舟》小助手)的基建换班模块负责把干员排进制造站、贸易站、控制中枢等设施,并完成心情恢复与产物切换。本文面向已跑通基础功能、想弄清换班如何决策与如何写自定义排班 JSON 的中高级用户:读完你可以按源码口径解释任意一次换班的执行顺序,并能独立编写、校验自己的排班作业。

从一次点击到换班完成:三种 mode 的执行路径

现象上你在任务设置里选择"常规模式""队列轮换"或"自定义基建配置",其余操作一致。差异全部集中在参数注入阶段:src/MaaCore/Task/Interface/InfrastTask.cpp 的set_params读取mode参数(枚举定义在 src/MaaCore/Task/Interface/InfrastTask.h:Default = 0、Custom = 10000、Rotation = 20000),再据此装配一条子任务链。

mode 值模式参数依赖
0常规(Default)facility、threshold、drones、四个跨设施组合开关
10000自定义(Custom)facility、filename、plan_index
20000队列轮换(Rotation)facility;drones不生效

换班设施列表为什么不是顺序

在常规模式下,facility参数(取值Dorm/Mfg/Trade/Power/Office/Control/Reception/Processing/Training/AssistantChange)在 AsstInfrastDef.h 的build_facility_plan中先被装入std::unordered_set去重,然后按固定顺序输出步骤:制造站巡检 → 宿舍前置轮 → 发电站 → 办公室 → 控制中枢 → 制造站 → 贸易站 → 会客室 → 宿舍重排轮 → 加工站 → 训练室 → 副手换人。也就是说你在 GUI 里调整"换班设施"的顺序不会产生任何效果,顺序由这套固定编码决定。

两个特殊分支:

  • 只启用贸易站未启用制造站时,计划开头插入MfgInspect:制造站以set_inspect_only(true)运行,只读取产物类型与赤金线数量供贸易站评分使用,不进入干员选择、不使用无人机(InfrastTask.cpp构造函数与build_facility_plan注释)。
  • 宿舍前置轮DormPrepare在常规模式下仅当fiammetta_recovery_enabled为 true 时才执行,否则整步跳过;宿舍重排轮DormRearrange不受影响,始终清空宿舍后按心情升序安置低心情干员。

触发条件 → 处理 → 结果的降级逻辑:facility中出现未知字符串,或某项不是字符串时,set_params会清空已装配的子任务、只保留进入基建入口任务,并返回 false,本次基建换班直接失败。

常规模式下的菲亚梅塔心情恢复走的是常驻m_dorm_task_ptr(prepare 相位):fiammetta_targets经infrast::normalize_fiammetta_targets规范化(最多 3 名),换班开始时挑当前心情最低的目标与菲亚梅塔同进宿舍互换,再把目标换出。这与自定义模式由 JSON 注入的临时宿舍任务(见后文)是两条独立实现。

验证方法:常规模式下只勾选贸易站与宿舍,观察EnterFacility回调序列,会依次出现 Mfg(巡检)→ Dorm → Trade → Dorm,与勾选顺序无关;把fiammetta_recovery_enabled关掉后,前置宿舍轮不再出现。

队列轮换与自定义模式的装配差异

队列轮换(mode=20000)走build_facility_plan的另一分支:步骤按facility的声明顺序输出(该分支保留数组顺序),但Dorm、Power、Office、Control四类设施被rotation_skips集合整体跳过;制造站、贸易站、会客室三个任务被set_skip_shift(true),只做轮换不执行换人,并在链首插入InfrastEnterRotation入口任务(set_ignore_error(true),进入失败不阻断后续)。

自定义模式(mode=10000)不读取 GUI 的drones、四个跨设施组合开关(相关代码位于mode != Mode::Custom与default_mode判断之后),全部行为由filename指向的作业文件决定。

决策流:每个设施入口处的筛选、枚举与复核

现象上,MAA 点进每个房间后"自动选了效率最高的干员"。这一句背后是 InfrastProductionTask.cpp 中shift_facility_list()的固定次序:产物识别 → 无人机(pre)→ skip 判定 → 换人(编组匹配 / 自定义选择 / 算法选择)→ 复核 → 确认 → 无人机(post)。

产物识别与无人机触发点

每个房间先按InfrastFlag*模板匹配当前产物,只有得分达到模板阈值才采信(set_product回调ProductOfFacility);识别不可靠时清空m_product,跳过所有依赖产物的分支。常规模式下制造站还会在此处按产物是否赤金更新TaskData::gold_station_num,供后续贸易站评分。无人机按m_custom_drones_config.order分两侧:Pre在换人之前、Post在换人之后触发,且index(已转为 0 基)必须等于当前房间下标才生效。

干员候选如何过滤

opers_detect()滑完整个干员列表,过滤规则是:mood_ratio低于m_mood_threshold(即 GUI 的"基建工作心情阈值",默认 0.3)的干员剔除;脸像哈希距离过近的视为同一干员去重。常规模式下,技能集合无法唯一确定身份时调用resolve_operator_identity做 OCR 确认,身份仍冲突的干员只计通用技能效果,不触发特殊加成与跨设施联动——这就是"识别不出名字的干员不会被误联动"的底层原因。

常规模式如何给组合打分

optimal_calc()在常规模式下构建ScoreContext(设施、产物、空位数、宿舍容量与等级和、赤金线数、发电站数、selected_operator_ids等),调用 InfrastScore.cpp 的select_best_opers做全组合枚举,用score_trade/score_mfg打分取最高分。打分基于 8 小时平均收益近似:不计算心情消耗与换班间隔,概率性效果忽略,部分技能值被手动微调以制造优先级。两个值得注意的规则:

  • 容量防护:max_storage + storage_sum < 20 || storage_sum < -15时组合直接禁选(score_mfg末尾)。
  • only_need机制:巫恋组、温蒂自动化类等特殊组合标记出唯一需要的干员,select_combinations会把其余被选中干员从结果中释放给后续房间使用。

跨设施加成的判定依据是context.selected_operator_ids,例如黑键在贸易站的"怅惘和声"只有在絮雨或迷迭香已被选入其他设施时补 0.44 效率。这份已选集合来自共享的TaskData,干员点进房间时仅stage_operator_selection暂存到 pending,点击确认按钮(click_confirm_button)才真正commit_pending进入全局集合——所以设施间"谁先上"直接受前面提到的固定换班顺序影响。

红松骑士团、感知信息、人间烟火、深海猎人四个参数(use_pinus_sylvestris/use_perception_information/use_worldly_plight/use_abyssal_hunter)只写入m_default_mode任务,自定义模式传了也会被忽略。

验证方法:查看日志中optimal_calc输出的infrastructure optimal score(设施名、分数、选中数);把"基建工作心情阈值"调到 1.0 会看到几乎所有干员被过滤、房间留空。

配置面:自定义排班 JSON 的解析、校验与字段行为

现象上你只改一个 JSON 文件,但它的解析发生在set_params阶段而非运行时:任何解析错误(文件不存在、JSON 非法、plan_index越界、未知product、未知房间键、无人机room取值错误)都会让set_params返回 false,整次基建换班无法启动。⚠️ 因此先验证 JSON 语法再运行,比事后看日志更快。

解析链与失败点

parse_and_set_custom_config的执行顺序(均在 InfrastTask.cpp):校验文件存在且为普通文件 → 打开 JSON → 按plan_index从plans数组取计划 → 录入groups编组 → 遍历rooms把每类设施注入对应任务 → 处理Fiammetta→ 处理drones。其中rooms的键必须命中control/manufacture/trading/power/meeting/hire/processing/dormitory之一,否则整体失败;注意这里的键名与facility参数的取值(Dorm、Mfg等)是两套词表。

换人后的复核(select_opers_review,InfrastAbstractTask.cpp):OCR 已选列表,逐一核销自定义名单,若选中了"工作中"的干员或自定义名单未选全则返回 false,调用方还原原始房间配置并重选。宿舍类房间(is_dorm_order)跳过复核,直接按心情排序进驻。

房间字段与执行时序

房间数组的下标必须与游戏内房间 tab 序号一致(current_room_config()用m_cur_facility_index取配置,越界时该房间起不再换班)。

字段默认值行为要点
skipfalse只跳过换人;产物识别、无人机、线索交流等操作照常
autofillfalse空名单 = 整房走原算法;非空 = 只按单干员效率补位,不算组合
sortfalse仅当选中人数大于 1 时生效;稀音/帕拉斯等需要暖机顺序的干员必须置true
product空取值Battle Record/Pure Gold/Dualchip/Originium Shard/LMD/Orundum;未知值解析直接失败
candidates空备选名单,有谁选谁直到选满;文档声明与autofill: true不兼容
use_operator_groupsfalse启用后operators里写的是编组名,按声明顺序取第一个全员可用的编组
groups(plan 级)空编组定义,仅对 control / manufacture / trading 生效;只装载被引用的编组;匹配失败回调CustomInfrastRoomGroupsMatchFailed
Fiammetta(plan 级)无target经 OCR 识别,为空则整段跳过;order取值pre/post,默认pre
drones(plan 级)无room只接受trading/manufacture;index为 1 基(对应左侧 tab 序号,内部减 1);order默认pre;rule为保留字段,当前无任何代码读取
duration(plan 级)—保留字段,当前版本不产生任何行为

period字段 core 同样不处理,按计划文档说明需接口集成方自行实现按时段选计划的逻辑。产物不一致时触发ProductIncorrect回调(界面红色提示),随后change_product每类产物最多重试 3 次;切换失败只记录警告,不阻断后续换人。

无人机与菲亚梅塔都是pre时,additional_advance_drones触发:在链首插入一个独立的纯无人机任务(目标房间用skip: true占位,只执行use_drone),注释说明"无人机和菲亚梅塔同时为 true 时,优先使用无人机"。菲亚梅塔pre的实现是插入两个临时InfrastDormTask:先把target单独挪出宿舍,再按target+菲亚梅塔的顺序进驻——源码注释解释了原因:若菲亚梅塔本来就在宿舍第二格,直接换不会触发技能,所以强制变位。

最小可用示例与字段速查

{ "title": "基础两班", "plans": [ { "name": "A 班", "drones": { "room": "trading", "index": 1, "order": "pre" }, "rooms": { "manufacture": [ { "operators": ["芬", "稀音", "克洛丝"], "sort": true, "product": "Battle Record" }, { "skip": true } ], "trading": [ { "operators": ["古米", "银灰"], "candidates": ["梅"], "autofill": true } ], "power": [ { "autofill": true } ] } }, { "name": "B 班", "Fiammetta": { "target": "可露希尔", "order": "pre" }, "rooms": { "manufacture": [ { "autofill": true }, { "autofill": true } ], "trading": [ { "autofill": true } ] } } ] }

注释仅为示意,直接复制会报错。rooms里没写的设施(如control、dormitory)使用默认算法换班;想完全不处理某个设施,用房间级skip: true,或在任务设置里取消对应设施勾选。内置作业可参考 resource/custom_infrast/153_layout_3_times_a_day.json,注意其文件头声明干员配置要求极高。

延伸材料

  • 协议文档:docs/zh-cn/protocol/base-scheduling-schema.md
  • 官方手册:docs/zh-cn/manual/introduction/infrastructure.md
  • 任务装配:src/MaaCore/Task/Interface/InfrastTask.cpp
  • 换班计划与设施步骤枚举:src/MaaCore/Common/AsstInfrastDef.h
  • 组合评分:src/MaaCore/Task/Infrast/InfrastScore.cpp
  • 选人与复核:src/MaaCore/Task/Infrast/InfrastAbstractTask.cpp

【免费下载链接】MaaAssistantArknights《明日方舟》小助手,全日常一键长草!| A one-click tool for the daily tasks of Arknights, supporting all clients.项目地址: https://gitcode.com/GitHub_Trending/ma/MaaAssistantArknights

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/7 16:06:38

VS Code扩展开发全家桶Superpowers安装实战与踩坑指南

有段时间我特别想给团队写一个VS Code内部插件&#xff0c;把发布前的检核动作收进去。插件功能本身不难&#xff0c;难的是环境第一次跑通——package.json里那些字段、扩展宿主窗口怎么起、分析工具去哪找&#xff0c;哪个环节出问题都能卡一下午。后来我才知道&#xff0c;微…

作者头像 李华
网站建设 2026/10/7 16:02:02

Modbus字节序解析:用ST语言按位拆解BYTE数组修复浮点数错误

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华