# Runtime Lifecycle The engine executes in a staged runtime model with two phases: authoring and stepping. ## Startup and Shutdown Construct a {cpp:struct}`RuntimeConfig ` or {py:class}`RuntimeConfig `, then initialize the runtime with {cpp:func}`Runtime::initialize ` or {py:meth}`Runtime.initialize `. Handle an unsuccessful initialization result before authoring a scene. Call {cpp:func}`Runtime::shutdown ` or {py:meth}`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. | C++ | Python | | --- | --- | | {cpp:struct}`RuntimeConfig ` | {py:class}`RuntimeConfig ` | | {cpp:struct}`SceneLayoutDesc ` | {py:class}`SceneLayoutDesc ` | | {cpp:func}`Runtime::initialize ` | {py:meth}`Runtime.initialize ` | | {cpp:func}`Runtime::getWorld ` | {py:meth}`Runtime.world ` | | {cpp:func}`World::createEntity ` | {py:meth}`World.create_entity ` | 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. | C++ | Python | | --- | --- | | {cpp:func}`Runtime::prepare ` | {py:meth}`Runtime.prepare ` | | {cpp:func}`Runtime::uploadWorld ` | {py:meth}`Runtime.upload_world ` | ::::{tab-set} :::{tab-item} C++ ```cpp Runtime runtime; runtime.initialize(config); World& world = runtime.getWorld(); // Register entities, components, constraints, and sensors. runtime.prepare(); runtime.uploadWorld(); ``` ::: :::{tab-item} Python ```python 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. | C++ | Python | | --- | --- | | {cpp:func}`Runtime::stepPhysics ` | {py:meth}`Runtime.step_physics ` | | {cpp:func}`Runtime::stepSimulationSensors ` | {py:meth}`Runtime.step_simulation_sensors ` | | {cpp:func}`Runtime::stepVisualSensors ` | {py:meth}`Runtime.step_visual_sensors ` | | {cpp:func}`Runtime::executeCustomComputePass ` | {py:meth}`Runtime.execute_custom_compute_pass ` | | {cpp:func}`Runtime::endFrame ` | {py:meth}`Runtime.end_frame ` | ::::{tab-set} :::{tab-item} C++ ```cpp 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); } ``` ::: :::{tab-item} Python ```python 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 {doc}`custom GPU computations ` to be interleaved with simulation in a straightforward manner. For a complete runnable-style example, see {doc}`../getting-started/first-scene`.