Hue draws · The library
Whole living worlds, grown from code.
A WebGL2 engine with no models, no textures and no asset pipeline. Real light and shadow with a cinematic finish, GPU crowds, water with true reflections, skeletal figures that walk, and scenes that drive themselves toward objectives.
Install
npm i @hue/enginev1.0.0Zero dependencies. ESM only. Types are in the package.
The public surface
Measured with the TypeScript checker against the published types. The entry point is a barrel of star re-exports, so a search of it finds nothing — the count below is what the compiler resolves through them.
Public exports
961
Values
742
Types
219
Modules
39
Where to start
The entry points, with the signatures the package publishes. Everything else is reachable from the module list below.
Make a world
createWorldexport declare function createWorld(o: WorldOpts): WorldTHE FRONT DOOR — build a `World` on a canvas. Everything else in this package is reached through the object it returns.
Worldexport declare class World { private canvas; private gl; private overlay; private og; private opts; private flyMode; private pitchMin; private pitchMax; private renderedPitch; /** The pitch the camera is actually RENDERING with — `cam.pitch` after the user offset, * the parallax nudge and the orbit clamp ([0.18, 0.95]; fly mode ±1.15) are applied. * ⛔ WHY THIS EXISTS (FOREST S1): scenes derived sk…THE RENDERER AND THE SCENE GRAPH IN ONE OBJECT — build it with {@link createWorld}, never with `new` (the factory is the published surface and keeps the constructor free to change).
WorldOptsexport type WorldOpts = { canvas: HTMLCanvasElement; maxDpr?: number; drift?: number; parallax?: number; /** true = orbit (drag + ctrl-wheel zoom). "fly" (W13) = free flight: drag to look, * wheel to fly forward/back, W/A/S/D to move, shift for speed. */ controls?: boolean | "fly"; /** shadow maps — lights[0] casts. true, or { size (px, default 2048), softness, bias } */ shadows?: boolean | { size…Everything `createWorld` accepts. Only `canvas` is required; every other field has a stated default and the per-field docs below carry it. Passed once at build time — a world does not re-read these, so a scene that must change one rebuilds.
capturePosterexport declare function capturePoster(o: Omit<WorldOpts, "canvas" | "controls">, build: (w: World) => void, width: number, height: number, t?: number): string | nullRender a recipe's poster frame OFF-SCREEN and return it as a PNG data URL — the placeholder-image pattern: paint it into the window (an <img> beneath the live canvas) at page load, and build the live world only when the window scrolls into view. The scratch world renders on a hidden staged canvas (sizing reads clientWidth, so it must be in the DOM) and its GL context is released before returning — a page can poster every window it owns without spending its live-context budget. Overlay labels (drawLabel) are not part of a poster. Returns null when WebGL is unavailable — callers keep their CSS fallback.
Geometry — meshes you build
boxexport declare function box(sx: number, sy: number, sz: number): MeshAn axis-aligned box centred on the origin (flat-shaded faces).
planeexport declare function plane(sizeX: number, sizeZ: number, nx?: number, nz?: number): MeshA flat XZ plane centred on the origin, normal +Y.
icosphereexport declare function icosphere(radius: number, subdiv?: number): MeshAn icosphere — geodesic subdivision of the icosahedron; normals are exact (radial), so it shades perfectly smooth at any subdivision level.
tubeexport declare function tube(path: V3[], radius: number | ((u: number) => number), segments?: number, closed?: boolean, /** * ⛔ **CAP THE TWO OPEN ENDS — optional, absent ⇒ BIT-IDENTICAL (the `flat` precedent).** * * A `tube` is a sleeve: it has a boundary at each end and is not a closed surface. That is * correct for a stem going into the ground or a branch leaving a trunk, where the end is burie…Sweep a circular cross-section along a polyline path using parallel-transport frames (no twist). `radius` may be a constant or a per-station function of u in 0..1 — taper for free.
latheexport declare function lathe(profile: { x: number; y: number; }[], segments?: number): MeshRevolve a 2D profile (x = radius, y = height; x >= 0) around the Y axis.
extrudeexport declare function extrude(shape: { x: number; z: number; }[], height: number): MeshExtrude a 2D polygon (CCW, on XZ) straight up by `height` — walls + fan caps.
heightfieldexport declare function heightfield(f: (x: number, z: number) => number, sizeX: number, sizeZ: number, nx?: number, nz?: number): MeshA heightfield surface: y = f(x, z) sampled on an (nx x nz) grid over [-sizeX/2, sizeX/2] x [-sizeZ/2, sizeZ/2], smooth normals.
parametricexport declare function parametric(f: (u: number, v: number) => V3, nu: number, nv: number, opts?: { wrapU?: boolean; }): MeshGrid helper: builds (nx*nz) quads from a parametric surface, smooth normals from central differences. Used by plane, heightfield and lathe alike.
mergeMeshexport declare function mergeMesh(...parts: Mesh[]): MeshtransformMeshexport declare function transformMesh(m: Mesh, mat: M4): MeshSigned distance fields
spheresphere: (radius: number) => SDFboxSDFexport declare function boxSDF(sx: number, sy: number, sz: number, radius?: number): SDFA box of the given FULL extents. `radius` rounds every edge and corner — the cheapest realism there is, because a razor-perfect edge is the thing eyes read as fake.
torustorus: (ring: number, tube: number) => SDFA torus in the XZ plane: `ring` is the centreline radius, `tube` the thickness.
capsuleexport declare function capsule(a: V3, b: V3, radius: number): SDFA capsule (a segment swept by a sphere) — the honest primitive for a limb or a branch.
coneexport declare function cone(height: number, radius: number): SDFA cone standing on the XZ plane, apex at +height.
cylinderexport declare function cylinder(height: number, radius: number, round?: number): SDFA Y-axis cylinder of the given full height, optionally round-edged.
unionunion: (...fs: SDF[]) => SDFsubtractsubtract: (a: SDF, b: SDF) => SDF`a` with `b` cut out of it.
intersectintersect: (...fs: SDF[]) => SDFsmoothUnionsmoothUnion: (a: SDF, b: SDF, k: number) => SDFsdfMeshexport declare function sdfMesh(field: SDF, opts: SDFMeshOpts): MeshThe one-liner: field in, Mesh out, ready for `world.mesh()`.
marchSDFexport declare function marchSDF(field: SDF, opts: SDFMeshOpts): SDFMeshResultMesh a field. Synchronous: it runs to completion before returning, and at a few tens of thousands of triangles that is a visible pause on the main thread. `marchSDFAsync` is the same algorithm with the pause broken up — see it for when that matters.
Collision and rays
boundingSphereexport declare function boundingSphere(m: Mesh): SphereThe bounding sphere of a mesh — vertex centroid + max distance. Not the minimal sphere, but stable and cheap; grown once at registration.
boundingCapsuleYexport declare function boundingCapsuleY(m: Mesh): CapsuleThe Y-axis capsule of a mesh — radial extent in XZ, segment along Y inset by that radius (so the capsule's round ends stay inside the mesh's own top and bottom). The right auto-collider for anything grown upright: a trunk, a mast, a stem.
raySphereexport declare function raySphere(o: V3, dir: V3, s: Sphere, r?: number, maxDist?: number): number | nullRay vs sphere: nearest hit distance t ≥ 0 along a UNIT dir, or null. Pass `r` to sweep a moving sphere of that radius instead of a point; a ray starting inside reports the exit hit.
rayCapsuleexport declare function rayCapsule(o: V3, dir: V3, c: Capsule, r?: number, maxDist?: number): number | nullRay vs capsule: nearest hit distance t ≥ 0 along a UNIT dir, or null. Pass `r` to sweep a moving sphere of that radius. A ray starting inside reports the exit hit — the same contract as `raySphere`, kept deliberately so a walker embedded in a trunk can find its way OUT instead of reporting nothing. Cylinder band + two end-sphere caps.
sphereHitexport declare function sphereHit(a: Sphere, b: Sphere): { n: V3; depth: number; } | nullOverlap between two spheres — null when apart; otherwise the contact: `n` points from b to a (the push-out direction for a), `depth` the overlap.
capsuleHitexport declare function capsuleHit(s: Sphere, c: Capsule): { n: V3; depth: number; } | nullSphere vs capsule — the sphere/sphere contact against the capsule's closest point. `n` points from the capsule to the probe (the push-out direction for the probe), exactly `sphereHit`'s contract.
avoidanceFieldexport declare function avoidanceField(obstacles: { spheres?: readonly Sphere[]; capsules?: readonly Capsule[]; }, o: { range: number; strength: number; vertical?: number; tangent?: number; }): (p: V3, t: number) => V3THE STEERING BRIDGE: obstacles, expressed as a field an agent can be steered by.
Scenes that drive themselves
attachObjectivesexport declare function attachObjectives(world: World, opts?: ObjectivesOpts): ObjectivesAttach the objectives layer to a World. Rides the frame loop as a grow() hook and drives the World through its public verbs — the renderer is untouched.
Objectivesexport type Objectives = { define(name: string, spec: ObjectiveSpec): void; retarget(name: string, patch: Partial<ObjectiveSpec>): void; remove(name: string): void; onReading(cb: (r: MovementReading) => void): () => void; readings(): MovementReading[]; }The user-facing facade returned by attachObjectives().
ObjectiveSpecexport type ObjectiveSpec = { /** rigid-body goal for a named group — interpolated spec, applied via setTransform */ transform?: { group: string; to: TransformSpec; from?: TransformSpec; }; /** morph-weight goal for a named group (meshMorph geometry). Default from: 0. */ morph?: { group: string; to: number; from?: number; }; /** fade goal for a named group. Default from: 1. */ fade?: { group: stri…ObjectiveCameraexport type ObjectiveCamera = { target?: V3; dist?: number; pitch?: number; yaw?: number; }What this machine can draw
classifyRendererexport declare function classifyRenderer(renderer: string): GpuTierClassify a renderer string. PURE and testable — no GL, no DOM — so the table below can be argued with, extended, and checked against real strings in a unit test rather than discovered on someone's laptop.
GpuTierexport type GpuTier = { tier: "low" | "mid" | "high"; /** the raw renderer string, kept so a caller can log or override on evidence */ renderer: string; /** why this tier was chosen, in words — a classification nobody can interrogate is a magic number */ reason: string; /** * THE SCENE'S **POPULATION** BUDGET, 0..1 — HOW MANY, never how finely. Multiply instance * counts and scatter populations by…What the engine thinks this GPU is. `detail` is the number a SCENE spends.
FrameGovernorexport declare class FrameGovernor { /** the frame time to aim under, ms. 20 ms ≈ 50 fps, leaving headroom under a 60 Hz vsync. */ readonly targetMs: number; /** how many frames to gather before judging */ readonly window: number; /** the deepest cut allowed */ readonly maxLevel: number; /** * The least improvement a cut must buy to be worth keeping, as a fraction of the frame time * that triggere…unitsPerMetreOfexport declare function unitsPerMetreOf(s: Scale): number⚠ A World satisfies `Scale` structurally, so `growQuadruped(FOX, world)` reads correctly and needs no import in either direction — the same trick `FieldSampler` uses between flock and field. Nothing in this file knows what a World is.
Scaleexport type Scale = { unitsPerMetre: number; }What a caller passes instead of a size: "here is how big a metre is in this world."
The colour law
bornexport declare function born(hue: number): HeldA colour is born with its identity fixed, fully certain, and entirely unseen.
lightenexport declare function lighten(c: Held, weight: number): HeldOne observation's visibility. `L <- L + (1 - L) * weight` — fills toward the ceiling, never past.
drainexport declare function drain(c: Held, weight: number): HeldDisagreement drains certainty. `S <- S * (1 - weight)`. Never rises; never below 0.
observeexport declare function observe(substrate: Held, light: number, ambient?: number): HeldOBSERVE — shade a substrate colour by an amount of light, under the law.
participateexport declare function participate(p: number): number⛔ **PARTICIPATION AT THE FLOAT32 CROSSING — the CPU sibling of the shader's `participate()` (bug #107, completing #104).** Identity below the knee, so every value the old wall did not touch is byte-identical; above it, strictly increasing forever, approaching 1 and reaching it for no finite input. The knee is `LIGHT_CEILING` — the SAME constant the old `Math.min` walls used, re-pointed from wall to curve exactly as the shader's `L_CEIL` was, so the correction is provably confined to the band the walls were destroying. Use it where `toRgb()` uses it: at the READ-OUT, where a held value becomes a colour a 32-bit pipeline will carry — never on the accumulator, whose bound is `FLOAT64_LAST_BELOW_ONE` above.
toRgbexport declare function toRgb(c: Held): [number, number, number]The held colour as linear RGB, 0..1. Standard HSL geometry — the LAW is upstream of this, in what may reach the three channels, so the conversion itself has nothing to enforce and does not try.
Heldexport type Held = { readonly hue: number; readonly saturation: number; readonly lightness: number; }One concept's held state. `hue` is degrees; `saturation` and `lightness` are 0..1.
LIGHT_CEILINGLIGHT_CEILING: number⚠ **KEPT AS AN ALIAS SO EXISTING CALLERS AND THE SHADER CONSTANT STILL RESOLVE**, and renamed in meaning rather than deleted: this corpus corrects by append. It no longer names a ceiling because there is not one — see above.
Every module, mapped
Each module is a subsystem you can import from the package root, and everything it exports is listed under it. The descriptions are the library’s own, where it wrote one.
The world
world26 exportsno description in the package
Functions and values
FRAME_DT_MAXFRAME_DT_MAX = 0.05GROUP_LIMITGROUP_LIMIT = 8RAIN_RATIO_CLAMPRAIN_RATIO_CLAMP: readonly [number, number]SURFACE_KINDSSURFACE_KINDS: readonly SurfaceKind[]Worldexport declare class World { private canvas; private gl; private overlay; private og; private opts; private flyMode; private pitchMin; private pitchMax; private renderedPitch; /** The pitch the camera is actually RENDERING with — `cam.pitch` after the user offset, * the parallax nudge and the orbit clamp ([0.18, 0.95]; fly mode ±1.15) are applied. * ⛔ WHY THIS EXISTS (FOREST S1): scenes derived sk…capturePosterexport declare function capturePoster(o: Omit<WorldOpts, "canvas" | "controls">, build: (w: World) => void, width: number, height: number, t?: number): string | nullcreateWorldexport declare function createWorld(o: WorldOpts): WorldframeDeltaexport declare function frameDelta(ts: number, tPrev: number): numberrainDropFactorexport declare function rainDropFactor(u: number): numberstateFromMoodexport declare function stateFromMood(m: SkyMood, base?: WorldState): WorldStateTypes
ColliderCollisionHitFaceOptsGlowOptsGrowFnInstancedHandleLineOptsPointLightProjectedRayHitResultRibbonOptsSkyMoodSurfaceKindSurfaceSpecWindNowWorldOptsmath38 exportsno description in the package
Functions and values
GOLDEN_ANGLEGOLDEN_ANGLE: numberGOLDEN_FRACTIONGOLDEN_FRACTION: numberTAUTAU: number_degenerateWarned_degenerateWarned: (reset?: boolean) => booleanaddadd: (a: V3, b: V3) => V3applyM4export declare function applyM4(m: M4, p: V3): V3clampclamp: (v: number, lo: number, hi: number) => numbercrosscross: (a: V3, b: V3) => V3dotdot: (a: V3, b: V3) => numbereaseInOuteaseInOut: (u: number) => numberhslexport declare function hsl(h: number, s: number, l: number): [number, number, number]hslFromexport declare function hslFrom(c: [number, number, number]): { hue: number; sat: number; light: number; }lenlen: (a: V3) => numberlerplerp: (a: number, b: number, u: number) => numbermComposeexport declare function mCompose(spec: TransformSpec): M4mIdentmIdent: () => M4mInvertexport declare function mInvert(m: M4): M4mLookAtexport declare function mLookAt(eye: V3, at: V3, up: V3): M4mMulexport declare function mMul(a: M4, b: M4): M4mPerspectiveexport declare function mPerspective(fovy: number, aspect: number, near: number, far: number): M4mRotXexport declare function mRotX(a: number): M4mRotYexport declare function mRotY(a: number): M4mRotZexport declare function mRotZ(a: number): M4mScalemScale: (s: V3) => M4mTranslatemTranslate: (t: V3) => M4mTransposeexport declare function mTranspose(m: M4): M4mix3mix3: (a: V3, b: V3, u: number) => V3normnorm: (a: V3) => V3normOrnormOr: (a: V3, fallback: V3, eps?: number) => V3normOrNullnormOrNull: (a: V3, eps?: number) => V3 | nullnormalMat3export declare function normalMat3(m: M4): Float32Arrayrndexport declare function rnd(i: number, k: number): numberscalescale: (a: V3, s: number) => V3subsub: (a: V3, b: V3) => V3v3v3: (x?: number, y?: number, z?: number) => V3Types
M4TransformSpecV3geometry19 exportsno description in the package
Functions and values
UNPAINTEDUNPAINTED: Paintboxexport declare function box(sx: number, sy: number, sz: number): MeshcheckPaintexport declare function checkPaint(m: Mesh, where: string): MeshcolourQueryexport declare function colourQuery(mesh: Mesh, cell?: number): (x: number, z: number) => [number, number, number] | nullextrudeexport declare function extrude(shape: { x: number; z: number; }[], height: number): MeshheightQueryexport declare function heightQuery(mesh: Mesh, cell?: number): (x: number, z: number) => number | nullheightfieldexport declare function heightfield(f: (x: number, z: number) => number, sizeX: number, sizeZ: number, nx?: number, nz?: number): Meshicosphereexport declare function icosphere(radius: number, subdiv?: number): Meshlatheexport declare function lathe(profile: { x: number; y: number; }[], segments?: number): MeshmergeMeshexport declare function mergeMesh(...parts: Mesh[]): MeshmeshVertCountmeshVertCount: (m: Mesh) => numberpaintMeshexport declare function paintMesh(m: Mesh, paint: (i: number, x: number, y: number, z: number) => [number, number, number]): Meshparametricexport declare function parametric(f: (u: number, v: number) => V3, nu: number, nv: number, opts?: { wrapU?: boolean; }): Meshplaneexport declare function plane(sizeX: number, sizeZ: number, nx?: number, nz?: number): MeshrefineGroundexport declare function refineGround(mesh: Mesh, o: { targetEdge: (x: number, z: number) => number; heightAt: (x: number, z: number) => number; maxTris?: number; /** central-difference step for the normals, in world units */ eps?: number; }): MeshtransformMeshexport declare function transformMesh(m: Mesh, mat: M4): Meshtubeexport declare function tube(path: V3[], radius: number | ((u: number) => number), segments?: number, closed?: boolean, /** * ⛔ **CAP THE TWO OPEN ENDS — optional, absent ⇒ BIT-IDENTICAL (the `flat` precedent).** * * A `tube` is a sleeve: it has a boundary at each end and is not a closed surface. That is * correct for a stem going into the ground or a branch leaving a trunk, where the end is burie…Types
MeshPaintsdf36 exportsno description in the package
Functions and values
atat: (f: SDF, t: V3) => SDFbendbend: (f: SDF, k: number) => SDFboxSDFexport declare function boxSDF(sx: number, sy: number, sz: number, radius?: number): SDFcapsuleexport declare function capsule(a: V3, b: V3, radius: number): SDFconeexport declare function cone(height: number, radius: number): SDFcylinderexport declare function cylinder(height: number, radius: number, round?: number): SDFdisplacedisplace: (f: SDF, amp: number, freq: number) => SDFfbm3export declare function fbm3(x: number, y: number, z: number, octaves?: number, gain?: number, lacunarity?: number): numbergradientexport declare function gradient(field: SDF, p: V3, eps?: number): V3intersectintersect: (...fs: SDF[]) => SDFmarchSDFexport declare function marchSDF(field: SDF, opts: SDFMeshOpts): SDFMeshResultmarchSDFAsyncexport declare function marchSDFAsync(field: SDF, opts: SDFMeshOpts, o?: { sliceMs?: number; onProgress?: (fraction: number) => void; }): Promise<SDFMeshResult>meshAreaexport declare function meshArea(m: Mesh): numbermeshVolumeexport declare function meshVolume(m: Mesh): numbermirrorMeshXexport declare function mirrorMeshX(m: Mesh): Meshnoise3export declare function noise3(x: number, y: number, z: number): numberplaneSDFexport declare function planeSDF(normal: V3, offset?: number): SDFrepeatexport declare function repeat(f: SDF, period: { x?: number; y?: number; z?: number; }): SDFrotatedexport declare function rotated(f: SDF, r: { x?: number; y?: number; z?: number; }): SDFroundConeexport declare function roundCone(a: V3, b: V3, ra: number, rb: number): SDFroundedrounded: (f: SDF, r: number) => SDFscaledscaled: (f: SDF, s: number) => SDFsdfMeshexport declare function sdfMesh(field: SDF, opts: SDFMeshOpts): MeshsdfMeshAsyncexport declare function sdfMeshAsync(field: SDF, opts: SDFMeshOpts, o?: { sliceMs?: number; onProgress?: (fraction: number) => void; }): Promise<Mesh>shellshell: (f: SDF, thickness: number) => SDFsmoothIntersectsmoothIntersect: (a: SDF, b: SDF, k: number) => SDFsmoothSubtractsmoothSubtract: (a: SDF, b: SDF, k: number) => SDFsmoothUnionsmoothUnion: (a: SDF, b: SDF, k: number) => SDFspheresphere: (radius: number) => SDFsubtractsubtract: (a: SDF, b: SDF) => SDFtorustorus: (ring: number, tube: number) => SDFtwisttwist: (f: SDF, k: number) => SDFunionunion: (...fs: SDF[]) => SDFTypes
SDFSDFMeshOptsSDFMeshResultLight, sky and air
atmosphere26 exportsno description in the package
Functions and values
CLOUD_BEAM_TRANSMITTANCECLOUD_BEAM_TRANSMITTANCE = 0.3GROUND_ALBEDOGROUND_ALBEDO = 0.23LAMBDALAMBDA: RGBSKY_EXPOSURESKY_EXPOSURE = 3.2TEMPERATE_CLEARTEMPERATE_CLEAR: WorldStateaerosolDepthexport declare function aerosolDepth(state: WorldState): RGBairmassexport declare function airmass(sunElevation: number): numberatmosphereSelfCheckexport declare function atmosphereSelfCheck(): { ok: boolean; note: string; }[]extinctionPerMetreexport declare function extinctionPerMetre(state: WorldState): RGBlightSplitexport declare function lightSplit(state: WorldState, groundAlbedo?: number, cloudBeamTransmittance?: number): { ambient: number; diffuse: number; }miePhaseexport declare function miePhase(cosTheta: number, g?: number): numberozoneDepthexport declare function ozoneDepth(): RGBrayleighDepthexport declare function rayleighDepth(): RGBrayleighPhaseexport declare function rayleighPhase(cosTheta: number): numberskyColourexport declare function skyColour(state: WorldState): { zenith: RGB; horizon: RGB; }skyMoodFromStateexport declare function skyMoodFromState(state: WorldState, opts?: { glow?: number; satLift?: number; }): { zenith: HSL; horizon: HSL; sun: HSL & { size: number; glow: number; }; sunPitch: number; ambient: number; diffuse: number; fogDistK: number; }skyRadianceexport declare function skyRadiance(state: WorldState, viewElevation: number, viewAzimuth: number): RGBsunTransmittanceexport declare function sunTransmittance(state: WorldState): RGBtoHSLexport declare function toHSL(c: RGB, exposure?: number): HSLvisibilityMetresexport declare function visibilityMetres(state: WorldState): numberweatherToneexport declare function weatherTone(tone: SurfaceTone, state: WorldState): SurfaceTonewetSurfaceexport declare function wetSurface(state: WorldState): { albedoScale: number; gloss: number; }Types
HSLRGBSurfaceToneWorldStateclouds23 exportssix species, each built its own way — no two clouds alike
Functions and values
CLOUD_BUILDERSCLOUD_BUILDERS: Record<CloudSpecies, (seed: number, o?: CloudOpts) => CloudMesh>CLOUD_SPECIESCLOUD_SPECIES: readonly CloudSpecies[]altocumulusexport declare function altocumulus(seed: number, o?: AltocumulusOpts): CloudMeshcirrusexport declare function cirrus(seed: number, o?: CirrusOpts): CloudMeshcloudDetailexport declare function cloudDetail(r: number, bias?: number): numbercumulonimbusexport declare function cumulonimbus(seed: number, o?: CumulonimbusOpts): CloudMeshcumulusexport declare function cumulus(seed: number, o?: CumulusOpts): CloudMeshlenticularexport declare function lenticular(seed: number, o?: LenticularOpts): CloudMeshsplitByNormalexport declare function splitByNormal(m: Mesh, threshold: number, body: Mesh, base: Mesh, /** ⛔ **DROP A TRIANGLE THAT IS INSIDE ANOTHER LUMP.** Optional; absent ⇒ bit-identical. */ buried?: (x: number, y: number, z: number) => boolean): voidstratocumulusexport declare function stratocumulus(seed: number, o?: StratocumulusOpts): CloudMeshTypes
AltocumulusOptsAltocumulusShapeCirrusOptsCirrusShapeCloudMeshCloudOptsCloudSpeciesCumulonimbusOptsCumulusOptsCumulusShapeLenticularOptsStratocumulusOptsStratocumulusShapecloudphysics8 exportsno description in the package
Functions and values
CLOUD_ASYMMETRY_GCLOUD_ASYMMETRY_G = 0.85cloudOpacityexport declare function cloudOpacity(optics: CloudOptics, nDotV: number): numbercloudOpticsexport declare function cloudOptics(state: WorldState, depthM?: number): CloudOpticscloudPhysicsSelfCheckexport declare function cloudPhysicsSelfCheck(): { ok: boolean; note: string; }[]dewPointCexport declare function dewPointC(temperatureC: number, humidity: number): numbereffectiveRadiusMexport declare function effectiveRadiusM(state: WorldState): numberlclMetresexport declare function lclMetres(state: WorldState): numberTypes
CloudOpticsskyfield30 exportsthe sky as a composition: weather, perspective, drift
Functions and values
KIND_FALLBACKKIND_FALLBACK: Record<string, readonly string[]>SKY_CLOUD_KINDSSKY_CLOUD_KINDS: readonly ["cumulus-humilis", "cumulus", "cumulus-congestus", "cumulonimbus", "stratocumulus", "stratus", "altocumulus", "cirrocumulus", "cirrus"]SKY_MOODSSKY_MOODS: { [K in keyof typeof SKY_MOOD_LOOK]: typeof SKY_MOOD_LOOK[K] & { cloudCover: number; }; }SKY_MOOD_AUTHORED_SPLITSKY_MOOD_AUTHORED_SPLIT: Readonly<Record<string, { ambient: number; diffuse: number; }>>SKY_PRESETSSKY_PRESETS: Record<string, SkyPreset>albedoForBounceexport declare function albedoForBounce(target: { hue: number; sat: number; light: number; }, /** ⚠ **A `V3`, BECAUSE THAT IS WHAT `w.ambientGround` IS.** A tuple would have made every call * site convert, and a conversion at a call site is a place to get the channel order wrong. */ ground: V3): { hue: number; sat: number; light: number; }layoutSkyexport declare function layoutSky(spec: SkySpec, make: CloudFactory): SkyLayoutmeshExtentexport declare function meshExtent(...parts: (Mesh | undefined)[]): MeshExtentresolveKindexport declare function resolveKind(kind: CloudKind, vocab?: readonly string[]): { kind: string; substituted: boolean; }skyCoverageexport declare function skyCoverage(preset: SkyPreset): numberskyDriftexport declare function skyDrift(layout: SkyLayout, t: number): { group: string; transform: TransformSpec; }[]skyElevationWindowexport declare function skyElevationWindow(o: { pitch: number; halfFovY: number; mirror?: boolean; floor?: number; }): { min: number; max: number; }skyMaterialsFromOpticsexport declare function skyMaterialsFromOptics(optics: { topReflectance: number; baseTransmittance: number; }, hue?: number, /** ⛔ **THE GROUND BOUNCE THE BASE WILL BE MULTIPLIED BY — OPTIONAL, AND ABSENT MEANS UNCHANGED.** * Pass `w.ambientGround` and the base albedo is DERIVED so the delivered underside is the hue * that was authored (`albedoForBounce`, #183 arm B). Omit it and every existing ca…skySpecexport declare function skySpec(preset: string | SkyPreset, o: Omit<SkySpec, "layers"> & { layers?: readonly SkyLayerSpec[]; drift?: SkyDriftSpec; }): SkySpecskySummaryexport declare function skySummary(layout: SkyLayout): stringTypes
AngularDiscCloudFactoryCloudKindCloudPartsCloudPlacementKindPickMeshExtentSkyBatchSkyDriftSpecSkyLayerSpecSkyLayoutSkyMaterialSkyPresetSkySpecWind2hold10 exportsno description in the package
Functions and values
FLOAT32_LAST_BELOW_ONEFLOAT32_LAST_BELOW_ONE: numberFLOAT64_LAST_BELOW_ONEFLOAT64_LAST_BELOW_ONE: numberLIGHT_CEILINGLIGHT_CEILING: numberbornexport declare function born(hue: number): Helddrainexport declare function drain(c: Held, weight: number): Heldlightenexport declare function lighten(c: Held, weight: number): Heldobserveexport declare function observe(substrate: Held, light: number, ambient?: number): Heldparticipateexport declare function participate(p: number): numbertoRgbexport declare function toRgb(c: Held): [number, number, number]Types
HeldWater
water15 exportsserpentine lakes, their bed, their shore
Functions and values
LAKESLAKES: Record<string, LakeSpec>LONG_WATERLONG_WATER: LakeSpecROUND_PONDROUND_POND: LakeSpeclakeBedexport declare function lakeBed(spec: LakeSpec, size: number | Scale, o?: { nu?: number; nv?: number; }): MeshlakeBlendexport declare function lakeBlend(spec: LakeSpec, size: number | Scale, x: number, z: number, runOutM?: number): numberlakeBoundsexport declare function lakeBounds(spec: LakeSpec, size: number | Scale): { x0: number; z0: number; x1: number; z1: number; }lakeDepthAtexport declare function lakeDepthAt(spec: LakeSpec, size: number | Scale, x: number, z: number): numberlakeGroundYexport declare function lakeGroundY(spec: LakeSpec, size: number | Scale, x: number, z: number): numberlakeSurfaceexport declare function lakeSurface(spec: LakeSpec, size: number | Scale, o?: { nu?: number; nv?: number; }): MeshprepareLakeexport declare function prepareLake(spec: LakeSpec, size: number | Scale): PreparedLakerainDropexport declare function rainDrop(rateMmH: number, exposureS?: number): { diameterMm: number; fallMs: number; streakM: number; }rainVisibleFractionexport declare function rainVisibleFraction(rateMmH: number): numbershorelineexport declare function shoreline(spec: LakeSpec, size: number | Scale, spacing: number): { p: V3; normal: V3; }[]Types
LakeSpecPreparedLakecaustics22 exportsthe light on a shallow floor, driven by the water's own waves
Functions and values
CAUSTIC_DEFAULTSCAUSTIC_DEFAULTS: Readonly<{ amp: 3; level: 0; depth: 40; eta: 0.75; focus: 1; soften: 0.08; }>DEFAULT_CHOPDEFAULT_CHOP: Required<ChopSpec>DEFAULT_WATER_SIZEDEFAULT_WATER_SIZE = 4000ETA_WATERETA_WATER = 0.75REFERENCE_WAVESREFERENCE_WAVES: readonly CausticWave[]WATER_GRID_CELLSWATER_GRID_CELLS = 64attachCausticsexport declare function attachCaustics(world: World, opts?: CausticSplatOpts): CausticHandlebuildChopexport declare function buildChop(spec?: ChopSpec): CausticWave[]causticFieldexport declare function causticField(spec?: CausticsSpec): CausticFieldcausticLightexport declare function causticLight(field: CausticField, x: number, z: number, t: number, base: number, gain?: number): numbercausticSamplecausticSample: () => CausticSamplefirstFoldLeverexport declare function firstFoldLever(trace: number, det: number): numbersplatScalesplatScale: (intensity: number) => numberwaterGridNyquistKwaterGridNyquistK: (size?: number) => numberwaterGridNyquistWavelengthwaterGridNyquistWavelength: (size?: number) => numberTypes
CausticFieldCausticHandleCausticSampleCausticSplatOptsCausticWaveCausticsSpecChopSpecaquatic71 exportsfish, frogs, newts, reeds and lilies — the pond's own life
Functions and values
AMPHIBIAN_BONESAMPHIBIAN_BONES: readonly ["body", "head", "tail", "foreL.up", "foreL.lo", "foreR.up", "foreR.lo", "hindL.up", "hindL.lo", "hindL.ft", "hindR.up", "hindR.lo", "hindR.ft"]AMPHIBIAN_SPECIESAMPHIBIAN_SPECIES: Record<string, AmphibianSpec>AMPHIBIAN_WARTAMPHIBIAN_WART: Record<AmphibianSkin, number>AQUATIC_DETAILAQUATIC_DETAIL = 1AQUATIC_PLANTSAQUATIC_PLANTS: Record<string, AquaticPlantSpecies>CARPCARP: FishSpeciesCOMMON_FROGCOMMON_FROG: AmphibianSpecCOMMON_REEDCOMMON_REED: AquaticPlantSpeciesCOMMON_TOADCOMMON_TOAD: AmphibianSpecDUCKWEEDDUCKWEED: AquaticPlantSpeciesFISH_BONESFISH_BONES: readonly ["body", "spine1", "spine2", "spine3", "peduncle", "caudal", "dorsal", "anal", "pelvL", "pelvR", "pectL", "pectR"]FISH_SPECIESFISH_SPECIES: Record<string, FishSpecies>FISH_STROUHALFISH_STROUHAL = 0.3FISH_TAIL_AMPLITUDEFISH_TAIL_AMPLITUDE = 0.2HORNWORTHORNWORT: AquaticPlantSpeciesMARSH_MARIGOLDMARSH_MARIGOLD: AquaticPlantSpeciesMINNOWMINNOW: FishSpeciesPERCHPERCH: FishSpeciesPIKEPIKE: FishSpeciesPOND_AMPHIBIANSPOND_AMPHIBIANS: AmphibianSpec[]POND_FISHPOND_FISH: FishSpecies[]POND_MARGINPOND_MARGIN: AquaticPlantSpecies[]REEDMACEREEDMACE: AquaticPlantSpeciesROACHROACH: FishSpeciesRUDDRUDD: FishSpeciesSCALE_GLOSSSCALE_GLOSS = 0.55SHOAL_CYCLESHOAL_CYCLE: { /** a fish climbs at this share of its cruising speed. It is a real constraint — a rising fish is * still swimming — and it is what makes a carp's rise from two metres take seconds and not a * frame. */ readonly climbShare: 0.8; /** the shoal's own centre mills at this share of cruise, on a slow Lissajous. A shoal wanders; * it does not commute. */ readonly driftShare: 0.15; /** abo…SMOOTH_NEWTSMOOTH_NEWT: AmphibianSpecSTICKLEBACKSTICKLEBACK: FishSpeciesTENCHTENCH: FishSpeciesWATER_LILYWATER_LILY: AquaticPlantSpeciesWATER_MINTWATER_MINT: AquaticPlantSpeciesYELLOW_FLAGYELLOW_FLAG: AquaticPlantSpeciesamphibianPaintexport declare function amphibianPaint(rig: AmphibianRig, spec: AmphibianSpec): (i: number, x: number, y: number, z: number) => [number, number, number]amphibianUnitsexport declare function amphibianUnits(spec: AmphibianSpec, size: number | Scale): AmphibianSizeaquaticSelfCheckexport declare function aquaticSelfCheck(): { ok: boolean; note: string; }[]fishBandMexport declare function fishBandM(spec: FishSpecies, waterDepthM: number): { topM: number; bottomM: number; }fishBodyBonesfishBodyBones: readonly number[]fishBodyCrossSectionexport declare function fishBodyCrossSection(rig: FishRig): { z: number; depth: number; width: number; }fishCruiseBLexport declare function fishCruiseBL(spec: FishSpecies): numberfishPaintexport declare function fishPaint(rig: FishRig, spec: FishSpecies): (i: number, x: number, y: number, z: number) => [number, number, number]fishPosePairexport declare function fishPosePair(spec: FishSpecies): { from: Pose; to: Pose; }fishTailHzexport declare function fishTailHz(spec: FishSpecies): numberfishToneUnderexport declare function fishToneUnder(spec: FishSpecies, patch: "flank" | "belly" | "fin", state: WorldState): SurfaceTonefishUnitsexport declare function fishUnits(spec: FishSpecies, size: number | Scale): FishSizegrowAmphibianexport declare function growAmphibian(spec: AmphibianSpec, size: number | Scale, o?: AquaticOptions): AmphibianRiggrowAquaticPlantexport declare function growAquaticPlant(spec: AquaticPlantSpecies, size: number | Scale, seed: number): MeshgrowFishexport declare function growFish(spec: FishSpecies, size: number | Scale, o?: AquaticOptions): FishRigpondMarginAtexport declare function pondMarginAt(depthM: number): AquaticPlantSpecies[]shoalAtexport declare function shoalAt(spec: FishSpecies, t: number, o: { index: number; count: number; home: V3; scale: number | Scale; waterDepthM: number; spreadM?: number; seed?: number; }): FishMomentshoalSizeexport declare function shoalSize(spec: FishSpecies, seed?: number): numbervalidateAmphibianexport declare function validateAmphibian(spec: AmphibianSpec): voidvalidateAquaticPlantexport declare function validateAquaticPlant(spec: AquaticPlantSpecies): voidvalidateFishexport declare function validateFish(spec: FishSpecies): voidTypes
AmphibianPostureAmphibianRigAmphibianSizeAmphibianSkinAmphibianSpecAquaticFormAquaticHeadAquaticOptionsAquaticPlantSpeciesCaudalShapeFishActivityFishMomentFishRigFishSizeFishSpeciesWashWaterHabitWeather and motion
weather31 exportsONE WEATHER: U10 in, everything derived — gusts, lean, deck wind
Functions and values
EKMAN_VEER_RADEKMAN_VEER_RAD: numberGRADIENT_HEIGHT_MGRADIENT_HEIGHT_M = 270GUST_LENGTH_MGUST_LENGTH_M = 100GUST_REL_AMPSGUST_REL_AMPS: readonly [0.5, 0.3, 0.2]GUST_WAVELENGTHS_MGUST_WAVELENGTHS_M: readonly [100, number, number]HELLMANN_ALPHAHELLMANN_ALPHA: numberLEAN_REF_RADLEAN_REF_RAD: numberLEAN_REF_ULEAN_REF_U = 9MOOD_BLEND_SMOOD_BLEND_S = 3SIGMA_FBM4_T1SIGMA_FBM4_T1 = 0.1692SIGMA_FBM4_T4SIGMA_FBM4_T4 = 0.1039SWAY_EXPONENTSWAY_EXPONENT = 2SWAY_F0_HZSWAY_F0_HZ = 1.5SWAY_L0_MSWAY_L0_M = 0.6TURBULENCE_INTENSITYTURBULENCE_INTENSITY: numberTURBULENCE_Z0_MTURBULENCE_Z0_M = 0.03VOGEL_BVOGEL_B = -0.7WANDER_RMS_RADWANDER_RMS_RAD: numberWEATHER_SEEDWEATHER_SEED = 9241deckWindMsexport declare function deckWindMs(U10Ms: number, heightM: number): numbergustOmegasgustOmegas: (U10Ms: number) => [number, number, number]gustPeriodSexport declare function gustPeriodS(U10Ms: number): numbermeanLeanRadexport declare function meanLeanRad(UMs: number): numberrequireU10export declare function requireU10(v: unknown, where: string): numberswayOmegaexport declare function swayOmega(heightM: number): numberswayOscRadexport declare function swayOscRad(UMs: number): numberswitchWindexport declare function switchWind(sw: WindSwitch, oldU10: number, newU10: number, tNow: number): voidtravellingGustexport declare function travellingGust(alongM: number, t: number, U10Ms: number, sw: WindSwitch): numberwindSampleexport declare function windSample(U10Ms: number, seed: number, t: number, sw: WindSwitch): WindSampleTypes
WindSampleWindSwitchfield9 exportsone current/wind field everything samples — leaves, kelp, fish, foam
Functions and values
FIELD_PRESETSFIELD_PRESETS: Record<string, MotionFieldSpec>MotionFieldexport declare class MotionField { seed: number; prevailing: V3; gust: Layer; turbulence: Layer; advect: number; surfaceY: number; constructor(spec?: MotionFieldSpec); /** * The largest magnitude `sample` is expected to return, in world units per second. * * The triangle-inequality half IS exact: if each layer's unit field stays in the unit ball then * the sum cannot exceed |prevailing| + the two …fbm4export declare function fbm4(seed: number, x: number, y: number, z: number, w: number, octaves?: number, gain?: number, lacunarity?: number): numbergnoise4export declare function gnoise4(seed: number, x: number, y: number, z: number, w: number): numbergnoise4gexport declare function gnoise4g(seed: number, x: number, y: number, z: number, w: number, out: Float64Array | number[] | null): numbermotionFieldmotionField: (spec?: MotionFieldSpec) => MotionFieldTypes
FieldLayerFlow2MotionFieldSpecflock23 exportsseparation/alignment/cohesion, so a school IS a school
Functions and values
Flockexport declare class Flock { readonly agents: FlockAgent[]; /** Live — mutate any field between steps (move `goal.p`, drop `bounds`, retune a weight). */ params: FlockParams; /** Optional motion field. Assignable at any time; `params.fieldWeight` decides whether it acts. */ field: FieldSampler | null; readonly seed: number; /** accumulated simulated seconds — what the field sampler and the wander …agentBasisexport declare function agentBasis(a: FlockAgent): AgentBasisagentSpecexport declare function agentSpec(a: FlockAgent, size?: number | V3): TransformSpeccreateFlockexport declare function createFlock(o: FlockOpts): FlockdefaultFlockParamsexport declare function defaultFlockParams(): FlockParamsflockCentreexport declare function flockCentre(f: Flock | FlockAgent[]): V3flockMeanSpeedexport declare function flockMeanSpeed(f: Flock | FlockAgent[]): numberflockPolarisationexport declare function flockPolarisation(f: Flock | FlockAgent[]): numberresolveFlockParamsexport declare function resolveFlockParams(init?: FlockParamsInit): FlockParamsTypes
AgentBasisFieldSamplerFlockAgentFlockBoundsFlockBoundsInitFlockGoalFlockGoalInitFlockOptsFlockParamsFlockParamsInitFlockPerchFlockRuleFlockStateFlockWandercollision10 exportsno description in the package
Functions and values
avoidanceFieldexport declare function avoidanceField(obstacles: { spheres?: readonly Sphere[]; capsules?: readonly Capsule[]; }, o: { range: number; strength: number; vertical?: number; tangent?: number; }): (p: V3, t: number) => V3boundingCapsuleYexport declare function boundingCapsuleY(m: Mesh): CapsuleboundingSphereexport declare function boundingSphere(m: Mesh): SpherecapsuleHitexport declare function capsuleHit(s: Sphere, c: Capsule): { n: V3; depth: number; } | nullrayCapsuleexport declare function rayCapsule(o: V3, dir: V3, c: Capsule, r?: number, maxDist?: number): number | nullraySphereexport declare function raySphere(o: V3, dir: V3, s: Sphere, r?: number, maxDist?: number): number | nullsphereHitexport declare function sphereHit(a: Sphere, b: Sphere): { n: V3; depth: number; } | nullsumFieldsexport declare function sumFields(...fields: ((p: V3, t: number) => V3)[]): (p: V3, t: number) => V3Types
CapsuleSphereLiving things
animals12 exportsTHE FRONT DOOR — deer(world), fox(world): one call, one living animal
Functions and values
ANIMALSANIMALS: Record<string, (w: World, o?: AnimalOptions) => Animal>COATSCOATS: Record<string, Pelage>SPECIES_WITH_A_DOORSPECIES_WITH_A_DOOR: string[]badgerbadger: (w: World, o?: AnimalOptions) => Animaldeerdeer: (w: World, o?: AnimalOptions) => Animalfoxfox: (w: World, o?: AnimalOptions) => AnimalgrowAnimalexport declare function growAnimal(w: World, spec: QuadrupedSpec, o?: AnimalOptions): Animalharehare: (w: World, o?: AnimalOptions) => AnimalheadLiftAtexport declare function headLiftAt(t: number, e: QuadrupedEthology): numberherdCellexport declare function herdCell(w: World, specs: readonly QuadrupedSpec[]): numberTypes
AnimalAnimalOptionspeople10 exportsno description in the package
Functions and values
FIGURES_WITH_A_DOORFIGURES_WITH_A_DOOR: string[]OUTFITS_A_FIGURE_MAY_WEAROUTFITS_A_FIGURE_MAY_WEAR: readonly Outfit[]PEOPLEPEOPLE: Record<string, (w: World, o?: PersonOptions) => Person>WEARSWEARS: Record<string, Outfit>adultadult: (w: World, o?: PersonOptions) => Personchildchild: (w: World, o?: PersonOptions) => PersongrowPersonexport declare function growPerson(w: World, spec: BipedSpec, o?: PersonOptions): PersonpeopleCellexport declare function peopleCell(w: World, specs: readonly BipedSpec[]): numberTypes
PersonPersonOptionsaviary9 exportsno description in the package
Functions and values
BIRD_SKIN_RESOLUTIONBIRD_SKIN_RESOLUTION = 48aviaryResolutionexport declare function aviaryResolution(w: World, specs: readonly BirdSpecies[], o?: { base?: number; floor?: number; }): Map<string, number>growAviaryexport declare function growAviary(w: World, spec: BirdSpecies, o?: AviaryOptions): Aviarykestrelskestrels: (w: World, o?: AviaryOptions) => Aviaryrobinsrobins: (w: World, o?: AviaryOptions) => AviarytawnyOwlstawnyOwls: (w: World, o?: AviaryOptions) => AviarywoodPigeonswoodPigeons: (w: World, o?: AviaryOptions) => AviaryTypes
AviaryAviaryOptionscreatures52 exportsanimals GROWN from proportions — species as data
Functions and values
ADULTADULT: BipedSpecBADGERBADGER: QuadrupedSpecBIPEDSBIPEDS: Record<string, BipedSpec>CHILDCHILD: BipedSpecCREATURE_DETAILCREATURE_DETAIL = 1FOXFOX: QuadrupedSpecFROUDE_PENDULUM_MAXFROUDE_PENDULUM_MAX: numberGRAZE_CROUCHGRAZE_CROUCH = 0.12GRAZE_STAGGERGRAZE_STAGGER = 1.4HAREHARE: QuadrupedSpecQUADRUPEDSQUADRUPEDS: Record<string, QuadrupedSpec>REGIONREGION: { /** bare skin or plain fur — the fallback, and never a silent one: every vertex this file emits * is given a region explicitly, and `skin` means "nothing more specific is true here" */ readonly skin: 0; /** the hair-bearing crown and back of the head — where hair goes */ readonly scalp: 1; /** the front of the head below the hairline — where a face goes */ readonly face: 2; /** the muzzl…REGION_NAMESREGION_NAMES: readonly string[]ROE_DEERROE_DEER: QuadrupedSpecSEAT_M_DEFAULTSEAT_M_DEFAULT = 0.45assertOnGroundexport declare function assertOnGround(rig: Rig, pose: Pose, label: string, tol?: number): voidbehaveQuadrupedexport declare function behaveQuadruped(spec: QuadrupedSpec, agent: QuadrupedAgent, dt: number, size: number | Scale, near?: readonly QuadrupedNeighbour[]): QuadrupedAgentcouchedexport declare function couched(t?: number): PoseearsBackexport declare function earsBack(t?: number): PosegrowBipedexport declare function growBiped(spec: BipedSpec, size: number | Scale, o?: GrowOptions): CreatureRiggrowQuadrupedexport declare function growQuadruped(spec: QuadrupedSpec, size: number | Scale, o?: GrowOptions): CreatureRigheadDownexport declare function headDown(t?: number, o?: { rig?: Rig; crouch?: number; }): PoseheadUpexport declare function headUp(turn?: number): PoselowestOfBonesexport declare function lowestOfBones(rig: Rig, pose: Pose, boneNames: string[]): numberposeFloorexport declare function poseFloor(rig: Rig, pose: Pose): numberquadrupedAgentexport declare function quadrupedAgent(spec: QuadrupedSpec, seed: number, o: { id?: number; x: number; z: number; facing?: number; }): QuadrupedAgentquadrupedClockexport declare function quadrupedClock(spec: QuadrupedSpec): QuadrupedClockquadrupedExtentexport declare function quadrupedExtent(spec: QuadrupedSpec): QuadrupedExtentquadrupedGaitexport declare function quadrupedGait(spec: QuadrupedSpec, size: number | Scale): QuadrupedGaitquadrupedMorphPosesexport declare function quadrupedMorphPoses(rig: Rig): { graze: Pose; alert: Pose; }quadrupedPoseexport declare function quadrupedPose(rig: Rig, agent: QuadrupedAgent): Posesittingexport declare function sitting(o?: { lean?: number; hold?: number; turn?: number; seatM?: number; rig?: Rig; }): Posestandingexport declare function standing(shift?: number): PosestartleQuadrupedexport declare function startleQuadruped(spec: QuadrupedSpec, agent: QuadrupedAgent, fromX: number, fromZ: number, size: number | Scale): booleanwalkBipedexport declare function walkBiped(phase: number, stride?: number): PosewalkBipedKeysexport declare function walkBipedKeys(keys?: number, stride?: number): { phases: number[]; poses: Pose[]; at(phase: number): { pair: number; k: number; }; }walkQuadexport declare function walkQuad(phase: number, stride?: number): PosewalkQuadKeysexport declare function walkQuadKeys(keys?: number, stride?: number): { phases: number[]; poses: Pose[]; at(phase: number): { pair: number; k: number; }; }Types
BipedSpecCreatureRigGrowOptionsQuadrupedActivityQuadrupedAgentQuadrupedClockQuadrupedEthologyQuadrupedExtentQuadrupedGaitQuadrupedGaitPointQuadrupedNeighbourQuadrupedSpecRegionIdRegionRangebirds56 exportsthirteen woodland birds, species as data
Functions and values
BEATS_PER_BOUTBEATS_PER_BOUT = 4BIRDSBIRDS: Record<string, BirdSpecies>BIRD_ACTIVITIESBIRD_ACTIVITIES: readonly BirdActivity[]BIRD_BONESBIRD_BONES: readonly ["body", "neck", "head", "tail", "wingL.in", "wingL.out", "wingR.in", "wingR.out", "legL", "footL", "legR", "footR"]BIRD_CYCLEBIRD_CYCLE: { /** the level-flight coefficient in `birdCruiseMS` — `sqrt(2g / (ρ·C_L))` at ρ 1.225 and a * cruising C_L near 0.6 comes to ≈ 5.2; this is that, rounded. */ readonly cruiseK: 5; /** `birdTakeoffSeconds` = base + per-loading × kg/m². Chosen so the thirteen span 0.26–0.76 s. */ readonly takeoffBaseS: 0.16; readonly takeoffPerLoadingS: 0.055; /** the landing takes this much longer than …BIRD_HABITATSBIRD_HABITATS: readonly BirdHabitat[]BLACKBIRDBLACKBIRD: BirdSpeciesCHAFFINCHCHAFFINCH: BirdSpeciesFEATHER_GLOSSFEATHER_GLOSS = 0.06GREAT_TITGREAT_TIT: BirdSpeciesJAYJAY: BirdSpeciesKESTRELKESTREL: BirdSpeciesNUTHATCHNUTHATCH: BirdSpeciesPHEASANTPHEASANT: BirdSpeciesROBINROBIN: BirdSpeciesSWIFTSWIFT: BirdSpeciesTAWNY_OWLTAWNY_OWL: BirdSpeciesWOODLAND_BIRDSWOODLAND_BIRDS: BirdSpecies[]WOODPECKERWOODPECKER: BirdSpeciesWOOD_PIGEONWOOD_PIGEON: BirdSpeciesWRENWREN: BirdSpeciesbirdActivityAtexport declare function birdActivityAt(spec: BirdSpecies, t: number, o: { at: V3; scale: number | Scale; facing?: number; index?: number; seed?: number; state?: "ground" | "air"; circuitM?: number; }): BirdMomentbirdBoutexport declare function birdBout(spec: BirdSpecies, t: number): { u: number; period: number; flapTime: number; rest: number; }birdCruiseMSexport declare function birdCruiseMS(spec: BirdSpecies): numberbirdDensityexport declare function birdDensity(spec: BirdSpecies, habitat: BirdHabitat): numberbirdFlockSizeexport declare function birdFlockSize(spec: BirdSpecies, seed?: number): numberbirdFootDropMexport declare function birdFootDropM(spec: BirdSpecies, resolution?: number): numberbirdGroundBoutexport declare function birdGroundBout(spec: BirdSpecies): BirdGroundBoutbirdPaintexport declare function birdPaint(rig: Rig, spec: BirdSpecies): (i: number, x: number, y: number, z: number) => [number, number, number]birdPeckPoseexport declare function birdPeckPose(spec: BirdSpecies, down?: number): PosebirdPerchableexport declare function birdPerchable(spec: BirdSpecies): booleanbirdPoseexport declare function birdPose(spec: BirdSpecies, t: number, o?: { bank?: number; phase?: number; amp?: number; }): PosebirdPoseSetexport declare function birdPoseSet(spec: BirdSpecies): BirdPosePair[]birdSolidsexport declare function birdSolids(rig: Rig, spec: BirdSpecies, size: number | Scale, resolution?: number): BoneSolid[]birdStandPoseexport declare function birdStandPose(spec: BirdSpecies, settle?: number): PosebirdTakeoffSecondsexport declare function birdTakeoffSeconds(spec: BirdSpecies): numberbirdToneUnderexport declare function birdToneUnder(spec: BirdSpecies, patch: "body" | "belly" | "wing" | "head" | "horn", state: WorldState): SurfaceTonebirdUnitsexport declare function birdUnits(spec: BirdSpecies, size: number | Scale): BirdSizebirdWingAreaexport declare function birdWingArea(spec: BirdSpecies): numberbirdWingLoadingexport declare function birdWingLoading(spec: BirdSpecies): numberbirdsForexport declare function birdsFor(habitat: BirdHabitat, o?: { areaHa: number; detail?: number; seed?: number; from?: BirdSpecies[]; }): BirdAssemblage[]birdsSelfCheckexport declare function birdsSelfCheck(): { ok: boolean; note: string; }[]growBirdexport declare function growBird(spec: BirdSpecies, size: number | Scale): RigvalidateBirdexport declare function validateBird(spec: BirdSpecies): voidTypes
BirdActivityBirdAssemblageBirdFlightBirdGaitBirdGroundBoutBirdHabitBirdHabitatBirdMomentBirdPosePairBirdSizeBirdSpeciesPlumageinsects23 exportsthe small flying life, species as data
Functions and values
CHITIN_GLOSSCHITIN_GLOSS = 0.1DRAGONFLYDRAGONFLY: InsectSpeciesFLIGHT_COLUMN_MFLIGHT_COLUMN_M: Record<Exclude<InsectFlight, "trundle">, { radius: number; height: number; rate: number; jitter: number; }>FLIGHT_GIRTHFLIGHT_GIRTH: Record<InsectFlight, number>FLIGHT_WINGFLIGHT_WING: Record<InsectFlight, { freq: number; amp: number; }>HONEY_BEEHONEY_BEE: InsectSpeciesHOVERFLYHOVERFLY: InsectSpeciesINSECTSINSECTS: Record<string, InsectSpecies>LADYBIRDLADYBIRD: InsectSpeciesMEADOW_BROWNMEADOW_BROWN: InsectSpeciesMEADOW_INSECTSMEADOW_INSECTS: InsectSpecies[]MIDGEMIDGE: InsectSpeciesRED_ADMIRALRED_ADMIRAL: InsectSpeciesgrowInsectexport declare function growInsect(spec: InsectSpecies, size: number | Scale, seed?: number): MeshgrowInsectWingsexport declare function growInsectWings(spec: InsectSpecies, size: number | Scale): MeshinsectFlightParamsexport declare function insectFlightParams(spec: InsectSpecies, world: Scale): { mode: "swarm"; wing: { freq: number; amp: number; }; swarm: { radius: number; height: number; rate: number; jitter: number; }; }insectToneUnderexport declare function insectToneUnder(spec: InsectSpecies, patch: "body" | "wing", state: WorldState): SurfaceToneinsectUnitsexport declare function insectUnits(spec: InsectSpecies, size: number | Scale): InsectSizeinsectsSelfCheckexport declare function insectsSelfCheck(): { ok: boolean; note: string; }[]validateInsectexport declare function validateInsect(spec: InsectSpecies): voidTypes
InsectFlightInsectSizeInsectSpeciesskeletal40 exportsno description in the package
Functions and values
BIPED_FEETBIPED_FEET: readonly string[]BONE_LIMITBONE_LIMIT = 16QUADRUPED_FEETQUADRUPED_FEET: readonly string[]SKIN_SLOTSSKIN_SLOTS = 4alertPoseexport declare function alertPose(turn?: number): PoseautoSkinexport declare function autoSkin(bones: Bone[], mesh: Mesh, boneOf: number[], band?: number): SkinbakePoseexport declare function bakePose(rig: Rig, pose: Pose): MeshbakeStandingexport declare function bakeStanding(rig: Rig, pose: Pose, standsOn?: readonly string[]): Meshbirdexport declare function bird(span?: number): RigcomposePoseexport declare function composePose(bones: Bone[], pose: Pose): Float32ArraycrouchPoseexport declare function crouchPose(t?: number): PosedeerAlertexport declare function deerAlert(turn?: number): PosedeerGrazeexport declare function deerGraze(t?: number): PosedeerRigexport declare function deerRig(h?: number): Rigfishexport declare function fish(len?: number): RigflapPoseexport declare function flapPose(phase: number, amp?: number): PosefoldPoseexport declare function foldPose(t?: number): PoseglidePoseexport declare function glidePose(bank?: number, dihedral?: number): PosegrazePoseexport declare function grazePose(t?: number): Posehumanoidexport declare function humanoid(h?: number): RigmixPoseexport declare function mixPose(a: Pose, b: Pose, t: number): PoseperchPoseexport declare function perchPose(settle?: number): Posepersonexport declare function person(h?: number): RigpersonSitexport declare function personSit(o?: { lean?: number; hold?: number; turn?: number; }): Posequadrupedexport declare function quadruped(h?: number): Rigrabbitexport declare function rabbit(L?: number): RigrabbitAlertexport declare function rabbitAlert(turn?: number): PoserabbitFlatexport declare function rabbitFlat(t?: number): PoserestrictSkinToHierarchyexport declare function restrictSkinToHierarchy(bones: Bone[], skin: Skin): SkinsitPoseexport declare function sitPose(o?: { lean?: number; hold?: number; turn?: number; }): PoseswimPoseexport declare function swimPose(phase: number, amp?: number, wavelength?: number): PosetrotPoseexport declare function trotPose(phase: number, stride?: number): PosevalidatePoseexport declare function validatePose(bones: Bone[], pose: Pose): voidvalidateRigexport declare function validateRig(rig: Rig): voidwalkPoseexport declare function walkPose(phase: number, stride?: number): PoseTypes
BonePosePoseRotRigSkinskin32 exportsno description in the package
Functions and values
CELLS_ACROSS_A_FEATURECELLS_ACROSS_A_FEATURE = 8GARMENT_REACHGARMENT_REACH = 2.2SKIN_FILLETSKIN_FILLET = 0.45SKIN_REACHSKIN_REACH = 2.6bipedFaceexport declare function bipedFace(bones: readonly Bone[], spec: BipedSpec, heightUnits: number): (boneName: string, p: V3, n: V3) => number | undefinedbipedHeadCellexport declare function bipedHeadCell(rig: Rig, spec: BipedSpec, heightUnits: number): numberbipedLegCellexport declare function bipedLegCell(rig: Rig, spec: BipedSpec, heightUnits: number): numberbipedSkinResolutionexport declare function bipedSkinResolution(rig: Rig, spec: BipedSpec, heightUnits: number, detail?: number, cellUnits?: number): numberbipedSolidsexport declare function bipedSolids(rig: Rig, spec: BipedSpec, heightUnits: number): BoneSolid[]bodyFieldexport declare function bodyField(solids: readonly BoneSolid[], fillet?: number, bones?: readonly Bone[]): SDFdistToSegmentexport declare function distToSegment(p: V3, a: V3, b: V3): numbergarmentFieldexport declare function garmentField(solids: readonly BoneSolid[], covers: readonly GarmentCover[], thickness: number, bones?: readonly Bone[]): SDFgrowGarmentexport declare function growGarment(bones: readonly Bone[], solids: readonly BoneSolid[], covers: readonly GarmentCover[], thickness: number, o?: { resolution?: number; from?: Rig; regionOf?: (boneName: string, p: V3, n: V3) => number | undefined; }): { /** ⚠ carries `region` so `dress()` takes its DECLARED path — *"when the rig says what each * vertex IS, believe it"* — rather than falling throug…growGarmentShellexport declare function growGarmentShell(skin: Rig & { region?: number[]; }, solids: readonly BoneSolid[], covers: readonly GarmentCover[], thickness: number, o?: { lift?: number; }): { rig: Rig & { region: number[]; }; /** * For each garment vertex, the SKIN vertex it was lifted from. * * ⛔ **RETURNED BECAUSE WITHOUT IT THE LAYER CANNOT BE HONESTLY MEASURED.** The obvious check — * *is every garm…growSkinexport declare function growSkin(bones: readonly Bone[], solids: readonly BoneSolid[], o?: { resolution?: number; margin?: number; from?: Rig; regionOf?: (boneName: string, p: V3, n: V3) => number | undefined; }): { /** ⚠ carries `region` so `dress()` takes its DECLARED path — *"when the rig says what each * vertex IS, believe it"* — rather than falling through to a derivation written for the swep…marchBoxOfexport declare function marchBoxOf(solids: readonly BoneSolid[], margin?: number): { min: V3; max: V3; }marchSpanOfexport declare function marchSpanOf(solids: readonly BoneSolid[], margin?: number): numbernearestSolidOfexport declare function nearestSolidOf(mesh: Mesh, solids: readonly BoneSolid[]): number[]nearestVerticesexport declare function nearestVertices(mesh: Mesh, o: { /** one point per instance of the feature — two eyes, one nose, two ears */ at: readonly V3[]; /** * How far from a target a vertex may be and still be a candidate. **Omit for no bound** — the * biped's face works that way, taking the K nearest out of the whole head with no ball at all, * and a `reach` it did not ask for would silently chang…outfitCoversexport declare function outfitCovers(bones: readonly Bone[], outfit: { sleeves: "long" | "short" | "none"; hem: "long" | "short"; }): { top: GarmentCover[]; legs: GarmentCover[]; }quadrupedLegCellexport declare function quadrupedLegCell(rig: Rig, spec: QuadrupedSpec, withersUnits: number): numberquadrupedSkinResolutionexport declare function quadrupedSkinResolution(rig: Rig, spec: QuadrupedSpec, withersUnits: number, detail?: number, cellUnits?: number): numberquadrupedSolidsexport declare function quadrupedSolids(rig: Rig, spec: QuadrupedSpec, withersUnits: number): BoneSolid[]regionsFromSolidsexport declare function regionsFromSolids(mesh: Mesh, solids: readonly BoneSolid[], bones: readonly Bone[], o?: { of?: (boneName: string, p: V3, n: V3) => number | undefined; minReach?: number; }): number[]skinFromSolidsexport declare function skinFromSolids(mesh: Mesh, solids: readonly BoneSolid[], minReach?: number): { skin: Skin; boneOf: number[]; }solidsMirrorXexport declare function solidsMirrorX(solids: readonly BoneSolid[]): booleanstampBipedFaceexport declare function stampBipedFace(rig: Rig & { region?: number[]; }, spec: BipedSpec, heightUnits: number, o?: { eyeFrac?: number; noseFrac?: number; earFrac?: number; }): { eye: number; nose: number; ear: number; }stampNearestexport declare function stampNearest(rig: Rig & { region?: number[]; }, o: Parameters<typeof nearestVertices>[1] & { region: number; keep?: readonly number[]; }): number[]stampQuadrupedEyesexport declare function stampQuadrupedEyes(rig: Rig & { region?: number[]; }, spec: QuadrupedSpec, withersUnits: number, o?: { frac?: number; reach?: number; }): number[]wearLayersexport declare function wearLayers(...layers: readonly (Rig & { region?: number[]; })[]): Rig & { region: number[]; }Types
BoneSolidGarmentCovergarments29 exportsskin, fur, cloth, shoes — the surface a creature wears
Functions and values
BADGER_PELAGEBADGER_PELAGE: PelageCHILD_PLAYCHILD_PLAY: OutfitCLOTH_GLOSSCLOTH_GLOSS = 0.05FOX_PELAGEFOX_PELAGE: PelageGARMENT_MGARMENT_M: { /** the standing band of a collar, above the shoulder line */ readonly collar: 0.03; /** a jacket cuff — the turned band at the wrist */ readonly cuff: 0.025; /** ⛔ HOOD CLOTH DEPTH — a lined hood is thicker than a shirt, and it needs SOME depth or its * opening is a paper edge (31 boundary edges, measured on a seated WINTER_COAT). 12 mm is a * waxed outer plus a lining, which is what…HARE_PELAGEHARE_PELAGE: PelageHILL_WALKERHILL_WALKER: OutfitOUTFITSOUTFITS: Outfit[]PELAGESPELAGES: Pelage[]REFERENCE_ADULT_MREFERENCE_ADULT_M = 1.72ROE_PELAGEROE_PELAGE: PelageRUNNERRUNNER: OutfitSUMMER_WALKERSUMMER_WALKER: OutfitWINTER_COATWINTER_COAT: Outfit_unbuiltLayerWarningsexport declare function _unbuiltLayerWarnings(reset?: boolean): string[]colourCensusexport declare function colourCensus(mesh: Mesh, round?: number): { distinct: number; counts: Map<string, number>; }dressexport declare function dress(rig: Rig, outfit: Outfit, size: number | Scale): RiggarmentToneUnderexport declare function garmentToneUnder(p: Palette, outfit: Outfit, state: WorldState): SurfaceTonegarmentsSelfCheckexport declare function garmentsSelfCheck(): { ok: boolean; note: string; }[]outfitPalettesexport declare function outfitPalettes(outfit: Outfit): Record<string, Palette>pelageAtDetailexport declare function pelageAtDetail(pelage: Pelage, detail: number): Pelagepeltexport declare function pelt(rig: Rig, pelage: Pelage, size: number | Scale): RigsiteMapexport declare function siteMap(rig: Rig): (v: number) => VertexSiteTypes
BodyChainOutfitPalettePelagePelageMarkingVertexSiteanthropometry9 exportsno description in the package
Functions and values
ALLALL: readonly (readonly [string, Segment])[]BREADTHBREADTH: { readonly shoulder: Segment; /** * ⛔ **THE WIDEST THING ON A BODY IS NOT `shoulder`, AND THE FIGURE HAS BEEN JUDGED AGAINST THE * WRONG ROW (#269, 2026-09-01).** `biacromialbreadth` is **bone to bone at the acromion**. The * SILHOUETTE runs over the deltoids, and ANSUR measures that separately: * * biacromial 0.2330 ⇒ 40.1 cm the two acromion processes * **bideltoid 0.2857 ⇒ 49.1 cm** wh…GIRTHGIRTH: { readonly neck: Segment; readonly head: Segment; readonly shoulder: Segment; readonly upperArm: Segment; readonly foreArm: Segment; readonly wrist: Segment; readonly thighUpper: Segment; readonly thighLower: Segment; readonly calf: Segment; readonly ankle: Segment; }HEIGHTHEIGHT: { readonly crown: Segment; readonly eye: Segment; readonly chin: Segment; readonly shoulder: Segment; /** * ⛔ **THE ARMPIT — WHERE THE ARM STOPS BEING PART OF THE TORSO (added 2026-09-01).** Operator, on * the render: *"you have no collisipon control on the arms"*. They are right, and this row is the * line the rule is written against. * * **ABOVE it the deltoid genuinely OVERLIES the ribc…RATIORATIO: { /** * A skull is taller than it is wide. * * ⛔ **1.30 → 1.464 ON 2026-09-01, AND IT IS A CONSTRAINT BETWEEN TWO OTHER ROWS RATHER THAN A * READING OF ITS OWN.** `SEGMENT.head ÷ BREADTH.head` = 0.1300 / 0.0888 = **1.464**, and the row * said 1.30 — a **12.6 % disagreement created the moment `BREADTH.head` was corrected** by ANSUR * II. *Changing one row of a table silently falsified anothe…SEGMENTSEGMENT: { readonly head: Segment; readonly neck: Segment; readonly upperArm: Segment; readonly foreArm: Segment; readonly hand: Segment; readonly thigh: Segment; readonly shank: Segment; readonly foot: Segment; /** ⛔ HEEL TO THE BALL — where a foot is WIDEST, and it is **74 % of the way to the toe**, not * halfway. A single taper aimed at the toe would put the widest point in the wrong place. */ …tableSelfCheckexport declare function tableSelfCheck(): { ok: boolean; note: string; }[]Types
ConfidenceSegmentGrowing things
wood7 exportsno description in the package
Functions and values
birchesbirches: (w: World, o?: WoodOptions) => WoodgrowWoodexport declare function growWood(w: World, species: TreeSpecies, o?: WoodOptions): Woodoaksoaks: (w: World, o?: WoodOptions) => Woodpinespines: (w: World, o?: WoodOptions) => WoodTypes
StandingTreeWoodWoodOptionsflowers4 exportsno description in the package
Functions and values
abundanceShareexport declare function abundanceShare(species: readonly FlowerSpecies[], total: number): [FlowerSpecies, number][]growFlowersexport declare function growFlowers(w: World, species: FlowerSpecies, o?: FlowersOptions): FlowersTypes
FlowersFlowersOptionsturf4 exportsno description in the package
Functions and values
growTurfexport declare function growTurf(w: World, spec: SwardSpec, o?: TurfOptions): TurfTypes
TurfTurfBandTurfOptionstrees13 exportstree SPECIES — the oak's proven recursion, species as data
Functions and values
BIRCHBIRCH: TreeSpeciesOAKOAK: TreeSpeciesPINEPINE: TreeSpeciesTREE_SPECIESTREE_SPECIES: Record<string, TreeSpecies>foliageAnchorsexport declare function foliageAnchors(tree: GrownTree, species: TreeSpecies, unitsPerMetre: number): TreeTip[]growTreeexport declare function growTree(species: TreeSpecies, height: number | Scale, o?: { seed?: number; minR?: number; }): GrownTreelimbMeshexport declare function limbMesh(limb: TreeLimb, o?: { barkAmp?: number; barkSeed?: number; }): MeshstandPlanexport declare function standPlan(o: { seed: number; count: number; radius: number; minGap: number; mix: { species: string; weight: number; }[]; }): { p: { x: number; z: number; }; species: string; seed: number; }[]treeMeshexport declare function treeMesh(tree: GrownTree, o?: { barkAmp?: number; fromDepth?: number; }): MeshTypes
GrownTreeTreeLimbTreeSpeciesTreeTipflora16 exportsleaves, grass, flowers — the vegetation vocabulary
Functions and values
ROOT_SINKROOT_SINK = 0.12STEM_LEANSTEM_LEAN = 0.1bladeexport declare function blade(h: number, w: number, bendDir: V3, bend: number, seg?: number): MeshflowerHeadexport declare function flowerHead(h: number, petals: number, seed: number, o?: { centreR?: number; }): MeshflowerSpikeexport declare function flowerSpike(h: number, florets: number, seed: number): MeshflowerStemexport declare function flowerStem(h: number, diameter: number): MeshgrassTuftexport declare function grassTuft(n: number, h: number, w: number, seed: number, seg?: number, spread?: number, bend?: number): MeshleafCardexport declare function leafCard(base: V3, dir: V3, L: number, n: V3): MeshleafClumpexport declare function leafClump(kind: LeafKind, count: number, r: number, seed: number, leafLen?: number): MeshneedleTuftexport declare function needleTuft(base: V3, dir: V3, L: number, n: V3): Meshrosetteexport declare function rosette(n: number, r: number, seed: number): MeshseedHeadexport declare function seedHead(h: number, seed: number): Meshsprigexport declare function sprig(base: V3, dir: V3, L: number, roll: number, n: V3): MeshstemAtexport declare function stemAt(h: number, u: number): V3umbelexport declare function umbel(h: number, rays: number, seed: number): MeshTypes
LeafKindmeadow40 exportsflower + grass SPECIES — the meadow, askable by name
Functions and values
BLUEBELLBLUEBELL: FlowerSpeciesBRACKENBRACKEN: GrassSpeciesBROAD_DOCKBROAD_DOCK: GrassSpeciesBUTTERCUPBUTTERCUP: FlowerSpeciesCOW_PARSLEYCOW_PARSLEY: FlowerSpeciesDEAD_THATCHDEAD_THATCH: GrassSpeciesDRY_STRAWDRY_STRAW: GrassSpeciesFINE_GRASSFINE_GRASS: GrassSpeciesFLOWER_SPECIESFLOWER_SPECIES: Record<string, FlowerSpecies>FOXGLOVEFOXGLOVE: FlowerSpeciesGRASS_SPECIESGRASS_SPECIES: Record<string, GrassSpecies>GROUND_LITTERGROUND_LITTER: GrassSpecies[]LEAF_LITTERLEAF_LITTER: GrassSpeciesLITTER_SPECIESLITTER_SPECIES: Record<string, GrassSpecies>MEADOW_FLOWERSMEADOW_FLOWERS: FlowerSpecies[]MEADOW_FOXTAILMEADOW_FOXTAIL: GrassSpeciesMEADOW_GRASSMEADOW_GRASS: GrassSpeciesMEADOW_GROUNDMEADOW_GROUND: GrassSpecies[]MOSS_CUSHIONMOSS_CUSHION: GrassSpeciesOXEYE_DAISYOXEYE_DAISY: FlowerSpeciesPETAL_GLOSSPETAL_GLOSS = 0.03PIGNUTPIGNUT: FlowerSpeciesPLANTAINPLANTAIN: GrassSpeciesPOPPYPOPPY: FlowerSpeciesQUAKING_GRASSQUAKING_GRASS: GrassSpeciesSCABIOUSSCABIOUS: FlowerSpeciesTALL_BENTTALL_BENT: GrassSpeciesYORKSHIRE_FOGYORKSHIRE_FOG: GrassSpeciesflowerToneUnderexport declare function flowerToneUnder(spec: FlowerSpecies, part: "face" | "stem", state: WorldState): SurfaceTonegroundPlantexport declare function groundPlant(name: string): GrassSpeciesgrowFlowerexport declare function growFlower(species: FlowerSpecies, size: number | Scale, seed: number): { head: Mesh; stem: Mesh; }growGrassexport declare function growGrass(species: GrassSpecies, size: number | Scale, seed: number): MeshmeadowSelfCheckexport declare function meadowSelfCheck(): { ok: boolean; note: string; }[]Types
FlowerFormFlowerSpeciesGrassFormGrassSpeciesSwayToneTuftShapesward54 exportsground cover that is good at every distance
Functions and values
BARE_COVERBARE_COVER: GroundCoverCAM_FOCAL_MULCAM_FOCAL_MUL = 1.15CAM_PITCH_RADCAM_PITCH_RAD = 0.5COVER_BLENDCOVER_BLEND = 0.18COVER_CALIBRATION_NCOVER_CALIBRATION_N = 4096COVER_KINDSCOVER_KINDS: readonly CoverKind[]COVER_SPECSCOVER_SPECS: Record<CoverKind, GroundCover>DAMP_COVERDAMP_COVER: GroundCoverDAMP_SWARDDAMP_SWARD: SwardSpecFAIRWAY_COVERFAIRWAY_COVER: GroundCoverGREEN_COVERGREEN_COVER: GroundCoverGROUND_COVERSGROUND_COVERS: readonly GroundCover[]LAWN_SWARDLAWN_SWARD: SwardSpecLITTER_MIN_PX2LITTER_MIN_PX2 = 4MEADOW_COVERMEADOW_COVER: GroundCoverMEADOW_SWARDMEADOW_SWARD: SwardSpecMOWN_COVERMOWN_COVER: GroundCoverROUGH_COVERROUGH_COVER: GroundCoverROUGH_SWARDROUGH_SWARD: SwardSpecSAND_COVERSAND_COVER: GroundCoverSWARDSSWARDS: readonly SwardSpec[]SWARD_SPECSSWARD_SPECS: Record<string, SwardSpec>TEE_COVERTEE_COVER: GroundCoverWORN_COVERWORN_COVER: GroundCoverWORN_SWARDWORN_SWARD: SwardSpecatDetailexport declare function atDetail(covers: readonly GroundCover[], detail: number): GroundCover[]bandAreaM2export declare function bandAreaM2(band: SwardBand, radiusM: number): numberbandCountexport declare function bandCount(band: SwardBand, radiusM: number): numbercheckCoverexport declare function checkCover(cover: GroundCover, fn: string): voidcheckSwardexport declare function checkSward(spec: SwardSpec, fn: string): voidcoverPatchFloorMexport declare function coverPatchFloorM(spacingM: number): numbercoverReachMexport declare function coverReachM(patchM: number, spacing: (rM: number) => number, maxRM?: number): numbergroundCoverexport declare function groundCover(o: { size: number | Scale; seed: number; /** relative AREA weights per cover; keys must be `CoverKind`s and weights positive */ mix: Partial<Record<CoverKind, number>>; /** how big one patch of one cover is at the viewer, in METRES across */ patchM: number; /** the ground mesh's local vertex spacing in metres at a radius of r metres */ spacingM?: (rM: number) =>…groundPaintexport declare function groundPaint(o: { coverAt: CoverAt; size: number | Scale; seed: number; covers?: readonly GroundCover[]; }): (i: number, x: number, y: number, z: number) => [number, number, number]groundPerVertexM2export declare function groundPerVertexM2(band: SwardBand): numbergrowSwardBandexport declare function growSwardBand(band: SwardBand, size: number | Scale, seed: number): MeshlitterPlanexport declare function litterPlan(coverAt: CoverAt, size: number | Scale, o: { /** WORLD UNITS */ radius: number; seed: number; screenPx: number; covers?: readonly GroundCover[]; minPx2?: number; focalMul?: number; pitchRad?: number; clearOf?: (x: number, z: number) => boolean; centre?: { x: number; z: number; }; }): LitterPlacement[]litterReachMexport declare function litterReachM(species: GrassSpecies, o: { screenPx: number; minPx2?: number; focalMul?: number; pitchRad?: number; }): numbermownCoverexport declare function mownCover(cutM: number, o?: { common?: string; }): GroundCoverpolarGroundSpacingexport declare function polarGroundSpacing(o: { radiusM: number; nu: number; nv: number; power?: number; }): (rM: number) => numberswardBatchesexport declare function swardBatches(coverAt: CoverAt, size: number | Scale, o: { /** WORLD UNITS, exactly as `swardPlan`'s */ radius: number; seed: number; covers?: readonly GroundCover[]; clearOf?: (x: number, z: number) => boolean; centre?: { x: number; z: number; }; }): SwardBatch[]swardPlanexport declare function swardPlan(spec: SwardSpec, size: number | Scale, o: { radius: number; seed: number; clearOf?: (x: number, z: number) => boolean; /** * ⛔ WHERE THE BANDS ARE MEASURED FROM. Defaults to the world origin, which is what this * function always assumed and never said. * * ⚠ IT MATTERS BECAUSE THE BANDS ARE ABOUT APPARENT SIZE. The whole design is "fine near, * wide far" — a state…swardSelfCheckexport declare function swardSelfCheck(): { ok: boolean; note: string; }[]swardToneUnderexport declare function swardToneUnder(band: SwardBand, state: WorldState): SurfaceToneTypes
CoverAtCoverKindCoverLitterGroundCoverLitterPlacementSoilSpecSwardBandSwardBatchSwardPlacementSwardSpecMade things and ground
props21 exportsbenches, vessels, stones — the human-made things
Functions and values
BENCHESBENCHES: Record<string, BenchSpec>BOTTLEBOTTLE: VesselSpecBOULDERBOULDER: StoneSpecCOBBLECOBBLE: StoneSpecLOG_SEATLOG_SEAT: BenchSpecMUGMUG: VesselSpecPARK_BENCHPARK_BENCH: BenchSpecPICNIC_BENCHPICNIC_BENCH: BenchSpecSTEPPING_STONESTEPPING_STONE: StoneSpecSTONESSTONES: Record<string, StoneSpec>TIN_CUPTIN_CUP: VesselSpecVESSELSVESSELS: Record<string, VesselSpec>benchFacingexport declare function benchFacing(spec: BenchSpec): number | nullbenchSeatXexport declare function benchSeatX(spec: BenchSpec, index: number, count: number, size: number | Scale): numberbenchSeatYexport declare function benchSeatY(spec: BenchSpec, size: number | Scale): numbergrowBenchexport declare function growBench(spec: BenchSpec, size: number | Scale): MeshgrowStoneexport declare function growStone(spec: StoneSpec, size: number | Scale, o?: { seed?: number; }): MeshgrowVesselexport declare function growVessel(spec: VesselSpec, size: number | Scale): MeshTypes
BenchSpecStoneSpecVesselSpecpaths32 exportsmade ways: routed, graded, draped, and walked
Functions and values
DESIRE_LINEDESIRE_LINE: PathSpecMOWN_RIDEMOWN_RIDE: PathSpecPARK_FOOTPATHPARK_FOOTPATH: PathSpecPATHSPATHS: Record<string, PathSpec>PATH_SURFACESPATH_SURFACES: Record<PathSurface, PathMaterial>SHARED_PATHSHARED_PATH: PathSpeccheckPathexport declare function checkPath(spec: PathSpec, fn: string): voidclearOfPathexport declare function clearOfPath(route: PathRoute): (x: number, z: number) => booleangaitCycleMexport declare function gaitCycleM(legM: number, strideRad?: number): numbergrowPathexport declare function growPath(route: PathRoute, o?: { /** 0–1 from `tier.ts`; default 1. Thins CROSS ROWS only — see above. */ detail?: number; /** deterministic surface speckle so the ribbon does not read as flat plastic; default 1 */ seed?: number; /** override the material's own worn-margin tone. The material carries one, so a scene never * has to know what colour the ground beside the path …onPathexport declare function onPath(route: PathRoute, x: number, z: number): booleanpathDrapeReportexport declare function pathDrapeReport(route: PathRoute): PathDrapepathGradeReportexport declare function pathGradeReport(route: PathRoute): PathGradepathLateralMexport declare function pathLateralM(route: PathRoute, x: number, z: number): numberpathLengthMexport declare function pathLengthM(route: PathRoute): numberpathPointAtexport declare function pathPointAt(route: PathRoute, t: number): PathPointpathRouteexport declare function pathRoute(spec: PathSpec, boundary: BoundaryPoint[], size: number | Scale, o: { /** metres out along each boundary normal. Positive = away from what the boundary bounds. */ offsetM: number; /** the SCENE's own ground, world units in and out. Required — see above. */ groundY: (x: number, z: number) => number; /** does the boundary close into a loop? `water.shoreline` returns…pathRouteFromexport declare function pathRouteFrom(spec: PathSpec, points: { x: number; z: number; }[], size: number | Scale, o: { groundY: (x: number, z: number) => number; closed?: boolean; forbid?: (x: number, z: number) => boolean; }): PathRoutepathSurfaceOfexport declare function pathSurfaceOf(spec: PathSpec): { kind: PathGrain; gloss: number; common: string; }pathToneUnderexport declare function pathToneUnder(material: PathMaterial, state: WorldState): SurfaceTonepathsSelfCheckexport declare function pathsSelfCheck(): { ok: boolean; note: string; }[]strideForStepMexport declare function strideForStepM(legM: number, stepM: number): numberwalkPathexport declare function walkPath(route: PathRoute, o: { /** how many walkers at full detail */ count: number; /** deterministic: the same seed must give the same crowd */ seed: number; /** seconds. Walkers advance along the route at `speedMps`. */ time: number; /** metres per second; default 1.4 */ speedMps?: number; /** 0–1 from `tier.ts`; default 1 */ detail?: number; /** one gait cycle's ground…Types
BoundaryPointPathDrapePathGradePathGrainPathMaterialPathPointPathRoutePathSpecPathSurfacegolf75 exportsa nine-hole parkland course, askable by name
Functions and values
BLADE_MOW_MMBLADE_MOW_MM = 25COURSESCOURSES: Record<string, CourseSpec>COURSE_DETAILCOURSE_DETAIL = 1COURSE_TURFCOURSE_TURF: readonly TurfSpec[]CUP_DEPTH_MCUP_DEPTH_M = 0.102CUP_DIAMETER_MCUP_DIAMETER_M = 0.108FAIRWAY_TURFFAIRWAY_TURF: TurfSpecFAIRWAY_WIDTH_MFAIRWAY_WIDTH_M: readonly [number, number]FLAGSTICK_MFLAGSTICK_M = 2.13GREEN_AREA_M2GREEN_AREA_M2: readonly [number, number]GREEN_SURROUNDGREEN_SURROUND = 1.2GREEN_TURFGREEN_TURF: TurfSpecPARKLAND_NINEPARKLAND_NINE: CourseSpecPARKLAND_SANDPARKLAND_SAND: CourseTonePARK_PAR3_NINEPARK_PAR3_NINE: CourseSpecPAR_BAND_MPAR_BAND_M: Readonly<Record<number, readonly [number, number]>>PROBE_ACROSSPROBE_ACROSS = 5PROBE_STEP_MPROBE_STEP_M = 4ROUGH_TURFROUGH_TURF: TurfSpecSAMPLES_PER_STRIPESAMPLES_PER_STRIPE = 3SEMI_ROUGH_TURFSEMI_ROUGH_TURF: TurfSpecSEP_SAMPLE_MSEP_SAMPLE_M = 6STRIPE_LIGHT_STEPSTRIPE_LIGHT_STEP = 2.3TEE_TURFTEE_TURF: TurfSpecTURF_BY_KINDTURF_BY_KIND: Record<TurfKind, TurfSpec>TURF_KINDSTURF_KINDS: readonly TurfKind[]TURF_SWARD_REACH_MTURF_SWARD_REACH_M = 400TURF_TONE_LAWTURF_TONE_LAW = "sorted by mowHeightMm ascending, hue / sat / light / gloss must all fall strictly"bunkerAtexport declare function bunkerAt(plan: CoursePlan, x: number, z: number): { bunker: PlacedBunker; r: number; } | nullcheckCourseexport declare function checkCourse(spec: CourseSpec, fn: string): voidcourseLengthMexport declare function courseLengthM(spec: CourseSpec): numbercourseParexport declare function coursePar(spec: CourseSpec): numbercoursePlanexport declare function coursePlan(spec: CourseSpec, size: number | Scale, o: { /** the ground's edge, with normals pointing INLAND — `water.shoreline`'s return, verbatim */ boundary: { p: V3; normal: V3; }[]; /** the plan is deterministic on this: the same seed must give the same course */ seed: number; /** * Is this ground available for a golf hole? **Return `true` for usable ground.** Called at…cupDiameterexport declare function cupDiameter(spec: CourseSpec, size: number | Scale): numberflagstickHeightexport declare function flagstickHeight(spec: CourseSpec, size: number | Scale): numbergolfSelfCheckexport declare function golfSelfCheck(): { ok: boolean; note: string; }[]greenRadiusMexport declare function greenRadiusM(hole: HoleSpec): numbergrowBunkerexport declare function growBunker(b: PlacedBunker, spec: CourseSpec, size: number | Scale, o: { groundY: (x: number, z: number) => number; detail?: number; }): MeshgrowCourseexport declare function growCourse(spec: CourseSpec, size: number | Scale, o: { /** the layout, from `coursePlan` */ plan: CoursePlan; /** the scene's OWN ground height, in world units. Required — never defaulted. */ groundY: (x: number, z: number) => number; /** tessellation multiplier — see `COURSE_DETAIL` */ detail?: number; }): GrownCoursegrowFairwayexport declare function growFairway(pl: HolePlacement, spec: CourseSpec, size: number | Scale, o: { groundY: (x: number, z: number) => number; detail?: number; }): MeshgrowFlagexport declare function growFlag(spec: CourseSpec, size: number | Scale, o?: { detail?: number; }): MeshgrowGreenexport declare function growGreen(pl: HolePlacement, spec: CourseSpec, size: number | Scale, o: { groundY: (x: number, z: number) => number; detail?: number; }): MeshgrowTeeexport declare function growTee(pl: HolePlacement, spec: CourseSpec, size: number | Scale, o: { groundY: (x: number, z: number) => number; detail?: number; }): MeshgrowWalkexport declare function growWalk(from: XZ, to: XZ, spec: CourseSpec, size: number | Scale, o: { groundY: (x: number, z: number) => number; detail?: number; }): MeshholeApproachYawexport declare function holeApproachYaw(pl: HolePlacement): numberholeGreenexport declare function holeGreen(pl: HolePlacement): XZholeRunMexport declare function holeRunM(hole: HoleSpec): numberholeTeeexport declare function holeTee(pl: HolePlacement): XZholeTeeBackexport declare function holeTeeBack(pl: HolePlacement): XZholeYawexport declare function holeYaw(pl: HolePlacement): numberparBandMexport declare function parBandM(par: number): [number, number]roughScatterexport declare function roughScatter(plan: CoursePlan, size: number | Scale, o: { /** which band — `"semi-rough"` or `"rough"`. A mown kind THROWS, as `turfSward` does. */ kind: TurfKind; /** the sward to plant, from `turfSward(TURF_BY_KIND[kind])` */ sward: SwardSpec; /** deterministic on this */ seed: number; /** where the distance bands are measured from, in WORLD UNITS */ centre: { x: number; …roughScatterEvenexport declare function roughScatterEven(plan: CoursePlan, size: number | Scale, o: { /** which band — `"semi-rough"` or `"rough"`. A mown kind THROWS, as `turfSward` does. */ kind: TurfKind; /** the sward to plant, from `turfSward(TURF_BY_KIND[kind])` */ sward: SwardSpec; /** WHICH band supplies the density and the blade. The caller's affordance decision. */ band: number; /** deterministic on thi…stripeAcrossexport declare function stripeAcross(widthM: number, turf: TurfSpec, detail: number): numberstripeLightexport declare function stripeLight(turf: TurfSpec, lateralUnits: number, unitsPerMetre: number): numberturfAtexport declare function turfAt(plan: CoursePlan, x: number, z: number): TurfKind | "sand" | nullturfDrawsBladesexport declare function turfDrawsBlades(turf: TurfSpec): booleanturfEdgeAtexport declare function turfEdgeAt(plan: CoursePlan, x: number, z: number): { kind: TurfKind | null; outM: number; }turfForexport declare function turfFor(spec: CourseSpec, kind: TurfKind): TurfSpecturfSwardexport declare function turfSward(turf: TurfSpec, o?: { reachM?: number; }): SwardSpecturfToneUnderexport declare function turfToneUnder(spec: CourseSpec, kind: TurfKind, state: WorldState): SurfaceToneTypes
BunkerSpecCourseDropCoursePlanCourseSpecCourseToneGrownCourseHolePlacementHoleSpecMownPatchPlacedBunkerRoughPlacementTurfKindTurfSpecXZGoverning the frame
tier13 exportswhat THIS machine can draw — classify, then govern
Functions and values
FORM_FLOORFORM_FLOOR: numberFORM_MIN_SIDESFORM_MIN_SIDES = 8FORM_NOMINAL_SIDESFORM_NOMINAL_SIDES = 12FORM_RUNGSFORM_RUNGS: readonly number[]FORM_SIDE_LADDERFORM_SIDE_LADDER: readonly number[]FrameGovernorexport declare class FrameGovernor { /** the frame time to aim under, ms. 20 ms ≈ 50 fps, leaving headroom under a 60 Hz vsync. */ readonly targetMs: number; /** how many frames to gather before judging */ readonly window: number; /** the deepest cut allowed */ readonly maxLevel: number; /** * The least improvement a cut must buy to be worth keeping, as a fraction of the frame time * that triggere…classifyRendererexport declare function classifyRenderer(renderer: string): GpuTierformFloorForexport declare function formFloorFor(nominalSides: number, minSides?: number): numbernestedCountexport declare function nestedCount(baseSegments: number, dial: number, Lmax?: number): numbersidesAtexport declare function sidesAt(nominalSides: number, form: number): numbersilhouetteErrorexport declare function silhouetteError(sides: number): numbertrimmedMeanexport declare function trimmedMean(samples: readonly number[]): numberTypes
GpuTierscale5 exportsone place that knows how big a metre is
Functions and values
PLANT_MPLANT_M: { /** a meadow grass tussock — knee-high at most, and most of a lawn is half this */ readonly grassTussock: 0.42; /** the fine mat between the tussocks */ readonly grassFine: 0.18; /** a tall bent-grass, the stuff that breaks a meadow's flat line */ readonly grassTall: 0.75; /** a grass seed head on its stem */ readonly seedHead: 0.65; /** the small one — quaking grass */ readonly seedHea…stemDiameterMexport declare function stemDiameterM(heightM: number): numberunitsForexport declare function unitsFor(size: number | Scale, realMetres: number): numberunitsPerMetreOfexport declare function unitsPerMetreOf(s: Scale): numberTypes
Scaleobjectives8 exportsno description in the package
Functions and values
ObjectivesCoreexport declare class ObjectivesCore { private apply; private objs; private listeners; private floor; private settleAfter; constructor(apply: ChannelAppliers, opts?: ObjectivesOpts); /** Define (or wholly replace) a named objective. The drive starts on the next tick. */ define(name: string, spec: ObjectiveSpec, camNow?: ObjectiveCamera): void; /** Move a live objective's goal — progress restarts FR…attachObjectivesexport declare function attachObjectives(world: World, opts?: ObjectivesOpts): ObjectivesTypes
ChannelAppliersMovementReadingObjectiveCameraObjectiveSpecObjectivesObjectivesOptsThe charts API rides on top
A chart recipe written against the charts package ports forward by changing one import. That is the reason to start small: nothing is thrown away if a chart later needs a world.
What it costs to run
Both packages carry their own frame-cost gate and publish measured figures with the conditions attached. Those numbers belong with their conditions, so they are not repeated here.
Licence · MIT