Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/facepunch/sbox-public/llms.txt

Use this file to discover all available pages before exploring further.

Every s&box game is built from Scenes and GameObjects. A Scene is the top-level container that holds every object in your game world, and a GameObject is anything that exists inside that scene — a player, a prop, a light, a camera. This page explains how both work, how they relate to each other, and how to work with them in code.

What is a Scene?

A Scene is a specialized GameObject that sits at the root of the hierarchy. It owns a SceneWorld (the rendering world), a PhysicsWorld, and a GameObjectDirectory that tracks every object and component by Guid for fast lookups. You never create a Scene manually at runtime; instead, you load one from a .scene file.
// Load a scene from a file resource
Game.ActiveScene.LoadFromFile( "scenes/mymap.scene" );
Game.ActiveScene always points to the currently running scene. You can read its properties, call FindAllWithTag, or spawn new objects into it.
Only one scene is “active” at a time. Additive loads are possible, but each loaded scene still has a distinct root Scene object.

What is a GameObject?

A GameObject is an object in the scene. On its own it does nothing except exist at a position in the hierarchy. Functionality comes from the Components you attach to it. Every GameObject has:
  • A name used for debugging and scene lookups
  • A transform that describes its position, rotation, and scale relative to its parent
  • An enabled flag that controls whether the object is active
  • A Children list of child GameObjects
  • A Components list of attached components
// Create a new GameObject in the active scene
var go = new GameObject( "My Object" );

// Create with an explicit parent
var child = new GameObject( go, enabled: true, name: "Child Object" );

The scene hierarchy

GameObjects form a tree rooted at the Scene. Each GameObject has a Parent property and a Children list. Parenting is how you build complex objects — a vehicle might have child GameObjects for each wheel, each with their own components.
// Reparent a GameObject, preserving its world position
go.SetParent( newParent, keepWorldPosition: true );

// Check the relationship
bool isChild  = go.IsDescendant( someAncestor );
bool isParent = go.IsAncestor( someDescendant );

// Walk to the root
GameObject root = go.Root;   // the child of the Scene
bool isRoot     = go.IsRoot; // true if parented directly to the Scene
Avoid reparenting objects every frame. The operation notifies tags, network state, and all components, which adds overhead.

Transforms

Every GameObject exposes a Transform property of type GameTransform. This holds the object’s local position, rotation, and scale — that is, values relative to its parent. World-space values are computed on top of the parent chain.
// Local transform (relative to parent)
go.Transform.LocalPosition = new Vector3( 0, 0, 100 );
go.Transform.LocalRotation = Rotation.FromYaw( 90 );

// World transform helpers (available on the GameObject directly)
Vector3 worldPos = go.WorldPosition;
Rotation worldRot = go.WorldRotation;

// Move by setting the full world transform
go.WorldTransform = new Transform( position, rotation, scale );

Enabling and disabling

A GameObject can be enabled or disabled by setting Enabled. When an object is disabled, all of its components stop ticking and their OnDisabled callbacks fire. Child objects follow the same rule — if a parent is disabled, its children become inactive even if their own Enabled property is true. The Active property tells you whether the object is truly active in the scene — it must be enabled, all ancestors must be enabled, and the object must belong to a scene.
// Disable the object (components stop updating)
go.Enabled = false;

// Re-enable it
go.Enabled = true;

// Check if truly active (considers parent chain)
if ( go.Active )
{
    Log.Info( "Object is active in the scene." );
}
Setting Enabled = false does not remove the object from the scene. It stays in memory and in the hierarchy — it simply stops processing.

Destroying a GameObject

Call Destroy() to permanently remove a GameObject and all of its children from the scene. All components receive OnDisabled then OnDestroy before the object is removed.
go.Destroy();

Finding objects in the scene

Find by tag

Use Scene.FindAllWithTag or Scene.FindAllWithTags to search by tag. Tags are strings attached to a GameObject.
foreach ( var go in Scene.FindAllWithTag( "enemy" ) )
{
    Log.Info( go.Name );
}

Find by name

Use the scene’s Directory to find objects by name. Name lookups are not performant — avoid calling them every frame.
var results = Scene.Directory.FindByName( "Player" );

Find by Guid

Each GameObject has a unique Id (Guid). The directory provides O(1) lookups.
var go = Scene.Directory.FindByGuid( someGuid );

Walk the hierarchy

Use GetAllObjects to enumerate every object in a subtree.
foreach ( var go in root.GetAllObjects( enabled: true ) )
{
    // visits root and all descendants
}

Next steps

Components

Add behaviour to GameObjects with components and the component lifecycle.

Prefabs

Package reusable GameObjects into prefab assets and instantiate them at runtime.

Build docs developers (and LLMs) love