Turn Protocol v2

battle-context 只公开三种 input.mode

  • selected-targetsexecute-turn 传非空 targetTokenIds
  • self:不传目标;
  • placed-template:不传目标,CLI 自动置前 Foundry,并在同一次调用里等待 DM 放置模板。

有限枚举参数与目标模式正交,不会产生第四种 input.mode。需要 DM 明确选择的 action 会在 battle-contextinput 中同时给出:

{
  "mode": "placed-template",
  "required": ["input.selections.effectMode"],
  "selections": [
    {
      "id": "effectMode",
      "type": "enum",
      "required": true,
      "values": [
        { "value": "suppress", "label": "压制魅惑/恐慌" },
        { "value": "indifferent", "label": "停止敌对" }
      ]
    }
  ]
}

DM 明确声明其中一个值时,execute-turn 请求写成:

{
  "actionId": "a2_ActionId",
  "input": {
    "selections": {
      "effectMode": "suppress"
    }
  },
  "advance": false
}

调用方只能使用 battle-context 当前列出的枚举值,不发送 action 定义或 contract 快照。execute-turn 会从当前行动角色的 embedded Item/activity 重新读取契约,并在模板放置、Midi workflow、资源消耗、Effect 创建和回合推进之前校验:

  • 缺失必填值;
  • 非法或已经从当前枚举移除的值;
  • contract 未声明的额外 selection。

上述错误统一返回 rejected + INPUT_INVALID,且没有副作用。过期的 action ID 不属于 selection 错误,返回 ACTION_NOT_FOUND。当前协议不弹出通用枚举选择 UI,也不静默选择默认值。

无法可靠归类的 activity 不出现在 v2 action 列表中。CLI 不公开 nonepointobject 或 Start/Wait 协议。

相关战斗原语

完整战斗流程见 标准战斗流程

execute-turnprofile-execute-turn 会自动把 Foundry 页面置前,以便同一次调用可以等待 DM 放置模板;无需再由 Agent 判断是否添加 --foreground

npm run fvtt:cdp -- --port 9230 --target-url autofvtt.criticalrole.top execute-turn --json '@turn.json'

本地自动化 QA 需要复现一次已知模板落点时,可以另开一个 CLI 调用,等待模板预览出现后按 Foundry 场景坐标发送真实鼠标点击:

npm run fvtt:cdp -- --port 9230 --target-url http://127.0.0.1:30000 canvas-click --x 1584 --y 1368 --wait-preview 30000

该命令通过 Foundry 自带的 canvas/client 坐标转换 API 换算落点,并返回预览前后数量、坐标往返误差和新建模板 ID。它是 QA/调试原语,不增加 Turn Protocol 的输入类型。