Skip to main content

Scene (scene.yaml)

A scene file lists what's in a level: the camera, lights, placed actors and scripted objects, plus scene-wide lighting and the BT functions that run when the scene loads, updates and stops. Studio's Scene View, Hierarchy and Inspector edit it.

Your main scene is the file registered as scene under files in the asset registry. paths.scene in game.json can point to a different one.

Example​

script:
lifecycle:
load: sceneLoad
update: sceneUpdate
stop: sceneStop
lighting:
ambient: [0.12, 0.12, 0.14]
shadows:
preset: quality
distance: 80
entities:
- id: main_camera
kind: camera
position: [0, 2, 8]
camera:
direction: [0, -0.2, -1]
field_of_view: 60
near_clip: 0.1
far_clip: 200
- id: sun
kind: directional_light
rotation: [-0.9, 0.4, 0]
light:
color: [1.0, 0.95, 0.9]
intensity: 3
source_radius: 0.5
- id: player_spawn
name: Player
kind: actor
actor: PlayerShip
position: [100, 0, 0]
script:
source: bt/player.bt
lifecycle:
load: playerLoad
update: playerUpdate

Top-level fields​

FieldTypeDefaultDescription
formatmapnoneOptional file format version; see File format versions.
script.lifecyclemapnoneScene-wide lifecycle hooks.
lightingmapengine defaultsScene-wide lighting.
entitieslistemptyThings in the scene; see Entities.

You can add your own fields anywhere. The engine ignores them and Studio keeps them when it edits the file.

Vectors​

Scenes and actor files write positions, rotations and colors as comma-separated numbers on one line, with or without brackets:

position: [1, 2, 3]
position: 1, 2, 3

Studio writes the bracketed form. Positions take 2 or 3 numbers ([x, y] means z = 0). Rotations, directions and colors take exactly 3.

Entities​

Each entity's kind says what it is. Entities with a kind the engine doesn't know are ignored by the game (unless they have a script), so you can use your own kinds for things your code reads.

FieldTypeDefaultDescription
idstring—Stable identifier. Required for lights and scripted entities. Up to 127 characters.
namestringid (lights)Display name.
kindstring—camera, actor, directional_light, point_light, spot_light, or your own.
positionvector[0, 0, 0]World position.
rotationvector[0, 0, 0]Rotation in radians (x, y, z). Used by lights.
scriptmapnonePer-entity script hooks.

Studio also reads model, material, size, health and collision on entities to draw its preview. Not implemented in the game: the engine doesn't create visuals or colliders for scene entities; your code does.

kind: camera​

The first camera becomes the game's starting 3D camera. Other cameras are ignored. Without a camera, the game starts with a 2D camera the size of the window.

FieldTypeDefaultDescription
positionvector[0, 0, 1]Camera position.
camera.directionvector[0, 0, -1]Direction the camera looks. Can't be zero.
camera.field_of_viewnumber72Vertical field of view in degrees, between 1 and 179.
camera.near_clipnumber0.04Nearest visible distance. Greater than 0.
camera.far_clipnumber180Farthest visible distance. Greater than near_clip.

kind: actor​

Places an actor from the asset registry. A scene can have up to 256 actor entities.

FieldTypeDefaultDescription
actorstring—Required. Actor name from the registry.
positionvectoractor's spawn.position, else originWhere to place it.

The scene doesn't spawn actors by itself. Your BT code reads the placements with worldSceneActors(), which gives each actor's name and position, and creates them.

Lights​

directional_light (sunlight), point_light and spot_light entities create lights when the game loads.

FieldTypeDefaultDescription
idstring—Required. Unique among lights.
positionvector[0, 0, 0]Light position (point and spot lights).
rotationvector[0, 0, 0]Radians. Sets which way directional and spot lights point; with no rotation they point along −Z.
light.colorvector [r, g, b][1, 1, 1]Light color (linear, not sRGB).
light.intensitynumber1Brightness.
light.rangenumber15How far point and spot lights reach, in world units.
light.inner_anglenumber≈25.8Spot light: angle (degrees from center) where the light starts to fade.
light.outer_anglenumber≈37.2Spot light: angle where the light ends. Less than 90.
light.source_radiusnumber≈0.27° (sun), 0.15 (others)Size of the light, which makes shadow edges softer. Degrees for directional lights, world units for others.
light.depth_biasnumber0.005Raise if surfaces show shadow speckles ("shadow acne"); too high detaches shadows.
light.normal_biasnumber0.015Same purpose as depth_bias, along the surface direction.
light.enabledbooltrueTurn the light on or off.
light.shadowsbooltrueThe light casts shadows.
light.resolutioninteger0Shadow detail for this light. 0 uses the scene default; otherwise a power of two from 16 to 32768.
light.priorityinteger0When there isn't room for every shadow, higher-priority lights keep theirs.

Lighting​

