Builtin Library
README.md
bakeState
Keeps the scene's baked lighting honest about the scene it was baked from. A bake is a photograph of a moment: move a wall, edit a static light, or delete a prop and every lightmap and probe field taken before that moment describes geometry that is no longer there.
BakedLighting.component drives this module off the engine's authored
change feed (layers.onEntityChanged). The bake attaches that component
itself, so producing baked artifacts and maintaining them are one act.
Invalidation is scene-wide
Indirect light is global. One moved wall changes the bounce reaching
every surface around it, so invalidating only the wall would leave its
neighbours holding light that wall no longer casts. invalidate drops
every lightmap, retires every probe field, and reinstates every withheld
light row.
That is also what makes the invalidation visible: the viewport goes from baked to realtime light the moment the edit lands, instead of continuing to show a stale photograph.
What reaches a bake
affects(entityId) answers it:
| Edit | Reaches the bake | Reason |
|---|---|---|
| Static geometry moved / changed | yes | geometry |
| Static light edited | yes | light |
| A tracked receiver or light despawned | yes | removed |
| Movable geometry, dynamic light | no | realtime, never baked |
A despawned entity can no longer be read, so dependents() — refreshed
after every bake and every invalidation — is the record of what the bake
depended on.
API
BakeState.affects(entityId) -> (boolean, reason?)BakeState.isBaked(entityId) -> booleanBakeState.dependents() -> { string }BakeState.hasBake() -> booleanBakeState.refresh()BakeState.hasMaintainer() -> booleanBakeState.ensureMaintainer() -> booleanBakeState.setLightsBaked(ids, baked) -> numberBakeState.invalidate(reason?) -> InvalidateReportBakeState.rebake(opts?) -> RebakeReportBakeState.autoBakeHold() -> { reason, at }?,BakeState.holdAutoBake(reason),BakeState.clearAutoBakeHold()
rebake recomputes the volumes already placed and the static receivers
already there. Placing new volumes is an authoring decision the baking
tools own.
A failed rebake is a failure
A stage that fails fails the rebake. The artifacts the stages left are dropped
(invalidate("bake failed")), so the scene is lit in realtime rather than by a
half-finished bake; no light is marked baked; a bake.rebake_failed notice
carries the cause; and rebake raises with it. The lights are marked baked, and
"baked lighting is current again" is posted, only when every stage succeeded.
Holding automatic re-baking
When the maintainer's automatic re-bake fails, holdAutoBake records why
(session state of the machine whose bake failed) and posts bake.autobake_held. Edits still
invalidate the bake while it is held; they do not start another, because an
editor produces an edit every few seconds and re-baking on the next one would
repeat a bake that has just failed. A bake that succeeds (rebake,
Lightmap.bakeAll, VolumeProbe.autoPlace, and so the baking tools that run
them) calls clearAutoBakeHold.