Turn Protocol v2
battle-context 只公开三种 input.mode:
selected-targets:execute-turn传非空targetTokenIds;self:不传目标;placed-template:不传目标,CLI 自动置前 Foundry,并在同一次调用里等待 DM 放置模板。
有限枚举参数与目标模式正交,不会产生第四种 input.mode。需要 DM 明确选择的 action 会在 battle-context 的 input 中同时给出:
{
"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 不公开 none、point、object 或 Start/Wait 协议。
相关战斗原语
完整战斗流程见 标准战斗流程。
execute-turn 和 profile-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 的输入类型。
