makepad/libs/game/gen/examples
Admin f5174a7d61 gen: kit composition — the AI builds levels from Kenney's modular tiles
Procedural LAYOUT + authored TILES: the AI decides where things go, Kenney's
artwork decides how it looks. Beats both random prop scatter and purely
procedural geometry, and it is how low-poly games are actually made.

ADJACENCY HOLDS BY CONSTRUCTION, not by rules. Rather than pairwise rules
between named roles (fragile and quadratic), layout marks occupied cells, each
cell reads its target mask off its occupied NEIGHBOURS, and a tile is chosen
matching that mask at some rotation. Both sides of every shared edge derive
from the same grid, so only rotation arithmetic can be wrong — and that is
what the tests pin. Junction type is never specified by a caller: two crossing
paths yield a crossroad, one teeing in yields a T, purely from neighbour count.

The interface deliberately keys on a 4-bit N/E/S/W `mask`, not on `role`, so
these algorithms don't depend on the asset index's filename taxonomy — if a
kit classifies `road-split` oddly, setting the mask keeps everything working.
Incomplete kits fall back to a superset tile: a crossroad standing in for a
missing tee leaves a stub opening onto nothing, which reads as unfinished road
rather than a hole in the world.

Generators: road_network (polylines), road_from_spline (the authored-tile
counterpart to the existing ribbon mesh — a kart track wants the ribbon, a city
street wants tiles), town (street grid, buildings on lots that front and face
a street, props at junctions), dungeon (BSP rooms + corridors, connectivity
guaranteed by the spanning tree and PROVED by flood fill over 12 seeds), plus
place_tile as the escape hatch.

  track from closed spline    13 us    120 tiles
  road network (13 paths)     32 us    397
  town 24x24                  71 us    547
  town 60x60                 822 us   2710
  dungeon 48x48              137 us   1180
  dungeon 96x96              932 us   3616

Town road histogram: 1248 straight, 121 cross, 44 tee, 4 corner, 0 dead ends —
correct for a closed grid. Zero mismatched edges on both large levels.

Two bugs caught by its own tests: indexing one kit with another kit's
placement indices (now impossible — layers merge by kit id, invariant
documented), and a superset-fallback that allocated a Vec per cell and tripled
generation time. The allocation-free count-then-pick rewrite is faster than
before the fallback existed: dungeon 96x96 went 1952 us -> 932 us.

Seed-deterministic via GenRng, never the world rng, so a town replicates as
(kit, seed, params). Not done: walls/doors around dungeon rooms (floor-only
today), multi-cell buildings.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-03 10:15:42 +02:00
..
costs.rs Arcade: procedural generation pipeline (libs/game/gen) 2026-08-03 09:22:03 +02:00
levels.rs gen: kit composition — the AI builds levels from Kenney's modular tiles 2026-08-03 10:15:42 +02:00
silhouette.rs Arcade: procedural generation pipeline (libs/game/gen) 2026-08-03 09:22:03 +02:00