# Procedural recipes `makepad-game-gen`: `mesh`, `terrain`, `tree`, `lsystem`, `spline`, `scatter`, `interior`, `kit`, `levelgen`, `implicit`, `texgen`, `cache`, `rng`. ## Determinism first Every generator takes a seed and must produce byte-identical output on every device. Use `makepad-game-gen::rng` and `makepad-game-math` transcendentals — never `std` float math, never thread RNG. This is what allows content to replicate as `(preset, seed, position)` instead of vertex data, and it is not optional in a networked game. ```rust #[test] fn deterministic() { assert_eq!(generate_forest(99), generate_forest(99)); } ``` ## Terrain `terrain` + `landform::LandKind`. Layer octaves of noise: a large-amplitude low-frequency pass for landform, a medium pass for hills, a small pass for surface break-up. Erode by lowering steep slopes toward their downhill neighbour over a few passes — this is what makes terrain read as landscape rather than as noise. Resolution is a *visual* budget, not a sim one: 65×65 with 100 movers and 50 bodies is 0.038 ms/tick. Terrain vertices upload once per revision, so the cost is memory and vertex count, not per-frame bandwidth. Flatten where gameplay needs flat: spawn areas, roads, building footprints. Do this **after** generation, as an explicit stamp, or you will fight the noise forever. ## Roads and rivers — `spline` Define a centreline, sample it, extrude a cross-section along it. Stamp the terrain flat under the road before placing it, or the road will float and clip in alternating segments. Bank on curves for driving. Place checkpoints (`Checkpoint`) at spline parameters so the track and the race logic cannot disagree. ## Foliage — `tree`, `lsystem`, `scatter` `lsystem` grows branching structures from a grammar; `tree` wraps the common cases. `scatter` distributes instances. Scattering rules that separate a forest from a field of stamps: - Poisson-ish spacing, not uniform random — uniform random clumps and leaves bald patches - Seeded jitter: ±10% scale, full yaw - Exclude by slope, by height band, and by a mask around gameplay areas - Two or three species mixed, with one dominant - Density falling off with distance from the player's likely path Replicate the field as `(preset, seed, region)`, never as placements. ## Interiors — `interior` Rooms, doors, connectivity. Validate before shipping: every room reachable, doors wide enough for the player capsule, no geometry inside the spawn. This is exactly the case the codebase learned the hard way — `makepad-game-blocks` dev-depends on `gen` because "a walker can enter a REAL generated room" is a claim about generated geometry meeting real physics, and testing the halves separately passes while the walker floats. ## Levels — `levelgen`, `kit`, `rtsmap` Tile-based assembly from a kit, so scale and style are consistent by construction. `kit_from_index` and `level_placements` (in `makepad-game-script::compose`) turn a kit into `PlacedTile`s. `libs/rtsmap` is the shared tiled-RTS generator. **Always validate:** ```rust assert!(path_exists(&level, level.spawn, level.goal), "unwinnable level, seed {seed}"); assert!(level.spawn_is_clear(), "spawn blocked, seed {seed}"); ``` Run the validator over a few hundred seeds in a test. A generator that fails 1 in 50 seeds will ship, and the failures will be found by players. ## Implicit surfaces `implicit` — SDF-style blobs, caves and smooth solids, polygonised to a mesh. Good for organic rock, cave systems and merged forms. Expensive to evaluate at high resolution: generate once, cache, do not regenerate per frame. ## Textures — `texgen` Tiling procedural detail, packed for `DrawGameTexture`. The cheapest fix for "everything is flat colour", and it adds no download weight. Match tiling scale to world units so texel density is consistent across surfaces — inconsistent texel density is one of those defects everyone notices and few can name. ## Meshes `mesh` builds geometry directly. Emit the packed layout `geom.GameMeshVertex` — position 3 exact f32, octahedral normal in one lane, uv 2×f16 in one lane, colour 4×unorm8 in one lane, 6 floats / 24 B total. Attributes here are f32-only; packing means bit-packing plus `unpack2f16` / `unpack4u8` in-shader. Wind vertices consistently, generate correct normals (smooth within a surface, split at hard edges), and keep UVs inside 0..1 per island. ## Colliders Never collide against the render mesh. Generate a simplified collider alongside: boxes and capsules for most things, a heightfield for terrain, a convex hull at worst. `model_collider_parts(id)` shows the shape the library uses. ## Caching `cache`, keyed by `(preset, seed)`. Regenerating on demand during play is a stutter source; an unbounded cache is a leak. Bound it, and generate during loading where you can predict the need. ## Validation checklist - [ ] Deterministic — same seed twice, byte-identical - [ ] Scaled to the player capsule - [ ] Packed vertex layout - [ ] Normals correct, winding consistent - [ ] Simplified collider present - [ ] Spawn clear, goal reachable, validated across many seeds - [ ] Cached with a bound - [ ] Visually varied — jittered scale and yaw, palette tints