# game.clowns.Clown
What a clown DOES, once `game.clowns.Roster` has built it. Mounted by the
Roster on the clown's own root; it finds the figure's joints by name,
remembers the pose they were built in, and writes a new pose over that base
every frame — a permanent breathing sway, plus whichever reaction was last
asked for.
## Fields
- `kind` — which clown this is.
- `entryDepth` — metres the figure walks in from during `enter`.
- `action` — the reaction currently playing.
## Methods
- `:react(name)` — `enter`, `idle`, `attack`, `hit`, `guard`, `laugh`, `die`.
Every reaction is a pose over the base plus an envelope in time, so one
interrupted half-way still lands somewhere sensible. `guard` and `die` hold.
- `:bind(hipY)` — re-read the joints and the rest pose, and tell the driver
how tall this figure stands. The Roster calls it once the parts are built.
## Notes
- Reach it through the Roster's handle rather than directly; the handle is
what the Director holds.
- The reactions live in one `REACTIONS` table — a duration and the function
that poses the figure, per name. A new reaction is a row in it.
- The sway runs on every frame of every figure, and it is meant to be seen at
the seat: the hips shift weight, the chest breathes, and the head, the hat
and the ruff each follow on their own frequency a beat behind.
# game.clowns.figures
What the four of them look like. One description per clown, and one builder
that turns a description into geometry and a node list.
- **Pinch the Auguste** — short and wide, a pot belly, red side-hair standing
out from a bald crown, a bulb nose, shoes far too big.
- **Bello the Whiteface** — a narrow column under a cone, a pleated ruff,
three black pompoms, a chalk face with brows drawn far too high.
- **Slats the Stilt-Walker** — a small striped man a long way up two poles,
under a squashed bowler, with black paint run down from both eyes.
- **Mr. Marrow the Ringmaster** — a broad red tailcoat with gold frogging, a
top hat, tails, a whip, and the only full-saturation red in the tent.
## Exports
- `Figures.kinds() -> { string }` — the ids, in the order the run meets them.
- `Figures.design(kind) -> record?` — one clown's description.
- `Figures.headProfile(radius, height, gaunt?) -> profile`
- `Figures.build(kind) -> { meshes, nodes, paint, dims, design, tint }` —
`meshes` are geometries ready for `renderer.mesh.create`; `nodes` is the
entity list, ordered parents-first, each `{ name, parent, pos, rot, mesh,
material }` with `parent = nil` meaning the clown's own root.
## Notes
- Nothing here touches the scene. `game.clowns.Roster` spawns what this
returns.
- `material` on a node is a ROLE — `face`, `cloth`, `trim`, `glove`, `dark`,
`nose` — which the Roster resolves to this kind's material.
# game.clowns.geom
The procedural geometry kit the four clowns of GREASEPAINT are cut from. A
lathe, a box, a tapered tube, a cone, a frilled ruff, a shoe, and the ability
to stamp any of them into a growing buffer under a transform. Everything a
performer is made of is one of those.
A geometry value is exactly the table `renderer.mesh.create` takes:
`{ positions, normals, uvs, indices }`.
## Exports
- `Geom.new() -> geometry` — an empty accumulator.
- `Geom.stamp(dst, src, xf) -> dst` — copy `src` into `dst` under
`{ pos, rot = {yaw, pitch, roll}, scale }`. Angles are radians.
- `Geom.stampFlat(dst, src, xf, u, v)` — as `stamp`, then collapse the added
vertices onto one texture coordinate, so a part that wears a painted
material can point at a plain patch of it.
- `Geom.lathe(profile, segments, opts) -> geometry` — revolve `{ r, y }`
points running bottom to top. `opts.uOffset` turns the unwrap around the
axis without turning the geometry; `opts.vFromY` maps v to height rather
than arc length.
- `Geom.spheroid(rx, ry, rings, segments, opts)`
- `Geom.tube(r0, r1, height, segments, opts)` — capped, optionally bulged.
- `Geom.limbDown(r0, r1, len, segments, opts)` — the same tube built pointing
DOWN from a joint at the origin, which is the rest pose an arm and a leg
hang in.
- `Geom.cone(radius, height, segments, opts)`
- `Geom.ruff(rInner, rOuter, thickness, lobes, segments)` — a pleated collar,
skinned on both sides.
- `Geom.box(sx, sy, sz)` — centred on x/z, sitting on y = 0.
- `Geom.shoe(length, width, height)` — far too long, turned up at the toe.
- `Geom.upload(geometry, guid?) -> MeshHandle`
## Notes
- A ring puts `x = r*sin(theta)`, `z = r*cos(theta)`, so u = 0 faces +Z. The
clowns face +Z (the audience), so a head takes `uOffset = 0.5` to bring the
painted face round to the front.
- Triangles wind counter-clockwise seen from outside. The engine reports a
mesh whose winding disagrees with its own normals, which is the check to
read after changing any index order here.
- Adapted from `figures.geom` in the ZeroMind world "Standing Ovation".
# game.clowns.paint
The greasepaint, generated. No clown's face in this game is a painted image:
each one is drawn here from a description, into a base-colour / normal /
roughness set that its material binds.
## Exports
- `Paint.head(spec) -> base, normal, roughnessMetallic, buffer` — a face.
The head texture is a cylindrical unwrap with the FACE at u = 0.5 and v
running up the head's own lathe profile by arc length, so every feature in
the spec is written in centimetres of real face: `mouthY`, `mouthHalf`,
`eyeSep`, `browY`, `cheekX` and the rest. `mouthLift` lifts both corners of
the smile and `mouthSkew` tilts the whole line, so one corner rides higher
than the other. `spec.profile` is the head
profile the figure was lathed from and `spec.radius` its widest radius.
Optional `muzzle` and `eyePatch` lay white ground under the red, which is
what separates an Auguste from a whiteface; optional `tear` paints a stripe
straight down from the socket.
- `Paint.cloth(spec) -> base, normal, roughnessMetallic, buffer` — a bolt of
cloth. `spec.pattern` is `"diamond" | "stripe" | "plain"`; the weave, the
wear and the grime are always there. Woven neutral so a material's own
`base_color` dyes it.
- `Paint.mapping(profile) -> toV, toY` — the height/v conversions a caller
needs to place something on a head by where it sits in metres.
- `Paint.at(buffer, w, h, u, v) -> r, g, b` — what the generator put at one
point, straight out of the buffer, so a face that looks wrong on screen can
be told from a face that was drawn wrong.
## Notes
- A face costs a second or two of pure Luau. Pass `spec.chunkRows` to spend
it a band at a time and hand the frame back between bands;
`game.clowns.Roster` does that so a spawn never freezes the game.