menu_bookDocumentation

Scene Tick Order: Full Frame Pipeline — FixedUpdate, Update, PreRender, ProcessDeletes, and Stage Hooks

calendar_today May 4, 2026 schedule ~2 min read person patrickjr verified 50

Scene Tick Order: The Full Frame Pipeline

Understanding the exact order of operations in a scene tick is critical for writing correct game logic.

Game Tick Order (Scene.GameTick)

  1. UpdateTime( timeDelta ) — advances TimeNow and TimeDelta (scaled by TimeScale)
  2. SyncContext.FrameStage.Update.Trigger() — async frame stage
  3. Fixed Update loop (if ProjectSettings.Physics.UseFixedUpdate):
- FixedUpdateInputContext.Flip() — flip input context for fixed update - Signal( Stage.StartFixedUpdate ) - RunPendingStarts() — call OnStart on any components that haven't had it yet - OnFixedUpdate() on all IFixedUpdateSubscriber components - Signal( Stage.PhysicsStep ) — physics simulation runs here - Nav_Update() — navmesh update - ProcessDeletes() — destroy queued objects - Signal( Stage.FinishFixedUpdate )
  1. ProcessDeletes() — destroy queued objects
  2. Signal( Stage.StartUpdate )
  3. InternalUpdate():
- RunPendingStarts() — call OnStart on pending components - Signal( Stage.Interpolation ) — transform interpolation - OnUpdate() on all IUpdateSubscriber components
  1. Signal( Stage.UpdateBones )
  2. PreRender() — OnPreRender() on all pre-render components (skipped if headless)
  3. ProcessDeletes()
  4. Signal( Stage.FinishUpdate )
  5. SoundHandle.FlushCreatedSounds()
  6. SyncContext.FrameStage.PreRender.Trigger()

Key Insights

GameObjectSystem Stage Hooks

GameObjectSystem can hook into any stage:
CSHARP
public class MySystem : GameObjectSystem<MySystem>
{
    public MySystem( Scene scene ) : base( scene )
    {
        Listen( Stage.StartUpdate, 0, OnStartUpdate, "MySystem.OnStartUpdate" );
        Listen( Stage.PhysicsStep, 0, OnPhysicsStep, "MySystem.OnPhysicsStep" );
        Listen( Stage.FinishUpdate, 0, OnFinishUpdate, "MySystem.OnFinishUpdate" );
    }

    void OnStartUpdate() { /* runs before OnUpdate on all components */ }
    void OnPhysicsStep() { /* runs during fixed update, after component FixedUpdate */ }
    void OnFinishUpdate() { /* runs after all OnUpdate calls */ }
}

The order parameter controls priority within a stage (negative = before default, positive = after).

Was this helpful?