pan
The ground half of GREEN SKY. Everything a camera stands on, and everything that gets wet.
greensky/pan — the salt flat, the strip, and the water that drowns them
The ground half of GREEN SKY. Everything a camera stands on, and everything that gets wet.
Read /zero/source/design/spec.md first. This module registers itself with
greensky/film at require time; the scene entry point calls Film.build()
once and Film.tick() per frame, and nothing else drives it.
What it stands up
| entity | what it is |
|---|---|
pan_ground | the salt flat: a disc of radius Film.SITE.panRadius at y = 0 |
pan_ground_far | the same flat ground carried out to 7.6 km, 12 mm lower, so a camera a kilometre up does not see the pan end in a circle |
pan_crust | the fine crust: hexagonal plates from 62 cm across, lifted and skirted, laid around every low camera station |
pan_crust_far | the coarse crust, 6.5 m to 13 m plates, out to 300 m from each station. Casts no shadow |
pan_runway | 1800 × 45 m of concrete, top face at Film.SITE.runwayY = 0.35 |
pan_paint | its centreline dashes, edge lines and threshold bars, 1 cm proud of the concrete |
pan_apron | the concrete in front of the hangar, and the taxiway joining it to the strip |
pan_hangar | 84 × 46 m, 22 m to the ridge, at Film.SITE.hangarPos |
pan_windsock_pole + pan_windsock_seg1..3 | a 9.5 m pole and a three-segment sock |
pan_marker_01..60 | edge markers along the strip, 6 cm to 41 cm tall |
pan_ring_01..30 | tie-down rings on the apron |
pan_flood | the standing water where the low cameras are: a 420 m wind-chopped sheet |
pan_flood_far | the flat water carrying the flood to the horizon under it |
Every one of them is spawned under the PAN anchor and marked temporary, so
the saved scene carries none of it and a world.commit is never held up
waiting on a hundred entities the module rebuilds anyway.
What moves
- The flood rises.
c.floodruns 0..1 and the water goes with it toFilm.SITE.floodMax. At 0:34 there is none; by 1:44 there is 42 cm and the runway's painted centreline is 6 cm under. - The markers drown one at a time. Their heights are spread across the
flood's whole range and dealt round the strip by a stride coprime with the
count, so the drowning sweeps the field rather than marching down it. The
count goes 0 at 0:45 → 6 at 0:55 → 20 at 1:05 → 35 at 1:15 → 48 at 1:25 →
60 at 1:44.
M.drownedCount(waterY)reads it back. - The water surface travels. The chop sheet is built once with a wave of
8.6 cm unit amplitude and then MOVED: its position is the wind carrying the
pattern east across the pan, and
localScale.yis the sea state, which comes up with the rain and settles mirror-flat at the end. The wave is clamped to the depth of the water it is in, so a 2 cm flood ripples and a 40 cm one chops. - The ground soaks.
M.wetness(t, flood)leads the flood — the rain darkens the crust well before there is standing water on it — and every surface tints from its dry colour to its wet one on that one number. - The windsock. Limp through act I, snapping taut and holding through act II, slackening at the end, fluttering throughout. Three chained segments, so a droop on the first curls the whole sock.
Heights, for anything that needs to sit on the pan
salt pan y = 0
runway top y = 0.35 (|z| < 22.5, |x| < 900)
apron top y = 0.30 (around the hangar)
water level y = c.flood * 0.42
There are no colliders anywhere in the pan. Nothing in the film touches the ground physically; a weather emitter that wants to bounce hail off concrete should test against those numbers rather than raycast.
Reading it back
local Pan = require("greensky.pan")
Pan.waterY(flood) -- metres of standing water above y = 0
Pan.wetness(t, flood) -- 0..1, how wet the ground reads
Pan.drownedCount(waterY) -- how many edge markers are under
Pan.markerHeights() -- all 60 heights, in spawn order
This is a greybox
Flat tints, one shared standard_default material, no textures and no
surface shader. The flood is opaque and does not reflect anything yet — the
lightning and the rainbow standing in the water are the refine stage's, and
so is every material here. What is settled and expensive to move is the
scale, the placement and the timing.
The geometry is built in Luau by greensky/pan/geom and uploaded with
renderer.mesh.create; nothing here is a .mesh asset on disk.
Scoped to this part · feeds back into the world's score.