State path and generation
Reset restores the state that preceded the call: RUNNING remains RUNNING and PAUSED remains PAUSED. It changes the generation and world state, with tick starting again at zero.
Prepare creates and checks dependencies; start advances the world; pause takes effect at a complete boundary; single-step advances one step and remains PAUSED; stop ends active execution; close releases every resource. The diagram shows normal paths and omits exceptional and transient states.
Reset starts a new generation and returns tick to zero. Queued writes, control sessions, and subscriptions from the old generation cannot leak into the new world. Read results carry generation so callers can reject stale values.
Asynchronous and synchronous facades
FastSimApplication is the recommended async facade for embedded applications, servers, and plugins. FastSimRun provides a blocking context for scripts and simple CLI integrations. They do not create separate runtimes.
Both facades consume the same ExecutionPlan and expose the same lifecycle states. Applications with an existing event loop use the asynchronous facade; short blocking scripts may use the synchronous context.
Finalization
Stopping is more than closing a backend. Control producers stop submitting, Operations reach terminal state, data plugins flush, outputs validate and publish atomically, and services are revoked. Only then is a Run complete.
Pause never leaves half a control/physics tick, close is idempotent, and failures retain structured results. See Application API and the Python SDK.
Prepare constructs the Provider world, public services, and selected plugin instances without continuous stepping. Start runs; pause preserves an inspectable committed boundary; reset creates a new generation; stop makes the Run terminal; close releases everything owned by the Application.
Pause is not completion, stop is not merely a UI pause, and close is not a process kill. During shutdown the runtime blocks new work, converges or cancels accepted Operations, closes subscriptions, runs plugin finalizers, validates or rejects staging outputs, and only then releases the Provider.
After reset, clients refresh state, capabilities, targets, and subscriptions. Old immutable values may be retained as history, but cannot be used as current-world authority. Late worker results are rechecked and discarded if their generation is stale.
Lifecycle timeouts indicate that a transition was not confirmed within the caller budget; they do not remove the runtime's cleanup obligations. Diagnostics should retain the before/after Application snapshot, run ID, generation, plugin failure records, and Provider error.