﻿# Multistage Execution

Set `runtime.multiStage=true` to run profileset jobs in multistage stages. If you've used autoSimC or similar staged approaches, this is the same idea: run all candidates at low precision first, cull the losers, then re-sim survivors at full precision. The result is the same ranking with less total compute. Jobs without profilesets, or with `multiStage` omitted/false, run in a single pass as normal.

## Stages and Precision

Multistage execution runs up to three stages at target errors of 1.0, 0.2, and 0.05. Between stages, candidates outside the statistical error band of the top performers are culled. If your profile specifies a `target_error` already satisfied by an earlier stage, the remaining stages are skipped. The final stage uses your profile's `target_error` (clamped to the platform safety floor of 0.01) when set, otherwise the stage default of 0.05. The final stage is also the only one where user-specified `iterations` apply.

## Directives Deferred to Final Stage

These directives are automatically held until the final stage: `calculate_scale_factors`, `scale_delta_multiplier`, `center_scale_delta`, `dps_plot_stats`, `report_details`, `scale_only`.

## Single-Run Fallback

Simmit evaluates your input before execution and may fall back to a single-run. The `multiStage.reason` field on the result tells you what happened:

| Reason                                  | Meaning                                                                              |
| --------------------------------------- | ------------------------------------------------------------------------------------ |
| `eligible_profileset_only`              | Multistage ran normally.                                                             |
| `disabled_by_option`                    | `runtime.multiStage` was `false` or omitted.                                         |
| `no_variants_in_input`                  | No `profileset.*` directives found. Multistage requires profilesets.                 |
| `no_profileset_candidates`              | Profileset directives resolved to zero candidates.                                   |
| `below_min_candidates`                  | Fewer than 4 candidates. Culling is not useful at this scale.                        |
| `unsupported_copy_set_only`             | Input uses `copy=`/`set=` blocks without `profileset.*`. Not stage-separable.        |
| `unsupported_mixed_profileset_copy_set` | Input mixes `profileset.*` with `copy=`/`set=` blocks. Not supported for multistage. |
| `unsupported_multi_actor`               | Input declares more than one player actor.                                           |
| `unsupported_stage_sensitive_directive` | Input contains a directive that cannot be safely staged.                             |

## Reading Results

Multistage metadata lives in `result.summary.multiStage`:

**`enabled`** _(boolean)_

`true` if multistage ran, `false` if the job fell back to single-pass.

**`reason`** _(string)_

The routing reason (see table above).

**`stages`** _(array)_

Array of stage objects in execution order. Empty for single-pass runs.

Each entry in `multiStage.stages` is:

**`stage`** _(number)_

Stage number (1-indexed).

**`label`** _(string)_

`initial`, `intermediate`, or `final`.

**`profilesets`** _(number)_

Count entering this stage.

**`culled`** _(number)_

Count eliminated at the end of this stage. The last executed stage reports `0`.

The funnel invariant `stages[i].profilesets - stages[i].culled = stages[i+1].profilesets` holds between adjacent stages. Each profileset in `result.summary.mainActor.profilesets.results` also includes a `stage` field indicating the highest stage it reached. Multistage runs emit artifacts per stage; use `kind + stage` as the stable identity when consuming `result.artifacts`.

---

_HTML version: https://simmit.com/docs/api-advanced/multistage-execution · Full docs index: https://simmit.com/llms.txt_
