Skip to main content
A Scene holds all the GameObjects that make up your game world at any given moment. Every s&box game has at least one scene, and you switch between scenes to move players through different areas or game states.

Getting the current scene

Access the active scene from any GameObject, Component, or Panel using the Scene accessor. You can also use the static Game.ActiveScene from anywhere:
var scene = Game.ActiveScene;

Loading a new scene

To replace the current scene with a different one, call Scene.Load:
// Replace the current scene with another scene asset
Scene.Load( myNewScene );

// Load a scene from a file path
Scene.LoadFromFile( "scenes/minimal.scene" );
To load a scene additively on top of the current one, use SceneLoadOptions:
var load = new SceneLoadOptions();
load.SetScene( myNewScene );
load.IsAdditive = true;
Scene.Load( load );
Additive loading keeps the existing scene’s GameObjects alive and layers the new scene on top. Use this for things like loading a persistent UI or shared manager scene.

The scene directory

Every scene has a Directory that indexes all GameObjects by their GUID. Use it for fast lookups when you already know a specific object’s GUID:
var obj = Scene.Directory.FindByGuid( guid );

Querying all components in a scene

The scene maintains a fast component index so you don’t have to traverse the entire hierarchy yourself. Use Scene.GetAll<T>() to iterate over every component of a type, or Scene.Get<T>() to grab a single instance (useful for singletons):
// Tint every model in the scene a random colour
foreach ( var model in Scene.GetAll<ModelRenderer>() )
{
    model.Tint = Color.Random;
}

// Grab your singleton manager
var game = Scene.Get<GameManager>();
Use Scene.Get<T>() as a lightweight singleton pattern — put a single manager component in your scene and retrieve it from anywhere without keeping a manual reference.

Scene systems

Beyond GameObjects and components, a scene can also contain GameObjectSystems — classes that do work at specific points in the frame update cycle. For example, the built-in SceneAnimationSystem resolves all skeletal animations in parallel at a single, well-defined moment each frame. To create your own system, derive from GameObjectSystem and call Listen in the constructor to register work at a specific stage:
public class MyGameSystem : GameObjectSystem
{
    public MyGameSystem( Scene scene ) : base( scene )
    {
        Listen( Stage.PhysicsStep, 10, DoSomething, "DoingSomething" );
    }

    void DoSomething()
    {
        Log.Info( "Did something!" );

        var allThings = Scene.GetAllComponents<MyThing>();
        // do something to all of the things
    }
}
s&box automatically instantiates every defined GameObjectSystem when a scene is created — you do not need to add it manually. If you want to access your system from other code, derive from GameObjectSystem<T> instead. This adds a static T Current property:
public class MyGameSystem : GameObjectSystem<MyGameSystem>
{
    public MyGameSystem( Scene scene ) : base( scene )
    {
    }

    public void MyMethod()
    {
        Log.Info( "Hello, World!" );
    }
}
// Access your system from anywhere
MyGameSystem.Current.MyMethod();

Stages and order

Stages correspond to specific moments in the frame — for example, Stage.PhysicsStep fires during FixedUpdate. The order value controls where within that stage your callback runs: negative values run before the default, positive values run after.

Configuring systems

Mark properties on your GameObjectSystem with [Property] to make them configurable in Project Settings > Systems. Settings are saved per-project and can also be overridden per-scene.