"Minimal scene: Sun, Skybox, Camera, Bootstrap"
- Giant hand-authored / generated
.scenefiles drift from C# and fight hotload. - Play starts with no light, no camera, or a Bootstrap that never runs.
- Scene JSON
__typecan't find your bootstrap class.
The proven pattern: the scene holds only what the editor needs to open a view; C# builds the rest in Bootstrap OnStart. Prefer runtime world-building over giant generated scene files for anything code must know about — hotloads better, no scene/code drift.
Custom components in scene JSON: __type is the plain class name when the class has no namespace. Keep bootstrap-referenced classes namespace-free.
Four GameObjects
| Object | Components |
|---|---|
| Sun | Sandbox.DirectionalLight |
| Skybox | Sandbox.SkyBox2D + Sandbox.EnvmapProbe |
| Camera | Sandbox.CameraComponent with IsMainCamera: true |
| Bootstrap | Your custom component — "__type": "YourBootstrap" (plain name, no namespace) |
Scene JSON details that matter: positions/rotations as strings ("x,y,z", quat "x,y,z,w"), every GO/component needs a unique __guid, Tags comma-separated.
Bootstrap order
protected override void OnStart()
{
if (Scene.IsEditor) return;
// 1. manager singletons (OnAwake publishes .Instance on Create)
// 2. static world
// 3. player
// 4. camera / sun attachments
// 5. UI — one GO: ScreenPanel + every PanelComponent
// 6. game-state last — its OnStart runs after the world exists
}Point .sbproj StartupScene at this scene (sbproj-title-ident-startup). Lifecycle details: component-lifecycle-onawake-onstart.
Editor Play only needs a camera and lights to present a frame; everything gameplay-owned stays in code where hotload replaces assemblies without rewriting megabytes of scene JSON. Namespace-free bootstrap types match how scene __type strings resolve.