Builtin Library
- ..
- .metadata17 B
- README.md6.5 KB
- init.luau20.7 KB
- inspector.luau232 B
README.md
SceneModule
A placement of a .sceneModule: the module this entity is built from, and the
params this placement sets. In edit mode it runs the module's builder and
reconciles the result under this entity; what lands is permanent scene content —
saved in scene.json, replicated, selectable and inspectable like anything
placed by hand.
Public fields:
source— the module to build. Gated by capability, so it accepts any asset whose type definesinstantiate.moduleis an input alias for it.params— this placement's input overrides, keyed by the names the module declares in itsinputs. A name the module declares overrides that input's default; a name it does not declare is left alone.
Those two are the whole record. A placement in scene.json reads:
{
"id": "ent_ee2d09b7c4ee5a28",
"name": "orchard_0",
"components": [
{
"type": "@builtin::components.SceneModule",
"data": {
"enabled": true,
"params": { "rows": 2 },
"source": { "name": "Orchard", "type": "sceneModule", "guid": "49ba97ac-…" }
}
}
]
}
The entities the build placed sit beside it as records of their own, each naming this entity as the build that placed it and its own chain of names from the build root down to it:
buildOwner=ent_ee2d09b7c4ee5a28 buildKey=orchard
buildOwner=ent_ee2d09b7c4ee5a28 buildKey=orchard/tree_r1
buildOwner=ent_ee2d09b7c4ee5a28 buildKey=orchard/tree_r1/canopy
local pusher = entity.spawn("pusher_0")
pusher.component.add("SceneModule", {
source = asset.resolve("CoinPusher", "sceneModule"),
params = { seed = 0, coinCount = 40 },
})
pusher.localPosition = { 0, 0, 0 }
Placing the same module twice with different params yields two different results from one asset:
for i = 0, 2 do
local p = entity.spawn("pusher_" .. i)
p.component.add("SceneModule", { source = coinPusher, params = { seed = i } })
p.localPosition = { i * 4, 0, 0 }
end
Rebuilds
A write to the module's init.luau, or a change to params, re-runs the
builder and reconciles the result: an entity the previous build placed is
updated in place, one the build no longer emits is removed, and a new one is
spawned. Ids hold, so a reference to a built entity survives the rebuild.
A rebuild recognises its own entities by computing those ids again: the same placement and the same place in the hierarchy give the same string. The scene save writes them and the load brings them back, so a rebuild in a later session lands on exactly the entities the first build placed with nothing carried between the two.
A CHANGE is what rebuilds, and the changes are source, params, and the
module's code on disk. Loading and mode flips are not changes: the entities are
in the scene as authored content, the last bake is what they hold, and the
placement runs nothing. A rebuild whose module, params and module source are
all unchanged is skipped too. :rebuild() forces one anyway — for a change
nothing else reports, such as an asset the builder resolves changing underneath
it, or a module edited while the world was closed.
A build that raises leaves the previous one in the scene and says so, rather
than emptying the placement over a typo. A build that runs as its scene loads
and states no records, over a placement that built entities before, is held to
the same rule: the previous build stays and a warning names it. A rebuild after
the load (:rebuild(), a write to the module) applies an empty statement.
A build that runs as its scene loads reruns on every load, so what it adds,
changes and stops placing is not recorded in the scene's unsaved edits: the
load shows it live, and a save writes it into scene.json.
Who states the params
A placement an author made — dragged in, spawned by a tool, written by a script — holds its own params. Nothing else sets them.
A placement a build made is stated by that build. A scene's build.luau
that places one names its source and its params, and every run of that build
states them again — on load, on a write to the file, on :build(). So a param
set on such a placement is a preview: it rebuilds at once and holds until the
next run of the build, which states the params its own source gives.
Both moments say so. Setting a param on a build-placed placement names the file that states it:
[warn] [client user] a build placed this entity and states its SceneModule params — a param
set on the placement holds until that build runs again and states them from its
own source { placement="tent_ring_placement", set="count = 9",
statedIn="/zero/source/scenes/main.scene/build.luau (content)" }
and the run that states them again names what it replaced:
[warn] [client user] a build ran and stated this placement's SceneModule params over the ones
set on the placement — the file the build is written in is where they are stated
{ placement="tent_ring_placement", replaced="count: 9 → 7",
statedIn="/zero/source/scenes/main.scene/build.luau (content)" }
A run that states what the placement already holds says nothing. To change the value for good, change it where the build states it.
A build that stops stating a placement takes what the placement built with it.
When a run no longer adds the SceneModule to an entity it places, because it
dropped the module or now places it there through instantiate, the entities
the placement built under that entity go with the component, so the entity
holds only what the build states now. A placement an author
added to an entity a build places is the author's: a run of that build leaves
it and what it built in place.
Play
In play of an editor session the placement builds from its module the way it
does in edit mode, and what the build lands exists in the play scene alone: it
records nothing in the scene's unsaved edits, so a module edited while the scene
was closed shows its current output in play before any save. A runtime-profile
boot has no edit session: the entities load as authored content from
scene.json, nothing builds, and the component is inert there.
Methods
:rebuild()— re-run the builder and reconcile, ignoring the signature. Returns false on a runtime-profile boot, where nothing builds.:declaredInputs()— the bound module's declared inputs, sorted:{ name, kind, default, values? }. The setparamscan address.