If a scene has a lighting section, its values (and the defaults for keys it leaves out) replace the engine's lighting settings.

FieldTypeDefaultDescription
lighting.enabledbooltrueScene lighting on or off.
lighting.ambientvector [r, g, b][0.18, 0.18, 0.18]Light that reaches everything, even in shadow.
lighting.shadows.presetperformance, balanced, quality or ultrabalancedStarting shadow quality. The keys below override it.
lighting.shadows.enabledbooltrueDraw shadows.
lighting.shadows.unlimitedboolfalseUpdate every shadow every frame with no limits. Best quality, slowest.
lighting.shadows.distancenumber100How far from the camera sunlight shadows are drawn.
lighting.shadows.atlas_sizeintegerpresetWidth of the shadow texture shared by all lights. Power of two, 16–32768.
lighting.shadows.atlas_heightintegerpresetHeight of that texture. 0 means square; otherwise a multiple of 16, at most 32768.
lighting.shadows.directional_resolutionintegerpresetDefault shadow detail for sunlight. Power of two, 16–32768.
lighting.shadows.local_resolutionintegerpresetDefault shadow detail for point and spot lights. Power of two, 16–32768.
lighting.shadows.max_resident_lightsintegerunlimitedMost lights that can have shadows at once. -1 is unlimited.
lighting.shadows.refresh_viewsintegerpresetShadow views updated per frame (a sun uses 4, a point light 6, a spot light 1). Lower is faster; -1 is unlimited.
lighting.shadows.filterlow, medium or highpresetShadow edge smoothness.
Presetatlas_sizeatlas_heightdirectional_resolutionlocal_resolutionrefresh_viewsfilter
performance40960102425624low
balanced40960102425624medium
quality81920204851264high
ultra163841126440961024128high

Lifecycle hooks​

Hooks name BT functions that run at points in the scene's life. The functions must be in your compiled scripts (bt.sources or something they include); if one is missing, the game stops with an error at startup.

KeyScene-wide functionRuns
loadfn name() -> voidOnce, when the scene loads, before bt.entry and the UI start.
startfn name() -> voidOnce, after everything created in load has started.
updatefn name(float dt) -> voidEvery simulation step.
drawfn name(float dt) -> voidEvery frame, while the world is drawn.
overlayfn name(float dt) -> voidEvery frame, after the world, for drawing on top of it.
stopfn name() -> voidOnce, when the game shuts down.

Entity scripts​

Give an entity a script.lifecycle to run hooks for it. Scripted entities need an id; a scene can have up to 256.

FieldTypeDescription
script.sourcestringThe script file Studio opens for this entity. It is not compiled automatically: list it in bt.sources or include it.
script.lifecycle.<phase>stringFunction for load, start, update, draw, overlay or stop.

Entity hooks receive the entity's details:

PhaseFunction
load, start, stopfn name(string id, string kind, float x, float y, float z) -> void
update, draw, overlayfn name(string id, string kind, float x, float y, float z, float dt) -> void

x, y, z are the position written in the scene.

Order: the scene-wide hook runs first, then entity hooks in file order. On shutdown, entity stop hooks run in reverse order, then the scene-wide stop. If load fails, the game doesn't start. If a per-frame hook fails, that hook stops running, but stop still runs.

Limits​

  • 256 actor entities and 256 scripted entities per scene.
  • IDs, kinds, actor names and hook names: up to 127 characters. Light names: up to 63.
  • Nested key paths (such as entities.3.light.color) up to 127 characters.
  • Other YAML rules: see Asset registry: YAML rules.

Errors​

MessageCause
scene file: `version: 1` is no longer usedDelete the version line (an older file).
scene file uses format version X; this cTurtle reads format …The file was written for a newer cTurtle; see File format versions.
could not parse scene YAMLUnsupported YAML, or a key path that's too long.
scene script.lifecycle.X must name a BtLang functionHook value isn't a function name.
scripted scene entity N requires an idScripted entity without id.
actor entity N requires an actor referencekind: actor without actor.
... entity N has invalid position / invalid directionWrong number of components, or not numbers.
camera entity N has zero directioncamera.direction is [0, 0, 0].
camera entity N field_of_view must be between 1 and 179 degreesFOV out of range.
camera entity N requires 0 < near_clip < far_clipInvalid clip distances.
scene has more than 256 actor records / scripted entitiesToo many.
scene references an unknown actor: XRegister the actor in the asset registry.
scene lifecycle function is missing: X, scene entity lifecycle function is missing: XThe function isn't in your compiled scripts.
entities.N.id: light requires a stable ID shorter than 128 bytesLight without id.
entities.N.kind: duplicate light IDTwo lights share an id.
entities.N.light: invalid light color, intensity, range, cone, source size, bias, or resolutionA light value is out of range.
lighting.shadows.preset: unknown preset, lighting.shadows: invalid resolution, atlas dimensions, or distanceFix the lighting value.

See also​