reflectionProbe
The reflectionProbe namespace — 40 functions.
globals/reflectionProbe/add
reflectionProbe.add(x: number, y: number, z: number, opts: { [string]: any }?) -> string
Add a reflection probe at (x, y, z) in one call: spawns a probe entity
carrying a ReflectionProbe component (which registers it and, unless
opts.bake == false, bakes it). The probe is an editor gizmo — invisible in
play mode. Returns the probe entity id.
Parameters
xnumber— World X.ynumber— World Y.znumber— World Z.opts{ [string]: any }(optional) — Optional{ radius = 12, probeId = "...", name = "..." }.probeIdis the STABLE asset identity (so a re-created probe reloads the same baked cube); defaults to the entity id. The probe does NOT bake on add — callbakeAll()once the scene is built (baking is an authoring step).
Returns string — The probe entity id.
reflectionProbe.add(0, 3, 0, { radius = 15, probeId = "lobby" })
globals/reflectionProbe/apply
reflectionProbe.apply() -> number
Push the current active-probe blend data (live positions + radii) to the renderer. Builds a dense slot array so each probe's data lands at its cube slot; freed/missing slots become inert placeholders. Called automatically by add / bake / remove; call it directly after moving a probe entity.
Returns number — The number of active probes applied.
globals/reflectionProbe/bake
reflectionProbe.bake(id: string) -> (string?, string?)
Bake the scene into probe id's cube slot from its current position AND
persist it to a faces6 .texture asset (so it survives reload + syncs),
then re-apply the probe set. Yields a few frames; call from a task/coroutine
context (component hook via task.spawn, bakeAll, or execute).
Parameters
idstring— Probe entity id.
Returns (string?, string?) — The asset path on success, or (nil, errorMessage) on failure.
globals/reflectionProbe/bakeAll
reflectionProbe.bakeAll() -> { baked: number, failed: number, errors: { string } }
Bake EVERY registered probe in the active layers, in one call. Captures
the sky into the fallback slot, then each probe's scene from its position
into its slot, persists it, and applies the full probe set. The agent/editor
one-liner. Yields; call from a task/coroutine context (execute, a tool, or
task.spawn).
Returns { baked: number, failed: number, errors: { string } } — { baked = N, failed = M, errors = { ... } }.
reflectionProbe.bakeAll()
globals/reflectionProbe/count
reflectionProbe.count() -> number
Number of registered probes.
Returns number
globals/reflectionProbe/ensureSkyFallback
reflectionProbe.ensureSkyFallback() -> boolean
Ensure the scene's sky is in the environment's sky fallback: a reflective surface no probe covers then reflects the sky rather than black, and a partially covered one blends the shortfall against it. Queues a capture when the sky slot holds none, and re-arms the fallback when a capture is there but switched off. The engine's own state answers both questions, so calling this on every probe that comes up costs one capture between them, and a scene that lost its fallback gets it back. Once captured, the fallback follows the sky the scene draws on its own.
Returns boolean — True if a capture was queued, false if the sky slot already holds one.
reflectionProbe.ensureSkyFallback()
globals/reflectionProbe/list
reflectionProbe.list() -> { any }
List every registered probe: { { id, slot, radius, priority, asset, position }, ... }.
Returns { any } — The probe list.
globals/reflectionProbe/loadBaked
reflectionProbe.loadBaked(id: string) -> boolean
Load probe id's PERSISTED baked cube (probe_<key>.texture) into its
slot WITHOUT re-rendering the scene — the runtime path. A probe bakes once at
authoring time and loads the asset on every subsequent scene load. Returns
false (not an error) when no baked asset exists yet.
Parameters
idstring— Probe entity id.
Returns boolean — True if a baked asset was loaded, false if none exists / load failed.
globals/reflectionProbe/register
reflectionProbe.register(id: string, radius: number, key: string?) -> number?
Register a reflection probe for entity id with influence radius.
Assigns a free cube slot and applies the updated probe set. Idempotent — a
re-register keeps the same slot and just updates the radius. Called by the
ReflectionProbe component's awake; rarely called directly.
Parameters
idstring— Probe entity id.radiusnumber— Influence radius (world units) — surfaces within blend it.keystring(optional) — Optional STABLE asset identity (the probe's probeId). Defaults toid. The baked cube persists atprobe_<key>.textureso an authored probe keeps the same asset across reloads even though its runtime entity id changes.
Returns number? — The assigned cube slot, or nil if all MAX_PROBES slots are taken.
globals/reflectionProbe/setPriority
reflectionProbe.setPriority(id: string, priority: number)
Set a probe's blend rank against the probes it overlaps, and re-apply. Probes are gathered highest rank first and each rank takes the coverage the ranks above it left, so a small interior probe ranked above the large exterior one it sits inside wins outright wherever it reaches full weight, while probes of equal rank crossfade by proximity as before.
Parameters
idstring— Probe entity id.prioritynumber— Blend rank. Defaults to 0 on every probe.
reflectionProbe.setPriority(interiorId, 1)
globals/reflectionProbe/setProxy
reflectionProbe.setProxy(id: string, kind: string, x: number, y: number, z: number)
Anchor a probe's reflections to a proxy volume and re-apply. A cube records the environment from one point, so sampling it along the raw reflection vector puts everything it recorded at infinity and the reflection slides across a surface as the camera moves. Sizing a proxy to the geometry the probe recorded — a room's walls, say — keeps the reflection anchored to what it depicts.
Parameters
idstring— Probe entity id.kindstring— "box" (sized by all three half-extents), "sphere" (sized byx), or "none" to sample along the raw reflection vector.xnumber— Half-extent along X, in world units — the sphere radius for "sphere".ynumber— Half-extent along Y.znumber— Half-extent along Z.
reflectionProbe.setProxy(id, "box", 5, 3, 4) -- a 10x6x8 room
globals/reflectionProbe/setRadius
reflectionProbe.setRadius(id: string, radius: number)
Update a probe's influence radius and re-apply.
Parameters
idstring— Probe entity id.radiusnumber— New influence radius.
globals/reflectionProbe/unregister
reflectionProbe.unregister(id: string)
Unregister entity id's probe, freeing its cube slot, and re-apply.
Parameters
idstring— Probe entity id.
modules/reflectionProbe/README
require("@builtin/modules/api/engine/reflectionProbe") -- reflectionProbe (also available as global 'reflectionProbe')
Reflection-probe system — multiple proximity-blended reflection probes in a scene. Each probe bakes the scene into its own cube slot from its position; surfaces reflect the probes covering them, gathered highest priority first and blended by proximity within a rank (the renderer's per-fragment probe blend), with the scene's sky under whatever coverage the probes leave. One-liner authoring (reflectionProbe.add) and a one-call bake-everything (reflectionProbe.bakeAll).
Usage: local reflectionProbe = require("@builtin/modules/api/engine/reflectionProbe") Also available as global: reflectionProbe
modules/reflectionProbe/add
add(x: number, y: number, z: number, opts: { [string]: any }?): string
Add a reflection probe at (x, y, z) in one call: spawns a probe entity
carrying a ReflectionProbe component (which registers it and, unless
opts.bake == false, bakes it). The probe is an editor gizmo — invisible in
play mode. Returns the probe entity id.
Parameters
xnumber— World X.ynumber— World Y.znumber— World Z.opts{ [string]: any }?(optional) — Optional{ radius = 12, probeId = "...", name = "..." }.probeIdis the STABLE asset identity (so a re-created probe reloads the same baked cube); defaults to the entity id. The probe does NOT bake on add — callbakeAll()once the scene is built (baking is an authoring step).
reflectionProbe.add(0, 3, 0, { radius = 15, probeId = "lobby" })
modules/reflectionProbe/apply
apply(): number
Push the current active-probe blend data (live positions + radii) to the renderer. Builds a dense slot array so each probe's data lands at its cube slot; freed/missing slots become inert placeholders. Called automatically by add / bake / remove; call it directly after moving a probe entity.
modules/reflectionProbe/bake
bake(id: string): (string?, string?)
Bake the scene into probe id's cube slot from its current position AND
persist it to a faces6 .texture asset (so it survives reload + syncs),
then re-apply the probe set. Yields a few frames; call from a task/coroutine
context (component hook via task.spawn, bakeAll, or execute).
Parameters
idstring— Probe entity id.
modules/reflectionProbe/bakeAll
bakeAll(): { baked: number, failed: number, errors: { string } }
Bake EVERY registered probe in the active layers, in one call. Captures
the sky into the fallback slot, then each probe's scene from its position
into its slot, persists it, and applies the full probe set. The agent/editor
one-liner. Yields; call from a task/coroutine context (execute, a tool, or
task.spawn).
reflectionProbe.bakeAll()
modules/reflectionProbe/count
count(): number
Number of registered probes.
modules/reflectionProbe/ensureSkyFallback
ensureSkyFallback(): boolean
Ensure the scene's sky is in the environment's sky fallback: a reflective surface no probe covers then reflects the sky rather than black, and a partially covered one blends the shortfall against it. Queues a capture when the sky slot holds none, and re-arms the fallback when a capture is there but switched off. The engine's own state answers both questions, so calling this on every probe that comes up costs one capture between them, and a scene that lost its fallback gets it back. Once captured, the fallback follows the sky the scene draws on its own.
reflectionProbe.ensureSkyFallback()
modules/reflectionProbe/list
list(): { any }
List every registered probe: { { id, slot, radius, priority, asset, position }, ... }.
modules/reflectionProbe/loadBaked
loadBaked(id: string): boolean
Load probe id's PERSISTED baked cube (probe_<key>.texture) into its
slot WITHOUT re-rendering the scene — the runtime path. A probe bakes once at
authoring time and loads the asset on every subsequent scene load. Returns
false (not an error) when no baked asset exists yet.
Parameters
idstring— Probe entity id.
modules/reflectionProbe/register
register(id: string, radius: number, key: string?): number?
Register a reflection probe for entity id with influence radius.
Assigns a free cube slot and applies the updated probe set. Idempotent — a
re-register keeps the same slot and just updates the radius. Called by the
ReflectionProbe component's awake; rarely called directly.
Parameters
idstring— Probe entity id.radiusnumber— Influence radius (world units) — surfaces within blend it.keystring?(optional) — Optional STABLE asset identity (the probe's probeId). Defaults toid. The baked cube persists atprobe_<key>.textureso an authored probe keeps the same asset across reloads even though its runtime entity id changes.
modules/reflectionProbe/setPriority
setPriority(id: string, priority: number)
Set a probe's blend rank against the probes it overlaps, and re-apply. Probes are gathered highest rank first and each rank takes the coverage the ranks above it left, so a small interior probe ranked above the large exterior one it sits inside wins outright wherever it reaches full weight, while probes of equal rank crossfade by proximity as before.
Parameters
idstring— Probe entity id.prioritynumber— Blend rank. Defaults to 0 on every probe.
reflectionProbe.setPriority(interiorId, 1)
modules/reflectionProbe/setProxy
setProxy(id: string, kind: string, x: number, y: number, z: number)
Anchor a probe's reflections to a proxy volume and re-apply. A cube records the environment from one point, so sampling it along the raw reflection vector puts everything it recorded at infinity and the reflection slides across a surface as the camera moves. Sizing a proxy to the geometry the probe recorded — a room's walls, say — keeps the reflection anchored to what it depicts.
Parameters
idstring— Probe entity id.kindstring— "box" (sized by all three half-extents), "sphere" (sized byx), or "none" to sample along the raw reflection vector.xnumber— Half-extent along X, in world units — the sphere radius for "sphere".ynumber— Half-extent along Y.znumber— Half-extent along Z.
reflectionProbe.setProxy(id, "box", 5, 3, 4) -- a 10x6x8 room
modules/reflectionProbe/setRadius
setRadius(id: string, radius: number)
Update a probe's influence radius and re-apply.
Parameters
idstring— Probe entity id.radiusnumber— New influence radius.
modules/reflectionProbe/unregister
unregister(id: string)
Unregister entity id's probe, freeing its cube slot, and re-apply.
Parameters
idstring— Probe entity id.
typed/builtin//modules/api/engine/reflectionProbe/reflectionProbe/add
reflectionProbe.add(x: number, y: number, z: number, opts: { [string]: any }?) -> string
Add a reflection probe at (x, y, z) in one call: spawns a probe entity
carrying a ReflectionProbe component (which registers it and, unless
opts.bake == false, bakes it). The probe is an editor gizmo — invisible in
play mode. Returns the probe entity id.
Parameters
xnumber— World X.ynumber— World Y.znumber— World Z.opts{ [string]: any }(optional) — Optional{ radius = 12, probeId = "...", name = "..." }.probeIdis the STABLE asset identity (so a re-created probe reloads the same baked cube); defaults to the entity id. The probe does NOT bake on add — callbakeAll()once the scene is built (baking is an authoring step).
Returns string — The probe entity id.
reflectionProbe.add(0, 3, 0, { radius = 15, probeId = "lobby" })
typed/builtin//modules/api/engine/reflectionProbe/reflectionProbe/apply
reflectionProbe.apply() -> number
Push the current active-probe blend data (live positions + radii) to the renderer. Builds a dense slot array so each probe's data lands at its cube slot; freed/missing slots become inert placeholders. Called automatically by add / bake / remove; call it directly after moving a probe entity.
Returns number — The number of active probes applied.
typed/builtin//modules/api/engine/reflectionProbe/reflectionProbe/bake
reflectionProbe.bake(id: string) -> (string?, string?)
Bake the scene into probe id's cube slot from its current position AND
persist it to a faces6 .texture asset (so it survives reload + syncs),
then re-apply the probe set. Yields a few frames; call from a task/coroutine
context (component hook via task.spawn, bakeAll, or execute).
Parameters
idstring— Probe entity id.
Returns (string?, string?) — The asset path on success, or (nil, errorMessage) on failure.
typed/builtin//modules/api/engine/reflectionProbe/reflectionProbe/bakeAll
reflectionProbe.bakeAll() -> { baked: number, failed: number, errors: { string } }
Bake EVERY registered probe in the active layers, in one call. Captures
the sky into the fallback slot, then each probe's scene from its position
into its slot, persists it, and applies the full probe set. The agent/editor
one-liner. Yields; call from a task/coroutine context (execute, a tool, or
task.spawn).
Returns { baked: number, failed: number, errors: { string } } — { baked = N, failed = M, errors = { ... } }.
reflectionProbe.bakeAll()
typed/builtin//modules/api/engine/reflectionProbe/reflectionProbe/count
reflectionProbe.count() -> number
Number of registered probes.
Returns number
typed/builtin//modules/api/engine/reflectionProbe/reflectionProbe/ensureSkyFallback
reflectionProbe.ensureSkyFallback() -> boolean
Ensure the scene's sky is in the environment's sky fallback: a reflective surface no probe covers then reflects the sky rather than black, and a partially covered one blends the shortfall against it. Queues a capture when the sky slot holds none, and re-arms the fallback when a capture is there but switched off. The engine's own state answers both questions, so calling this on every probe that comes up costs one capture between them, and a scene that lost its fallback gets it back. Once captured, the fallback follows the sky the scene draws on its own.
Returns boolean — True if a capture was queued, false if the sky slot already holds one.
reflectionProbe.ensureSkyFallback()
typed/builtin//modules/api/engine/reflectionProbe/reflectionProbe/list
reflectionProbe.list() -> { any }
List every registered probe: { { id, slot, radius, priority, asset, position }, ... }.
typed/builtin//modules/api/engine/reflectionProbe/reflectionProbe/loadBaked
reflectionProbe.loadBaked(id: string) -> boolean
Load probe id's PERSISTED baked cube (probe_<key>.texture) into its
slot WITHOUT re-rendering the scene — the runtime path. A probe bakes once at
authoring time and loads the asset on every subsequent scene load. Returns
false (not an error) when no baked asset exists yet.
Parameters
idstring— Probe entity id.
Returns boolean — True if a baked asset was loaded, false if none exists / load failed.
typed/builtin//modules/api/engine/reflectionProbe/reflectionProbe/register
reflectionProbe.register(id: string, radius: number, key: string?) -> number?
Register a reflection probe for entity id with influence radius.
Assigns a free cube slot and applies the updated probe set. Idempotent — a
re-register keeps the same slot and just updates the radius. Called by the
ReflectionProbe component's awake; rarely called directly.
Parameters
idstring— Probe entity id.radiusnumber— Influence radius (world units) — surfaces within blend it.keystring(optional) — Optional STABLE asset identity (the probe's probeId). Defaults toid. The baked cube persists atprobe_<key>.textureso an authored probe keeps the same asset across reloads even though its runtime entity id changes.
Returns number? — The assigned cube slot, or nil if all MAX_PROBES slots are taken.
typed/builtin//modules/api/engine/reflectionProbe/reflectionProbe/setPriority
reflectionProbe.setPriority(id: string, priority: number)
Set a probe's blend rank against the probes it overlaps, and re-apply. Probes are gathered highest rank first and each rank takes the coverage the ranks above it left, so a small interior probe ranked above the large exterior one it sits inside wins outright wherever it reaches full weight, while probes of equal rank crossfade by proximity as before.
Parameters
idstring— Probe entity id.prioritynumber— Blend rank. Defaults to 0 on every probe.
reflectionProbe.setPriority(interiorId, 1)
typed/builtin//modules/api/engine/reflectionProbe/reflectionProbe/setProxy
reflectionProbe.setProxy(id: string, kind: string, x: number, y: number, z: number)
Anchor a probe's reflections to a proxy volume and re-apply. A cube records the environment from one point, so sampling it along the raw reflection vector puts everything it recorded at infinity and the reflection slides across a surface as the camera moves. Sizing a proxy to the geometry the probe recorded — a room's walls, say — keeps the reflection anchored to what it depicts.
Parameters
idstring— Probe entity id.kindstring— "box" (sized by all three half-extents), "sphere" (sized byx), or "none" to sample along the raw reflection vector.xnumber— Half-extent along X, in world units — the sphere radius for "sphere".ynumber— Half-extent along Y.znumber— Half-extent along Z.
reflectionProbe.setProxy(id, "box", 5, 3, 4) -- a 10x6x8 room
typed/builtin//modules/api/engine/reflectionProbe/reflectionProbe/setRadius
reflectionProbe.setRadius(id: string, radius: number)
Update a probe's influence radius and re-apply.
Parameters
idstring— Probe entity id.radiusnumber— New influence radius.
typed/builtin//modules/api/engine/reflectionProbe/reflectionProbe/unregister
reflectionProbe.unregister(id: string)
Unregister entity id's probe, freeing its cube slot, and re-apply.
Parameters
idstring— Probe entity id.