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.
3.8 KiB
Core loop, levels, difficulty
The brief
Before code. Keep it in artifacts/game-progress.md and re-read it after any interruption.
Loop: Player drives a route, hits checkpoints, beats a lap time.
Escalate: Each lap adds traffic; the target time tightens.
Win: 3 laps under par. log "race: won"
Lose: Timer expires. log "race: lost"
Input: kb WASD+Space | pad LS+RT/LB | touch left stick + pedals
Camera: chase, 6 m back, 2.4 m up, 60 deg fov, player car 4.2 m long
Device: desktop + Quest, 72 Hz target
Art: dusk desert, warm key, long shadows, Kenney racing kit
Emit those exact log lines from the game. They make win/lose machine-checkable in a makepad-test run, which is the difference between a claim and evidence.
Loop archetypes
| Archetype | Escalation | Ends when | Blocks to use |
|---|---|---|---|
| Race | opponents, tighter par | laps complete / time out | Car, RaceKit, Checkpoint |
| Arena survival | wave size and mix | player dies / wave N cleared | Character, Brain, Npc |
| Chase / evade | pursuer speed, spawn rate | caught / escaped | Brain::chase, caught |
| Collect | scatter distance, hazards | quota met / timer | interactable, score |
| Traversal | gap width, hazard density | goal reached / fall | mover + deck_floor_under |
| Flight | wind, corridor width | landed / crashed | Plane |
Pick one and do it well. A game that is two archetypes stapled together is usually neither.
Level structure
Three stages, always in this order:
- Teach — the mechanic in isolation, no failure possible. One idea.
- Test — the same mechanic under pressure. This is most of the game.
- Twist — the mechanic combined with a second one, or inverted.
Build one complete vertical slice through all three before making level 2. A slice that is wrong is cheap to fix; five levels of the same wrongness are not.
Generating levels
makepad-game-gen gives levelgen, kit, interior, scatter, terrain, spline, lsystem, tree, implicit, mesh, texgen, all from a seeded rng. makepad-game-script::compose adds kit_from_index, level_placements, PlacedTile. libs/rtsmap is the tiled-RTS map generator shared by the importer and the sandbox.
Rules:
- A level is a seed plus a preset, not a vertex dump. That is what makes it replicable across the wire and cheap to store.
- Generate, then validate: is the goal reachable, is the spawn clear, is there a navigable path? An unvalidated generator produces unwinnable levels roughly as often as it produces good ones.
- Hand-place the things the player must notice. Scatter the rest.
Difficulty
Tune three axes independently so a change is diagnosable: density (how many), speed (how fast), tolerance (how much error is forgiven — hitbox, coyote time, par time).
Widen tolerance early and narrow it late; players read tolerance as "I got better", and read density as "the game got harder". Never scale all three at once.
State machine
Every game needs these states, and every one needs a UI surface (see makepad-game-ui-designer):
Boot -> Menu -> Playing -> Paused -> Playing
|-> Win -> Menu | Retry
|-> Lose -> Menu | Retry
Failure modes worth naming: pausing that does not stop the sim step; a retry that leaves score, timers, particle emitters or audio voices from the previous run alive; a win that fires twice because the condition is checked without a latch. Reset through one reset() that rebuilds world state, and test it by winning twice in a row.
Scoring
Keep score in the sim (score, score_of verbs, or a sim field) — never in the widget, or it dies with the view and cannot be replicated to clients. Make it observable: log it on every change so tests can assert on it.