garden
The garden of Ashbloom: ~13,000 plants across five hardware-instanced populations — fern fronds, terrace tufts, moss cushions, wall vines and bioluminescent blooms — one `renderer.mesh.drawInstanced` each, every member shading from its own four per-instance lanes.
ashbloom.garden.garden
The garden of Ashbloom: ~13,000 plants across five hardware-instanced
populations — fern fronds, terrace tufts, moss cushions, wall vines and
bioluminescent blooms — one renderer.mesh.drawInstanced each, every member
shading from its own four per-instance lanes.
build() seeds three static buffers per population (placement, identity, wave
position), taken off the crater slice's own craterGeo.surfaceAt so a plant sits
on the stone rather than on a height a formula guessed, and clustered into shared
BEDS so the terraces read as planted. apply(t) is the registered stage: it
writes seven scalar params and dispatches ab_garden_lanes once per population,
which rewrites the transform and lane buffers on the GPU. Nothing in the garden
is an entity, so growing it costs no apply_vfs_mutations at all.
Read report() for what is reserved, what is drawn this frame, and the film time
the stage last ran at.
Interface
What this asset declares: the schema it conforms to, what it exposes, and the rendered structured payload.
conforms to
zero/source-extract/v2strict
groundAt(r: number, th: number) → void
Height of the stone under a polar point, and the radius the crater's warp actually put that ring at.
| arg | type | description |
|---|---|---|
| r | number | |
| th | number |
rng(seed: number) → void
Deterministic noise. The film must look the same on every run, so nothing here touches `math.random`. xorshift32 through `bit32`, NOT a plain LCG. A 32-bit LCG written in Lua arithmetic multiplies past 2^53 and loses its low bits to double rounding, so it degenerates into near-identical consecutive draws — which showed up here as pairs of plants sharing a position, a size and a phase.
| arg | type | description |
|---|---|---|
| seed | number |
lerp(a: number, b: number, x: number) → number
| arg | type | description |
|---|---|---|
| a | number | |
| b | number | |
| x | number |
zoneSpan(zone: number) → void
Placement The radial span of a zone's flat. Zone 0 is the garden floor around the pool; zone `i` is terrace `i`, running from its own retaining wall out to the next.
| arg | type | description |
|---|---|---|
| zone | number |
flatPoint(zone: number, rand: () → void
A point on a zone's flat, taken off the crater's OWN surface so it sits on the stone rather than on the height a formula guessed.
| arg | type | description |
|---|---|---|
| zone | number | |
| rand | ( |
wallPoint(zone: number, rand: () → void
A point on the retaining wall that holds terrace `zone` up: the vertical face standing at that terrace's inner radius, between the surface below and its own.
| arg | type | description |
|---|---|---|
| zone | number | |
| rand | ( |
pickZone(rand: () → void
| arg | type | description |
|---|---|---|
| rand | ( |
makeBeds( ) → void
bedPoint(bed: Bed, rand: () → void
A point inside a bed, denser at its middle.
| arg | type | description |
|---|---|---|
| bed | Bed | |
| rand | ( |
anchorAt(name: string) → void
Seeding. Every plant gets a PHASE. It is the plant's place in time: when it emerges, when it opens, how its breath is offset. The array is sorted by phase, so the drawn instance count can simply climb with the growth curve and the plants that are not up yet cost nothing.
| arg | type | description |
|---|---|---|
| name | string |
seedPopulation(spec: any) → void
| arg | type | description |
|---|---|---|
| spec | any |
makeAsset(kindName: string, name: string, opts: any) → any
Materials `asset.create`'s third argument is type-specific and the checker only knows one shape for it, so a material's own property table goes through a widened local rather than being written at the call site.
| arg | type | description |
|---|---|---|
| kindName | string | |
| name | string | |
| opts | any |
makeMaterials( ) → void
leafPair(nightMul: number) → void
| arg | type | description |
|---|---|---|
| nightMul | number |
gpuBuffer(name: string, ty: string, len: number, readback: boolean?) → void
Build
| arg | type | description |
|---|---|---|
| name | string | |
| ty | string | |
| len | number | |
| readback | boolean? |
build( ) → void
Stand the whole garden: four meshes, four materials, three static seed buffers and two per-frame buffers per population, and one `drawInstanced` each. Safe to call again — it tears the previous populations down first.
teardown( ) → void
Drop every population, buffer and mesh this module stood. A hot-reload replaces this module's table, and the previous instance's populations are still registered with the renderer while nothing holds a handle to them — so the sweep goes by the buffer NAMES the draws were registered under rather than by what this table happens to remember.
apply(t: number) → void
The garden's whole animation for film time `t`: seven scalar params, one dispatch per population, one instance count per population.
| arg | type | description |
|---|---|---|
| t | number |
report( ) → void
What the garden currently holds — one row per population, with the count it reserves and the count it is drawing this frame.
readLanes(name: string, first: number, count: number) → any
Start a readback of one population's lane buffer: `count` instances from `first`, four vec4 lanes each. Returns a pending handle — drain it with `:result()` a frame or two later. The read that answers whether every member of a population really is at its own moment.
| arg | type | description |
|---|---|---|
| name | string | |
| first | number | |
| count | number |
Pop = {Bed = { x: number, y: number, z: number, r: number, band: number, zone: number, ang: number }Sub-parts
Everything contained inside this part. Assets are composite children (clickable cards). Files are leaf payloads. Expand any row to view its source.
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.