Runtime control

This section describes runtime control, application state, and common expected behavior of client applications. Note that all of this is optional. For some applications, state is irrelevant, but applications that implement one or more of the states should probably consider the entire idea of what’s described here.

Included in the RTI contract and client libraries

A typical simulator application can go through the following states, triggered by runtime control messages in parentheses:

Initial -> (Load scenario) Loading -> Ready -> (Start) Running -> (Pause) Paused -> (Start) Running -> (End) End or (Stop) Stopped -> (Play) Playback -> (Pause) Playback Paused -> (Play) Playback -> (End) Playback End or (Stop) Playback Stopped -> (Reset) Initial

To conform to the above state handling, a simulator application should:

  • Initially present a “home screen” - with no environment or simulation models active
  • Load a scenario when receiving the load scenario message, publish geometry and any other static information, but not start the simulation, publish entities or any other dynamic information
  • Start the simulation at time = 0 when receiving the start message
  • Pause the simulation and clock when receiving the pause message
  • Continue the simulation when receiving start while being paused
  • Stop the simulation when receiving an end message
  • Destroy all entities, stop the simulation when receiving a stop message
  • Return to the “home screen” or similar initial state when receiving a reset message

To support playback, a simulator application should:

  • Go into “observer mode” (or whatever is appropriate) when receiving the play message
  • Be able to spawn entities and react appropriately to position and state messages, from other simulators as well as those published by the application itself during simulation
  • Not publish any entity or state information during playback
  • Optionally support simulate-from-playback, which means playing back for a while, pausing and then starting a simulation from that state when receiving a start message

See the runtime control protobuf definition for more reference information.

Scenarios

A scenario typically specifies an environment model, initial position of entities in the world, and possibly pre-defined behavior of entities (the “game mechanics”). A scenario can be loaded right before a simulation starts. If you were to develop a training simulator, there would probably be a scenario designed for each “lesson” or “training session”.

Runtime control helpers

The client libraries include a runtime control helper that takes care of the mechanics described above: it subscribes to the runtime control channel, keeps track of the current state and scenario, and gives you a callback per message — load scenario, start, pause, end, stop, reset, seek, time scale — instead of a protobuf switch. It also declares the runtimecontrol, scenario and timescale capabilities on your behalf, so that tools like the Launcher and the CLI know what your application can do.

The same helper works in the other direction: the same object can publish runtime control, which is what you use when writing a test harness, a scenario driver, or an operator interface that starts and stops a federation.

See runtime control in the client libraries for examples.

Fast-time

Normally a simulation runs in real time: logical simulation time advances together with wall-clock time, optionally scaled by a time scale. In fast-time, logical time is instead advanced as fast as the participating applications can compute it, with no relation to wall-clock time at all.

Fast-time is useful for maximum-throughput batch runs, deterministic and repeatable execution, headless/CI runs, and for performance profiling — measuring how long each application takes to compute a step, and which one is the bottleneck.

Instead of every application keeping its own clock, a fast-time controller owns time and hands it out in steps. The controller is usually the CLI (rti fast), which also configures the time step, limits and timeouts for a run. Participating simulators act as fast-time workers, and everything else — Viewer, Recorder, dashboards — remains passive: those applications just observe the normal runtime state and data streams, and don’t need to know that a run is fast-time at all.

Coordination happens on a dedicated fast-time control channel, separate from runtime control, in a fixed-step barrier loop:

  1. The controller announces a run and its step settings, and the workers acknowledge it.
  2. The controller grants a step, covering a logical time interval [start_time, end_time].
  3. Each worker computes that interval, publishes its results on the normal channels, and reports the step complete.
  4. When all workers have completed the step, the controller grants the next one.

The barrier is what makes the run well-defined: no application is ever ahead of another, so results don’t depend on how fast each machine happens to be. A worker that fails to complete a step, or times out, aborts the run — the controller stops granting steps and the runtime state goes to paused or stopped, visible to passive clients as usual.

The ordinary runtime control states still apply during a fast-time run — a run is still loaded, started, paused and stopped in the usual way, and passive clients see running just like in real time. Fast-time only replaces how time advances while running.

A consequence of stepping is that message handling has to be disciplined: an application shouldn’t change its simulation state from a message callback in the middle of a step, since that would make the run non-deterministic. The client libraries handle this by buffering incoming messages while a step is in progress and delivering them at the start of the next step. Runtime control itself is exempt, so that stop and reset always get through immediately.

Fast-time stepping is currently fixed-step only. More flexible conservative time management — letting a worker request advancement to a specific time, or to its next event — is a possible future addition.

See the fast-time control protobuf definition for reference, and fast-time control in the client libraries for how to make an application a fast-time worker.


Copyright © Inhumate AB 2026