Nine agent skills for building Makepad/Rust games, ported from majidmanzarpour/threejs-game-skills. Same director-routed workflow and premium bar; runtime rewritten for this fork's game crates. - makepad-game-director entrypoint, routing, continuity, asset probe - makepad-gameplay-systems loop, movers vs rigid bodies, input, camera, netplay - makepad-aaa-graphics-builder lighting, shaders, budget, visual scorecard - makepad-game-ui-designer HUD, menus, touch and XR UI - makepad-debug-profiler defect bisection and profiling - makepad-qa-release verification ladder, evidence, packaging - makepad-3d-generator CC0 model search, casts, procedural geometry - makepad-image-generator texgen textures, palettes, sky, icons - makepad-audio-generator sample bank, mixer, material impacts, 3D audio Written against the real APIs in libs/game/*, libs/sim and apps/arcade: the game.* verb table, GameRenderer adaptive quality, the packed 6-float GameMeshVertex layout, script_mod! splash styling, makepad-test driving, and the BUDGETS.md numbers. No paid generation API is required - the CC0 library plus seeded makepad-game-gen replaces them. Includes install.sh (Codex/Claude), validate-skills.sh and a repo-aware probe_assets.sh; both scripts verified against this checkout.
5.1 KiB
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.
#[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 PlacedTiles. libs/rtsmap is the shared tiled-RTS generator.
Always validate:
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