Turn Protocol v2

battle-context exposes only three input.mode values:

  • selected-targets: execute-turn receives non-empty targetTokenIds.
  • self: no targets are passed.
  • placed-template: no targets are passed; the CLI brings Foundry to the foreground and waits for the DM to place a template during the same call.

Finite enum parameters are orthogonal to target mode, so there is no fourth input.mode. Actions that require an explicit DM choice expose that choice inside battle-context.input:

{
  "mode": "placed-template",
  "required": ["input.selections.effectMode"],
  "selections": [
    {
      "id": "effectMode",
      "type": "enum",
      "required": true,
      "values": [
        { "value": "suppress", "label": "Suppress charmed/frightened" },
        { "value": "indifferent", "label": "Stop hostility" }
      ]
    }
  ]
}

When the DM declares one value, the execute-turn request looks like this:

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

Callers may only use enum values currently listed by battle-context; they do not send action definitions or contract snapshots. execute-turn re-reads the contract from the acting character’s embedded Item/activity and validates it before template placement, Midi workflow, resource consumption, effect creation, and turn advancement:

  • missing required values;
  • illegal or removed enum values;
  • extra selections not declared in the contract.

All such errors return rejected + INPUT_INVALID with no side effects. An expired action ID is a separate ACTION_NOT_FOUND error. The protocol does not show a generic enum picker and never silently picks a default.

Activities that cannot be classified reliably do not appear in the v2 action list. The CLI does not expose none, point, object, or Start/Wait protocols.

See Combat Flow for the full combat loop.

execute-turn and profile-execute-turn automatically bring the Foundry page to the foreground so the same call can wait for template placement; the Agent does not need to decide whether to add --foreground:

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

When local automation QA needs to reproduce a known template drop point, open another CLI call and send a real mouse click at Foundry scene coordinates after the preview appears:

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

This command uses Foundry’s built-in canvas/client coordinate conversion API and returns before/after preview counts, coordinate round-trip error, and the newly created template ID. It is a QA/debug primitive and does not add a new Turn Protocol input type.