Body, Mind & Soul — API Reference
    Preparing search index...
    userChoice: {
        allowedTargetScopes: string[];
        configPartial: string;
        execute: (outcome: any, context: any) => Promise<void>;
    }

    Prompt the subject's controller to pick one of several author-defined options, then run that option's own nested outcome list against the same execution context. This is the "User Choice" meta outcome — a second promptFor consumer alongside summonNpc/scryArrange/playAnimation, but routed through _renderUserChoice (prompt-renderers.mjs) instead of a bespoke Application.

    Config: promptTitle string | null — optional dialog heading; falls back to a sensible default (referencing the subject's name) when unset. sampleCount number — 0 (default) preserves today's behavior: prompt with every configured option. Any value > 0 does NOT skip the prompt — it randomly narrows options down to that many DISTINCT entries (sampling without replacement — Math.random(), matching this registry's existing convention for applyDamage's type: "random" damage-type pool) and prompts with ONLY that narrowed subset, via the exact same promptFor/_renderUserChoice flow used when not sampling. The human (player/GM) still makes the actual choice, from a smaller randomly-drawn pool instead of the full option list — this is a pre-filter on the choice SET, never a bypass of the human prompt. This is authored at design time (a trigger outcome config, edited once, fired many times) — not a runtime/per-call override, matching the 0-means-"feature off" numeric-field convention already used by changeVital's max field elsewhere in this file, rather than a separate enable-flag-plus-count pair. If sampleCount exceeds (or equals) the number of configured options, it's silently capped at options.length (console warning logged when it strictly exceeds) and the prompt simply shows the full pool — matching this file's general cap-with-warning handling for out-of-range counts (see useAction's recursion-depth cap). options Array<{ id string — foundry.utils.randomID() name string — short label shown on the choice button description string — longer text shown under the name outcomes object[] — plain-object outcome entries { id, order, type, target, config }, same shape as TriggerOutcomeModel fields but never backed by an EmbeddedDataField. Deliberately NOT nestable — a userChoice inside an option's outcomes is rejected by the config UI, not by this executor. }>

    Only { id, name, description } per option crosses into the prompt spec sent to promptFor — the nested outcomes arrays never leave the GM/ executor client, since they're plain data (not sanitized for socket transport) and only ever need to run locally once a choice comes back. promptFor is always called — cfg.sampleCount > 0 only changes which options are included in the spec's options array (the narrowed subset instead of the full pool); it never skips the call itself.

    On response, the single chosen option's outcomes runs through _runOutcomeList against the same context (so NegateSignal, context._actorUpdateBatch, and context.outcomeResults all compose with the rest of the trigger's outcome list). Stamps context.outcomeResults.userChoice[subject.id] = { chosenOptionId, chosenOptionName } — exactly one option is ever chosen (by the human), regardless of whether the pool was narrowed by sampleCount first, so the result shape stays singular.

    Type Declaration

    • allowedTargetScopes: string[]
    • configPartial: string
    • execute: (outcome: any, context: any) => Promise<void>