greenhouse
Raises the Verdigris Cloister — the derelict monastery greenhouse the game is played in. Floor, dais, walls, piers, the brass vault and its cracked glass, the clerestory, the irrigation, the hanging censers, the shafts of sun and the pools they lay on the stone, the vapour and th…
greenhouse
Raises the Verdigris Cloister — the derelict monastery greenhouse the game is played in. Floor, dais, walls, piers, the brass vault and its cracked glass, the clerestory, the irrigation, the hanging censers, the shafts of sun and the pools they lay on the stone, the vapour and the spores. Plus the scene's sun and ambient, the sky, and the post-process chain for the whole game.
local Env = require("game.env.greenhouse")
Env.build(root) -- clear every env_* under root and raise the room
Env.clear(root) -- take it down again
Env.post() -- the post chain, stated as priorities
Env.sky() -- flat blown-out overcast beyond the broken roof
Env.SHAFTS is the one table that decides where the light is: which pane of
which bay the roof has lost. The roof is built with those panes missing, a cone
falls from each hole, and a point light sits where it reaches the floor.
Normally you do not call this directly — put the Cloister component on an
entity under the scene's Greenhouse anchor and it runs at load. See
../README.md.
Interface
What this asset declares: the schema it conforms to, what it exposes, and the rendered structured payload.
conforms to
zero/source-extract/v2strict
rnd(seed: number) → number
The room must come up the same on every load — the rubble does not move between sessions — so nothing here uses math.random.
| arg | type | description |
|---|---|---|
| seed | number |
rrange(seed: number, lo: number, hi: number) → number
| arg | type | description |
|---|---|---|
| seed | number | |
| lo | number | |
| hi | number |
qAxisAngle(x: number, y: number, z: number, ang: number) → void
| arg | type | description |
|---|---|---|
| x | number | |
| y | number | |
| z | number | |
| ang | number |
qFromTo(a: { number }, b: { number }) → void
The rotation that carries direction `a` onto direction `b`, both unit.
| arg | type | description |
|---|---|---|
| a | { number } | |
| b | { number } |
newGeom( ) → Geom
pushVert(g: Geom, px: number, py: number, pz: number, nx: number, ny: number, nz: number, u: number, v: number) → number
| arg | type | description |
|---|---|---|
| g | Geom | |
| px | number | |
| py | number | |
| pz | number | |
| nx | number | |
| ny | number | |
| nz | number | |
| u | number | |
| v | number |
pushQuad(g: Geom, a: number, b: number, c: number, d: number) → void
| arg | type | description |
|---|---|---|
| g | Geom | |
| a | number | |
| b | number | |
| c | number | |
| d | number |
quadMesh( ) → any
A single flat quad in the XY plane, 1x1, centred, facing +Z. The workhorse for light pools and vapour banks.
tubeMesh(sides: number, caps: boolean) → any
A closed cylinder along +Y, radius 1, from y = -0.5 to y = 0.5.
| arg | type | description |
|---|---|---|
| sides | number | |
| caps | boolean |
shaftMesh(sides: number, rings: number, rTop: number) → any
An open cone hanging DOWN from local origin: y = 0 at the roof end, y = -1 at the floor end, radius `rTop` at the top and 1 at the bottom. `uv.y` runs 0 at the roof to 1 at the floor, which is the contract cloister_shaft reads.
| arg | type | description |
|---|---|---|
| sides | number | |
| rings | number | |
| rTop | number |
ribMesh(a: number, b: number, y0: number, yc: number, width: number, depth: number, segs: number) → any
The vault rib: a rectangular brass section swept along a half-ellipse from (-a, y0) up over (0, y0 + b) and down to (a, y0), extruded `depth` in z. NOTE, and it decides the shape of this whole module: a Model whose geometry sits a long way from its entity's own transform renders correctly and casts NO SHADOW — it is dropped from the shadow pass while a transform-centred copy of the same geometry casts normally. So every mesh below is built about its own centroid and the entity is placed there, rather than the easier thing of baking world coordinates into the vertices and leaving the entity at the origin. `yc` is that centroid's height; the caller places the entity at it.
| arg | type | description |
|---|---|---|
| a | number | |
| b | number | |
| y0 | number | |
| yc | number | |
| width | number | |
| depth | number | |
| segs | number |
roofBayMesh(a: number, b: number, y0: number, yc: number, z0: number, z1: number, segs: number, missing: { [number]: boolean }) → any
One bay of the glass roof: the elliptical surface between two ribs, cut into `segs` panes. `missing` names the panes this bay has lost — that is where the light comes in, so the holes are load-bearing, not decoration.
| arg | type | description |
|---|---|---|
| a | number | |
| b | number | |
| y0 | number | |
| yc | number | |
| z0 | number | |
| z1 | number | |
| segs | number | |
| missing | { [number]: boolean } |
sporeMesh(count: number, hw: number, y0: number, y1: number, z0: number, z1: number) → any
The spore field: one quad per mote, all four corners collapsed onto the mote's home point. The corner lives in `uv` and the mote's own seed in `color`; cloister_spore opens the quad out along the camera axes and walks it around. See that shader's README.
| arg | type | description |
|---|---|---|
| count | number | |
| hw | number | |
| y0 | number | |
| y1 | number | |
| z0 | number | |
| z1 | number |
put(root: any, name: string, meshOrModel: any, mat: any, pos: { number }, scale: { number }?, rot: { number }?) → any
| arg | type | description |
|---|---|---|
| root | any | |
| name | string | |
| meshOrModel | any | |
| mat | any | |
| pos | { number } | |
| scale | { number }? | |
| rot | { number }? |
pipe(root: any, name: string, tube: any, mat: any, ax: number, ay: number, az: number, bx: number, by: number, bz: number, r: number) → any
A brass tube from world point A to world point B.
| arg | type | description |
|---|---|---|
| root | any | |
| name | string | |
| tube | any | |
| mat | any | |
| ax | number | |
| ay | number | |
| az | number | |
| bx | number | |
| by | number | |
| bz | number | |
| r | number |
clear(root: any) → void
| arg | type | description |
|---|---|---|
| root | any |
light(root: any) → void
| arg | type | description |
|---|---|---|
| root | any |
paneCentre(p: number, b: number) → void
The world point the centre of pane `p` of bay `b` sits at.
| arg | type | description |
|---|---|---|
| p | number | |
| b | number |
build(root: any) → void
| arg | type | description |
|---|---|---|
| root | any |
post( ) → void
The post chain for the WHOLE game. Owned here because the look of the room and the look of the image are one decision, and because a chain assembled twice by two slices is a chain nobody can reason about. Order matters and is stated as priority: haze belongs in scene-referred light (so the fog is fogging real radiance), bloom on top of it, then the grade, then the tonemap that lands it in the display, then the vignette.
sky( ) → void
What is beyond the broken roof. A greenhouse at the end of the world does not get a blue sky: it gets a flat, blown-out, slightly warm overcast, which is also what makes the glass read as glass rather than as a window on a nice day.
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.