Runtime Lifecycle#

The engine executes in a staged runtime model with two phases: authoring and stepping.

Startup and Shutdown#

Construct a RuntimeConfig or RuntimeConfig, then initialize the runtime with Runtime::initialize or Runtime.initialize. Handle an unsuccessful initialization result before authoring a scene.

Call Runtime::shutdown or Runtime.shutdown when resources must be released before the runtime object reaches the end of its lifetime. In C++, the Runtime destructor calls shutdown(), so an explicit call is normally unnecessary.

Scene Authoring#

A scene is configured by registering entities, components, and physics constraints through the C++ or Python API. Supply the scene-layout capacities in RuntimeConfig when initializing the runtime; the runtime applies that layout before any entities are authored. Each entity is created with the environment index to which its simulation and rendering state belongs.

After authoring a scene, call prepare() and then uploadWorld() before physics or custom-compute execution. prepare() updates render resources and other prepared state; uploadWorld() synchronizes the physics and GPU scene. Repeat that sequence whenever host-authored structural state changes. It is not required for an otherwise unchanged steady-state frame.

Runtime runtime;
runtime.initialize(config);

World& world = runtime.getWorld();
// Register entities, components, constraints, and sensors.

runtime.prepare();
runtime.uploadWorld();
runtime = neo.Runtime()
runtime.initialize(config)

world = runtime.world()
# Register entities, components, constraints, and sensors.

runtime.prepare()
runtime.upload_world()

Frame Stepping#

Once initialized, the runtime steps through a steady-state frame execution loop:

  1. Data upload writes dynamic updates, such as kinematic target transforms or user inputs, into device buffers when those updates are needed.

  2. Physics step dispatches the HLSL PBD physics solvers for rigid-body and deformable constraints, collisions, and other physics work on the GPU.

  3. Sensor and rendering step processes cameras and simulation sensors, such as ultrasound synthesis, and writes to GPU render targets.

  4. Optional user-defined custom compute passes are dispatched for custom tasks, such as post-processing, data packaging, and post-physics calculations. After the world has been uploaded, they can be inserted where their inputs are current.

  5. Frame finalization submits and finalizes frame work, presents when enabled, and completes any queued data readbacks.

while (running) {
    runtime.stepPhysics(frame);
    runtime.stepSimulationSensors(frame);
    runtime.stepVisualSensors(frame);

    // Optional: insert custom compute where the task requires it.
    runtime.executeCustomComputePass(customPass);

    runtime.endFrame(frame);
}
while running:
    runtime.step_physics(frame)
    runtime.step_simulation_sensors(frame)
    runtime.step_visual_sensors(frame)

    # Optional: insert custom compute where the task requires it.
    runtime.execute_custom_compute_pass(custom_pass)

    runtime.end_frame(frame)

This design makes synchronization boundaries explicit and allows custom GPU computations to be interleaved with simulation in a straightforward manner.

For a complete runnable-style example, see First Scene.