feat: birch

This commit is contained in:
Dan Finch 2026-08-07 13:01:32 +02:00
parent 16f205babe
commit a4490f7a20
11 changed files with 110 additions and 24 deletions

View file

@ -72,7 +72,7 @@ rules live in `.agents/rules/*.md`.
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 geometry, sapling..full via a `growth` knob;
(procedural low-poly oak/spruce/birch geometry, sapling..full via a `growth` knob;
`Tree.build` appends into shared trunk + foliage meshes), `Boulder`
(procedural low-poly rock: a squashed, jittered, part-buried sphere;
`Boulder.build` appends into a shared mesh), `Bush` (cluster of small leaf
@ -116,7 +116,7 @@ rules live in `.agents/rules/*.md`.
scattered (`placeMobs`; `FROG_/BEE_COUNT`, `MOB_SEED`, `MOB_REACH` — mobs move,
so they carry no baked colliders), then `buildChunks` bakes
terrain + props into a `CHUNK_GRID` x `CHUNK_GRID` grid of `Chunk`s (each =
per-texture meshes grass/bark/leaf/needle/rock/flowers + a tight AABB) that
per-texture meshes grass/bark/birchBark/leaf/needle/rock/flowers + a tight AABB) that
`main` frustum-culls; bushes fold into the leaf mesh, flowers get their own
(drawn double-sided). Trees + boulders are baked **twice** — full geometry and
a low-poly impostor (`barkFar/leafFar/needleFar/rockFar`, via the builders'
@ -134,9 +134,9 @@ rules live in `.agents/rules/*.md`.
`#fps` meter div (styled inline).
- `scripts/gen-assets.ts` — procedurally draws the placeholder textures and
writes PNGs (hand-rolled encoder via `node:zlib`). Run via `bun run assets`.
- `assets/` — generated `floor/grass/bark/leaf/needle/rock/flower/wall/crate/npc/frog/bee`
PNGs (`floor` = room stone, `grass` = outdoor ground, `bark`/`leaf`/`needle` =
tree trunk/oak/spruce, `rock` = boulders, `flower` = 2x2 bloom-color atlas,
- `assets/` — generated `floor/grass/bark/birch/leaf/needle/rock/flower/wall/crate/npc/frog/bee`
PNGs (`floor` = room stone, `grass` = outdoor ground, `bark`/`birch`/`leaf`/`needle` =
brown trunk / white birch trunk / oak leaf / spruce needle, `rock` = boulders, `flower` = 2x2 bloom-color atlas,
`frog`/`bee` = mob skin atlases: frog green + eye tone; bee stripe bands +
head-dark + wing-pale regions).
Swap for real art anytime;
@ -271,18 +271,24 @@ branching in the cloud shader. Cost scales with sky resolution — fine at
## Trees (`engine/scene/Tree.ts`)
Procedural low-poly geometry, faceted flat-shaded like everything else. Two
Procedural low-poly geometry, faceted flat-shaded like everything else. 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
to a tip (taller than wide, conical).
- **`birch`** — silver birch: tall, slender, near-straight trunk with an airy,
high, slightly drooping canopy (lean silhouette). Uses a separate **white**
`birch` bark texture (brown bark can't stand in), and shares the oak `leaf`
foliage.
`growth` (0..1) runs **sapling → full grown**: it scales height/girth and adds
canopy blobs (oak) / tiers (spruce); `seed` gives each tree its own wobble.
`Tree.build` appends into caller meshes so a forest batches into 3 draw calls
(one bark trunk mesh, oak-leaf and spruce-needle foliage meshes). `app/level.ts`
`scatterTrees` seeds the forest; add a species by extending the union + a builder.
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`).
**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