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.
7.3 KiB
| name | description |
|---|---|
| makepad-gameplay-systems | Design and implement Makepad game loops: entities, movers, rigid bodies, terrain, input, camera, physics, AI brains, racing, scoring, netplay and feel. Use for core loop, level design, controls, collision, character/vehicle handling, NPC behaviour, multiplayer session, and game-feel work on makepad-game-sim, makepad-game-blocks, makepad-game-script and makepad-game-session. |
Makepad Gameplay Systems
Build the loop that makes it a game: something the player does, a reason to do it, and a state that ends.
Before implementing
Write the contract down. Four lines, in artifacts/game-progress.md:
- Core loop — one sentence: what the player repeatedly does and why it escalates.
- Win / lose — both reachable, both testable, both observable in a log line.
- Input map — every action, on every target device you claim to support.
- Camera scale — how tall is the player in world units, how far is the camera. This decides asset scale, terrain scale, and readability, and it is expensive to change later.
Pick the route (script verbs vs Rust crate) per makepad-game-director/references/architecture.md before writing code.
The simulation model
makepad-game-sim is Cx-free. Every gameplay rule you write belongs in a Cx-free crate and gets a unit test. If a rule needs a Cx to test, it is in the wrong place.
GameWorld holds entities and steps at a fixed TICK_DT. Never advance by a variable frame delta — it breaks netplay, replay, and determinism.
Movement comes in three kinds, and picking wrong is the most common design error here:
| Kind | Use for | API |
|---|---|---|
| Mover (kinematic capsule) | players, NPCs, anything that should feel controlled | capsule_mover_step, apply_mover_contacts |
| Rigid body | debris, crates, ragdolls, anything that should feel thrown | RigidDynamics, step_dynamics, rigid_impulse, rigid_spin |
| Scripted transform | platforms, doors, lifts on rails | set position directly per tick |
A player on a rigid body feels floaty and catches on geometry. A crate on a mover feels weightless. Mixed control — a mover that is sometimes rigid — is how ragdoll works (activate_ragdoll, ragdoll_active, ragdoll_body_poses), and that transition must be explicit, not emergent.
Ground and collision helpers: ground_y, ground_normal, deck_floor_under, box_floor_under, cast_ray, projectile_ccd, raycast_filter(), projectile_filter(). Use projectile_ccd for anything fast — a bullet stepped discretely tunnels through walls, and this is not a bug you will find by playing.
Also in sim: terrain, landform, water (WaterVolume, WaterWave, buoyancy), voxel, nav (NavMap, NavAgent, FlowField), decal (BulletDecal), particles, hud, player, sense, queries.
Entity lookup is O(log n) binary search over a sorted-id Vec. Do not build a parallel HashMap index beside it.
Building blocks — do not reimplement these
makepad-game-blocks already solved the hard handling problems. Reaching for raw physics when a block exists is the second most common error here.
Car/CarConfig— vehicle handling, suspension, wheelsCharacter/CharacterConfig/CharacterPose— humanoid locomotion and posePlane/PlaneConfig— flightNpc/NpcConfig/Personality/Activity/Poi/PoiSet/DoorUse/DAY_SECONDS— daily-routine NPCs with points of interestBrain/BrainKind— wander, chase, patrol behaviourRaceKit/Checkpoint/SpawnPoint/Standing— laps, checkpoints, standingsDriveInput,RawInput,ControlSource,PlayerRig,Seat,Blocks
Tune a *Config before writing new physics. If the config genuinely cannot express the feel, extend the block in libs/game/blocks — with a unit test — rather than bypassing it in the app.
Input
RawInput and ControlSource abstract the source; GameInputState / GamepadState come from makepad_platform::event::game_input. Support keyboard, gamepad, and touch through the same action enum — branch at the mapping layer, never inside gameplay code.
Two things that get missed and are always caught in review:
- Touch: no hover, no right-click, fat fingers. Every action needs a touch path or the mobile claim is false.
- XR:
apps/arcade/src/xr_input.rsexists. If the target includes Quest, controller input is not the same shape as gamepad input.
Deadzone analog sticks, normalise diagonal keyboard movement (or diagonals are faster — the classic bug), and buffer the jump input a few frames before ground contact.
Feel
Feel is mostly timing, and timing is cheap. In rough order of return:
- Coyote time — jump remains valid ~100 ms after leaving ground.
- Input buffering — an action pressed just before it becomes legal still fires.
- Acceleration curves — never set velocity directly from input for a character.
- Camera lag and lookahead — the camera trails and leads;
CameraRiginmakepad-game-renderowns this. - Hit feedback —
cam_shake, a particleburst, ansfx, and a HUD flash on the same frame as the hit. All four, or the hit reads as nothing. - Recovery frames — a brief committed window after an action makes it feel weighty.
Script route specifics
Verbs are listed in architecture.md; makepad_game_script::api_text() is authoritative. Constraints that shape design:
- One cumulative 500k-instruction pool per tick, shared by
on_tick+ timers + touch events, target ≤ 2 ms. Do not write a per-entityon_tick; iterate a batch inside one handler. - Options keys are typo-guarded. A rejected key is a wrong key.
- Use
rand/rand_range, the seeded verbs — never host RNG — or netplay desyncs. - Untrusted scripts pass through
strip_capabilitieswith aTrustlevel first. AI-authored code is untrusted.
Multiplayer
makepad-game-net is host-authoritative LAN transport; makepad-game-session gives HostSession, ClientSession, Session, SessionEvent, replication, MAX_PLAYERS, and drive_input_for(world, player).
Design rules: clients send input, never state. The host steps the sim and replicates. Anything derived from std float math or unseeded RNG will desync — use makepad-game-math and seeded rng. Content replicates as (preset, seed, position), not vertex data.
makepad-game-coedit handles collaborative editing (leases, diff3, Transaction, Refusal) — a different problem from gameplay replication. Do not mix them.
Verification
cargo test -p makepad-game-sim
cargo test -p makepad-game-blocks
cargo check -p <your app crate>
Assert on behaviour, not on internals: the mover clears a 0.5 m step and does not clear a 1.5 m wall; the car's body does not sink into the road; the lap counts once per crossing and not twice; the NPC reaches its POI within N ticks. Test the composed system when the claim is about composition — a walker entering a real generated room is one test, not two half-tests that both pass while the walker floats.
Required reading
references/core-loop.md— briefs, level structure, difficulty, state machine.references/physics-and-movement.md— mover vs rigid, collision, tuning tables.references/input-and-camera.md— action mapping, devices, camera rigs.