feat: actors stage 2

This commit is contained in:
Dan Finch 2026-08-07 19:11:43 +02:00
parent 4869db01e5
commit 581e5892b0
19 changed files with 752 additions and 594 deletions

View file

@ -63,7 +63,9 @@ rules live in `.agents/rules/*.md`.
Bayer dither), `RenderConfig` (the look dials + presets), `Rasterizer`
(optional backface cull per draw), `Frustum` (6 planes from the viewProj +
AABB test, for chunk culling), `Texture` (nearest/bilinear, wrapping, no
mipmaps), `Sky` (gradient + sun + procedural clouds; renders at 1/`step` res).
mipmaps), `Material` (texture + cull flag; a `DrawGroup` pairs a mesh with one,
so the renderer draws by list, not by named texture), `Sky` (gradient + sun +
procedural clouds; renders at 1/`step` res).
- `scene/``Camera` (fps yaw/pitch; far plane reaches the outdoor peaks),
`Mesh` (indexed tris; verts stored flat: `STRIDE` floats x,y,z,u,v per vertex,
no per-vertex objects — cache-friendly + alloc-free to draw), `Sprite`
@ -71,9 +73,11 @@ rules live in `.agents/rules/*.md`.
heightfield around the room: flat clearing in the center, rolling hills, tall
edge peaks. `Terrain.patch` builds one ground patch over a rectangle -- called
per chunk, aligned so patches weld crack-free, with a hole for the room;
`Terrain.height` is the shared ground-height sampler for the player), `Tree`
(procedural low-poly oak/spruce/birch geometry, sapling..full via a `growth` knob;
`Tree.build` appends into shared trunk + foliage meshes), `Boulder`
`Terrain.height` is the shared ground-height sampler for the player), `Actor`
(the `Entity` interface — geometry + behavior + bounds — that each mob kind
implements), `Tree` (procedural low-poly oak/spruce/birch, sapling..full via a
`growth` knob; each species a `TreeSpecies` in `trees/<Kind>.ts`, assembled by a
registry — see the Trees section), `Boulder`
(procedural low-poly rock: a squashed, jittered, part-buried sphere;
`Boulder.build` appends into a shared mesh), `Bush` (cluster of small leaf
blobs, shares the oak leaf texture/mesh), `Flower` (thin stem + colored bloom;
@ -273,10 +277,13 @@ Both are exported presets in `app/level.ts`; the active one is set in
branching in the cloud shader. Cost scales with sky resolution — fine at
`standard`, heavy at `clean` (mitigate: fewer fbm octaves or half-res sky).
## Trees (`engine/scene/Tree.ts`)
## Trees (`engine/scene/Tree.ts` + `engine/scene/trees/`)
Procedural low-poly geometry, faceted flat-shaded like everything else. Three
`kind`s carry the species read purely by silhouette:
Procedural low-poly geometry, faceted flat-shaded like everything else. Each species
is a `TreeSpecies` definition in its own `trees/<Kind>.ts` module (geometry +
which chunk materials its trunk/foliage bake into); `Tree.ts` just assembles them
into a registry (`Tree.species(kind)`, `TREE_KINDS`) and shared primitives live in
`trees/treekit.ts`. Three `kind`s carry the species read purely by silhouette:
- **`oak`** — short tapered trunk, a couple of branches, a broad cluster of
lumpy canopy `blob`s (wider than tall, bushy).
- **`spruce`** — tall thin trunk under stacked narrowing `cone` tiers pointing
@ -288,11 +295,14 @@ Procedural low-poly geometry, faceted flat-shaded like everything else. Three
`growth` (0..1) runs **sapling → full grown**: it scales height/girth and adds
canopy blobs (oak/birch) / tiers (spruce); `seed` gives each tree its own wobble.
`Tree.build` appends into caller-chosen trunk + foliage meshes, so a forest still
batches into a few draw calls (brown-bark trunks, white-birch trunks, oak/birch
leaf foliage, spruce needles). `app/level.ts` `placeTrees` seeds the forest and
rolls the species; add one by extending the union + a builder (a new bark/leaf
look also needs its own texture + per-chunk mesh channel — see `birchBark`).
A species declares its `trunk`/`foliage` **material keys** (e.g. birch → white
`birch` trunk, oak `leaf` foliage); the chunk baker (`level.ts`) accumulates one
mesh per material key and routes each tree via `Tree.species(kind)` — so a forest
still batches into a few draw calls and the baker names no texture. `app/level.ts`
`placeTrees` seeds the forest and rolls the species. **Add a species** = add a
`trees/<Kind>.ts` module (its geometry + material keys) + one entry in the `Tree`
registry; only a genuinely new material also needs a `Material` in `buildLevel` +
its key in `MAT_ORDER`.
**Boulders** (`engine/scene/Boulder.ts`) work the same way: `Boulder.build`
appends a squashed, per-vertex-jittered low-poly sphere (seam/pole-safe so it