makepad/skills/makepad-3d-generator/SKILL.md
Arena Agent fe21c07d84 skills: add Makepad game skills pack ported from threejs-game-skills
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.
2026-09-05 21:18:58 +00:00

103 lines
6 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
name: makepad-3d-generator
description: "Source and create 3D content for Makepad games: search the CC0 model library by description, pick rigged character casts, and generate geometry procedurally with makepad-game-gen (terrain, trees, splines, interiors, level kits, implicit surfaces, meshes). Use for characters, vehicles, weapons, buildings, props, rigs, animation, terrain and level geometry requests."
---
# Makepad 3D Generator
Two sources, and choosing between them is most of the job.
| Source | Best for | Cost |
| --- | --- | --- |
| **CC0 library** (`makepad-game-assets`) | hero props, vehicles, characters, anything whose silhouette must read as a specific recognisable object | a one-time download |
| **Procedural** (`makepad-game-gen`) | terrain, roads, foliage, interiors, level layout, tiling detail, anything needed in bulk or varied by seed | free, deterministic, replicates as a seed |
No paid generation API is involved, and none is required. When neither source fits, extend the procedural generator — do not hand-author vertex dumps into the repo.
## The library
Fetch once (binaries are not in git):
```bash
./apps/arcade/download_assets.sh # core, ~1900 models, ~75 MB
./apps/arcade/download_assets.sh --packs=all # 4669 models / 47 packs, ~185 MB
./apps/arcade/download_assets.sh --list
bash skills/makepad-game-director/scripts/probe_assets.sh
```
Everything is pinned and sha256-verified; a moved or tampered upstream fails loudly. Downloads are sequential with a delay — do not parallelise someone else's bandwidth.
**Search by description, never filename.** `makepad-game-assets` provides `AssetIndex`, `find_model`, `find_cast`, `Filters`, `Hit`, `AssetKind`, `KitInfo`, `CastInfo`, `CATEGORIES`. Ids look like `kenney/racing/vehicle-truck-yellow` and are stable across re-downloads, because generated game code writes them.
The index is ~120 ms to build, ~0.2 ms per search, ~2.1 MB heap at 4,999 entries. Query-side stemming handles inflections; on a score tie the kind the query implies wins.
## Rigged characters
`find_cast` lists animated casts. **A cast is a set of characters sharing one skeleton** — any clip works on any member, so a part can be recast without touching animation code.
| rig | members | clips |
| --- | --- | --- |
| 41 joints (KayKit) | 9 | 7695 — block, dodge, hurt, dance, sleep, carry |
| 7 joints (Kenney mini) | 22 | 2532 — walk, run, jump, attack, sit, wave |
| 6 joints (Kenney platformer) | 5 | 25 |
Two rules: **one cast per scene**, and **different members within it** so a crowd is not clones. Mixing casts means an animation authored for one will not play on the other — a common and confusing failure.
Rendering: `SkinnedModel`, `PoseBuffer`, `SkinnedBatch`, `SkinnedDraw` in `makepad-game-render::skin`. Skinning is CPU-side and re-uploads every frame, so skinned character count is the most expensive visual budget you control.
## Procedural generation
`makepad-game-gen` modules: `mesh`, `terrain`, `tree`, `lsystem`, `spline`, `scatter`, `interior`, `kit`, `levelgen`, `implicit`, `texgen`, `cache`, `rng`. Plus `libs/rtsmap` for tiled RTS maps and `makepad-game-script::compose` (`kit_from_index`, `level_placements`, `PlacedTile`).
**Everything is seeded.** `makepad-game-math` supplies deterministic transcendentals so two devices generate byte-identical meshes from the same seed — which is what lets a forest replicate as `(preset, seed, position)` instead of vertex data. Never use `std` float math or unseeded RNG in a generator.
Pick by shape:
- **Heightfield ground** → `terrain` + `LandKind`
- **Organic branching** → `tree`, `lsystem`
- **Roads, rivers, rails** → `spline`
- **Fields of things** → `scatter` (with seeded scale/yaw jitter)
- **Rooms and buildings** → `interior`
- **Tile-based levels** → `levelgen`, `kit`, `rtsmap`
- **Blobs, caves, smooth solids** → `implicit`
- **Anything else** → `mesh` directly
## Rules that keep output usable
**Scale to the player capsule.** Decide player height in world units first (gameplay), then obey it. A door at 1.6 m in a world with a 1.8 m player is the sort of error that is invisible in a screenshot and obvious in play. Check with `model_bounds(id)`.
**Use the packed vertex layout.** `geom.GameMeshVertex` — 6 floats / 24 B (exact position, octahedral normal, f16 uv, unorm8 colour). Do not emit a fatter vertex for convenience; skinned and shadow meshes especially.
**Validate what you generate.** Is the spawn clear? Is the goal reachable? Is there a navigable path? An unvalidated level generator produces unwinnable levels about as often as good ones, and only playtesting finds them.
**Provide colliders.** `model_collider_parts(id)` gives library colliders. For generated geometry, produce a simplified collider — never collide against the render mesh.
**Cache.** `makepad-game-gen::cache`, keyed by `(preset, seed)`. Regenerating a forest every frame is a stutter source; an uncapped cache is a leak. Bound it.
## Variety without new assets
The library is shared, so default scenes look like everyone else's project. Four seeded levers, all free:
1. **Tint**`ModelInstance::with_tint`, from `Palette` / `Spread` / `VarietyParams`
2. **Scale jitter** — ±10%
3. **Yaw jitter** — full range
4. **Member variety** — different cast members, different props from the same kit
Seeded, so all four still replicate across the wire.
## Verification
```rust
assert!(renderer.model_is_loaded(id), "missing {id}"); // silent primitive fallback otherwise
renderer.model_bounds(id); // scale sanity
renderer.model_triangles(id); // budget
assert_eq!(generate(1234), generate(1234), "generator must be deterministic");
```
Judge geometry by eye where a number cannot: the `ao_render` dev example in `makepad-game-render` software-rasterises props so baked AO and form read correctly without a `Cx` or the app.
## Required reading
- `references/asset-search.md` — querying, casts, kits, ids, filters.
- `references/procedural-recipes.md` — generator recipes and validation.