crater
Stands the place and drives it from the film clock.
local crater = require("ashbloom.crater.crater")
crater.build() -- idempotent: meshes, materials, entities, anchors
crater.ashCoverage(t) -- 1 -> 0 as the rain crosses
crater.waterY(t) -- where the pool's surface is
crater.state(t) -- what it is doing now, including the LIVE uniforms
Requiring this module registers the crater stage, so the director poses the
place once a frame with everything else.
What build does
Makes the four materials and the seven meshes it is missing, spawns the geometry
under a Crater entity, deletes the skeleton's scaffold rings, and moves the
A_* shot anchors onto the surface the real geometry built — keeping each one's
azimuth, so the compositions the shot list was written against still hold.
It is idempotent and safe after a hot-reload. teardown() takes the geometry
down and marks every mesh for re-cutting, which is what the component's rebuild
field uses when the generator itself changes.
What it drives
Two numbers, pushed into the crater's materials every frame:
ash_coverage—ashCoverage(t), 1 through movement I and stripped to 0 between t 42 and t 60. The ash mantle reads it as how much of itself is still lying; the stone reads it as how much dust is still in its joints.wetness—film.wetness(t), 0 to 0.78. Basalt goes from dry grey to near-black with a grazing sheen, water gathers in the low places, and ash that is still lying holds the water off the stone under it.
What other slices ask it
waterY(t) is where the pool's surface stands — −2.25 in the dry basin, rising
to −0.30 just under the kerb as the rain fills it. The refractive pool plane
follows it. CHANNEL_ANGLES are the four bearings the stone channels run on;
A_Channel stands at the first.
Scoped to this part · feeds back into the world's score.