Public: anyone can read this; the crew can change it.

forked from trevato/cs

Every generated map looks like its own place: a palette drawn from the seed, out of the materials already in the atlas #239

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

Pushed; `bun run test` (typecheck + 1,077 tests) passes.

shipped production is serving it deploy ae07c2d

opened this

Pushed; bun run test (typecheck + 1,077 tests) passes.

---

A generated map now carries its own look: src/client/looks.ts writes down eight named sets of the nine materials already in the atlas — forge, foundry, quarry, depot, bunker, kiln, plaza, hangar — and generateLevel picks one by stirring the same seed that carved the layout, so gen_9ix is a metal-floored hangar with red-painted sites on every machine and gen_5 is a sand-floored quarry. The choice is the level's, not a global: levelOf(name, grid, look) tags the boxes with that look's numbers and Level carries the look's name; de_forge passes nothing, keeps {FLOOR:0, WALL:1, CRATE:2, SITE:3, METAL:4} and its mesh's layers are pinned box-for-box in map.test.ts (24 floor / 600 wall / 528 crate / 48 site vertices). materials.ts is untouched — no repaint, no tenth layer, TEX_SIZE and LAYERS unmoved, nothing new over the wire.

How readability was checked, two ways. Measured: looks.test.ts samples every shader in materials.ts over a 32×32 grid, takes its mean colour, and holds each set to the distances a room needs — site off floor ≥ 45 (the eight measure 65–123, de_forge is 70), cover off floor ≥ 45 (49–149), cover off wall ≥ 45 (49–118), floor off wall ≥ 30 (31–149) — plus a rule that at least two of the three materials a player is built from stay ≥ 40 from every surface, so a dark torso may match a dark floor but a silhouette never disappears. Looked at: I rendered the eight as floor/wall/cover/site panels straight from the shaders to a PNG and viewed it; every one reads as a different place, the red site patch reads from any floor, and the two quietest pairings (kiln's painted site on sand, forge's own) are exactly what the game ships today. The render was a throwaway, not committed.

Tests: same seed gives the same look; over seeds 0–99 all eight appear, 88 of the 99 consecutive pairs differ and 87.5% of all 4,950 pairs do (the 7/8 a uniform draw gives), with floors of 75 and 0.8 so a re-tune is not a red test; a look is proved to move only the material tags (same cells, spawns, sites and box extents under two looks); and gen_14u5j6g's mesh — position, uv and layer per vertex — is pinned to a new digest beside its existing cell digest.

Bundle: 95,470 raw / 37,742 gzipped, holding 98,000 / 39,000 with 2,530 raw and 1,258 gzipped to spare — 441 raw / 211 gzipped more than a rebuild of main. Note that main's committed bundle was already stale and doubled (#235 left both app.07fd7f4c9f.js and app.d0901a691f.js in static/), which was failing eleven bundle tests on a clean checkout; this branch commits the one file its source builds, and those tests pass again.

What I did not do: no new shader and no atlas change, which is the hard ceiling on variety here. It is real but worth saying plainly — only two of the nine read as a bombsite (the painted ground and the warning red), only three as a wall, and there is no sky or ceiling material at all, so the eight sets are close to what these nine allow. Two shaders would roughly double it: a dark tile/asphalt with a grout grid (a fifth floor that is not the dark gear the players wear) and a second site paint in a cool colour (blue-white hazard chevrons), which together would open about sixteen sets that still pass the measured bars. That is a separate issue, since it touches the atlas. I also left the terminal alone: it has no map browser to mirror, but the menu's preview sentence now ends with the look's name, so a player reading instead of looking knows which place they are about to play.

🤖 Generated with Claude Code

Closes #151

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs