Log inGet started
World

Builtin Library

Branchmain
Branchesmainpublish
Commitdd348ac6c3

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:

EditReaches the bakeReason
Static geometry moved / changedyesgeometry
Static light editedyeslight
A tracked receiver or light despawnedyesremoved
Movable geometry, dynamic lightnorealtime, 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) -> boolean
  • BakeState.dependents() -> { string }
  • BakeState.hasBake() -> boolean
  • BakeState.refresh()
  • BakeState.hasMaintainer() -> boolean
  • BakeState.ensureMaintainer() -> boolean
  • BakeState.setLightsBaked(ids, baked) -> number
  • BakeState.invalidate(reason?) -> InvalidateReport
  • BakeState.rebake(opts?) -> RebakeReport
  • BakeState.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.