p_snow
<!-- zero:scaffolded-readme --> <!-- Replace the line below with what this module provides and who consumes it, then delete both comment lines. -->
p_snow
<!-- zero:scaffolded-readme --> <!-- Replace the line below with what this module provides and who consumes it, then delete both comment lines. -->TODO: describe this module.
Interface
What this asset declares: the schema it conforms to, what it exposes, and the rendered structured payload.
conforms to
zero/source-extract/v2preseed/parts/p_snow.module — SNOWLINE: a skier drops into an alpine valley and carves it. Every turn cuts a trench into the snow and throws the displaced snow up into a bank beside it, and the trail stays cut for the whole run. The skier is SIMULATED, not placed. A body integrates under gravity in contact with one surface function — piste, kickers, rail — so it accelerates down the fall line, leans as hard as the turn it is actually holding, rides up a take-off and flies off the lip because the surface stopped rising, and absorbs the landing. Nothing it can hit is a special case, and nothing it can hit is passed through. Because the skier is simulated, the camera cannot be a precomputed path: it is a set of stations in the BODY's own frame, evaluated against the live body and damped, so a shot holds its composition wherever the run actually went.
baseCarve(z: number) → number
The line the skier is trying to hold, as a function of z alone — the body chases it with its edges rather than being placed on it, so the run is whatever the physics could actually hold.
| arg | type | description |
|---|---|---|
| z | number |
targetX(z: number) → number
| arg | type | description |
|---|---|---|
| z | number |
pisteOnly(z: number) → number
| arg | type | description |
|---|---|---|
| z | number |
buildPark(place: ?, spec: ?) → void
The park built from a set of placements. An entry that is nil is a feature not placed yet, and it is simply not on the mountain — which is what lets the solver below run the mountain as it stands at each stage.
| arg | type | description |
|---|---|---|
| place | ? | |
| spec | ? |
surfaceFor(kickers: ?, rail: ?) → void
The one surface everything on this mountain stands on and the body collides with: the piste, plus whatever the park puts on top of it.
| arg | type | description |
|---|---|---|
| kickers | ? | |
| rail | ? |
crossingX(surface: ?, z: number) → number
WHERE THE BODY ACTUALLY GOES, not where it is aiming. The body chases its line with its edges, and the steering lag means it passes any given z about a metre off the line — measured, not guessed. Placing a rail on the LINE therefore places it a metre from the skier, who clips its edge for one frame and hops. Widening the catch to cover that only turns a miss into a scuff. So the park is placed on the path the body takes. Not the path down BARE piste: a feature deflects everything below it, so a placement solved against an empty mountain is right for the first feature and drifts by a metre by the second. A feature only ever perturbs the run DOWNSTREAM of itself, which is what makes this solvable in run order — each feature is placed where the body arrives with every feature ABOVE it already standing, and a few passes settle the one loop that remains, a kicker's own ramp deflecting the approach to its own lip. Where the body is when it crosses `z`, run from the top against `surface`.
| arg | type | description |
|---|---|---|
| surface | ? | |
| z | number |
pathThrough(surface: ?, z0: number, z1: number) → void
The line the body takes across a stretch of the run, sampled every half metre.
| arg | type | description |
|---|---|---|
| surface | ? | |
| z0 | number | |
| z1 | number |
fitRail(surface: ?, fz: number, length: number, search: number) → void
WHERE ALONG THE RUN a straight rail stands is what decides whether the skier rides it. The body crosses the fall line at a couple of metres a second and a rail is a few centimetres of steel: over most of a turn the line sweeps clean across the steel and the skier is shoved off the edge it climbed. There is one stretch of every turn where the line is momentarily straight down the hill, and that is the only place a rail down the fall line lies under the skier for its whole length. It is found from the line rather than guessed: the window of `length` metres, within `search` of where the rail was authored, across which the line moves least.
| arg | type | description |
|---|---|---|
| surface | ? | |
| fz | number | |
| length | number | |
| search | number |
solvePark(spec: ?) → void
| arg | type | description |
|---|---|---|
| spec | ? |
stationAt(t: number) → void
| arg | type | description |
|---|---|---|
| t | number |
spawnModel(ctx: ?, name: string, geom: ?, mat: ?, parent: string?) → void
| arg | type | description |
|---|---|---|
| ctx | ? | |
| name | string | |
| geom | ? | |
| mat | ? | |
| parent | string? |
applyLook( ) → void
The alpine day this run is lit by. It is scene-wide state — the sky entity, the key, the ambient, the clear colour — so it belongs to `enter` and not to `build`: the director may build a part up to a second before its cut, under the outgoing part's fade, and a daylight sky installed there would land on the part still on screen.
build(ctx: ?) → void
| arg | type | description |
|---|---|---|
| ctx | ? |
claimProbes(ids: ?) → void
REFLECTION PROBES ALONG THE RUN. Snow is not matte: it is a field of ice facets under an open sky, and most of what it returns is the sky itself. Without a probe every surface here reads its indirect specular from nothing, which is why the piste and the park features came back looking like painted plaster — the glint has something to catch, but the broad sheen underneath it has nothing. Three down the fall line rather than one, because the run is long and the valley closes in at the top: a single probe taken at the start reflects open sky onto snow that is by then under a shoulder of the mountain. They overlap, and the renderer blends by proximity. `probeId` makes each a PREBAKE — the cube is baked once and loaded on every run after. Probes are registered by `probeId`, and a probe already standing under that id is a leftover from a previous entry: the slot table holds eight, so a part re-entered a few times exhausts it and a LATER part silently gets no probe at all. Claiming the ids means an entry always starts from none of its own.
| arg | type | description |
|---|---|---|
| ids | ? |
plant(ctx: ?) → void
| arg | type | description |
|---|---|---|
| ctx | ? |
enter(ctx: ?) → void
| arg | type | description |
|---|---|---|
| ctx | ? |
findSkinned(root: ?) → void
| arg | type | description |
|---|---|---|
| root | ? |
walk(e: ?, depth: ?) → void
| arg | type | description |
|---|---|---|
| e | ? | |
| depth | ? |
hideBuiltBody(skier: ?) → void
| arg | type | description |
|---|---|---|
| skier | ? |
walk(e: ?, depth: ?) → void
| arg | type | description |
|---|---|---|
| e | ? | |
| depth | ? |
onRail(b: ?) → void
| arg | type | description |
|---|---|---|
| b | ? |
trickClip(b: ?) → void
| arg | type | description |
|---|---|---|
| b | ? |
driveTrickClip(ctx: ?, b: ?) → void
| arg | type | description |
|---|---|---|
| ctx | ? | |
| b | ? |
mountKit(ctx: ?, b: ?) → void
| arg | type | description |
|---|---|---|
| ctx | ? | |
| b | ? |
ensureRig(ctx: ?, dt: ?) → void
| arg | type | description |
|---|---|---|
| ctx | ? | |
| dt | ? |
collect(e: ?, depth: ?) → void
| arg | type | description |
|---|---|---|
| e | ? | |
| depth | ? |
driveCamera(ctx: ?, t: number, dt: number) → void
| arg | type | description |
|---|---|---|
| ctx | ? | |
| t | number | |
| dt | number |
update(ctx: ?, t: number, dt: number) → void
| arg | type | description |
|---|---|---|
| ctx | ? | |
| t | number | |
| dt | number |
exit(_ctx: ?) → void
| arg | type | description |
|---|---|---|
| _ctx | ? |
Sub-parts
Everything contained inside this part. Assets are composite children (clickable cards). Files are leaf payloads. Expand any row to view its source.
Showing up to 3 levels deep. Open a part to see what it holds further down.
Problems
Everything affecting this asset right now: its own problems, anything wrong inside it, and problems on its direct dependencies.
agent_score is exposed.+ quality × 0.35
+ performance × 0.25
± compat factor
Usability ratings
Did the part work as advertised when consumers tried to drop it in. Separate from upvotes: those are taste; this is "did it function".
Scoped to this part · feeds back into the world's score.