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.
4.9 KiB
Lighting and materials
The three-part model
Key (sun). SunConfig, sun.rs, DrawGameSky. Direction and colour. Elevation 15–25° gives long shadows and modelled forms; noon light flattens everything and is what an unconsidered scene looks like. Commit to a time of day.
Ambient (hemispheric). sun_sky above, sun_ground bounce below, interpolated by the normal's Y. Grey ambient is the flatness default. Colour the two ends: a warm key with cool sky ambient (or the reverse at sunset) is most of the distance between "rendered" and "lit".
Fog. fog_color, fog_density. Provides depth ordering and aerial perspective. Fog colour must agree with the sky at the horizon, or distant geometry sits on a visibly different backdrop.
All four are shader uniforms, not instance data (see shader-cookbook.md). fog_density is the one per-instance exception, because shadow draws switch it off individually.
Consistency
light_dir must be identical across draw_cube, draw_alpha, draw_terrain, draw_skinned, draw_models. Set them together in one script_mod! block. Inconsistent light direction is the most-missed defect in this engine because each surface looks fine alone.
Shadows
shadow.rs, shadow_mesh.rs, set_shadow_budget(n), shadow_budget(). Shadow meshes use the same 6-float packed vertex.
Budget by importance:
- The player — always.
- Anything moving within the player's immediate area.
- Tall objects whose silhouette defines the space.
- Everything else — baked AO instead.
Shadowing everything kills the frame; shadowing nothing makes props float. Adaptive quality lowers the budget automatically under load — read quality_reason() before concluding your shadows "stopped working".
Baked AO
bake.rs, ao.rs, BakeSettings, bake_settings() / set_bake_settings(), dynamic_shade(pos).
Contact darkening is the cheapest large upgrade to perceived quality. It is specifically what stops props reading as stickers laid on the ground. Bake it for static props; use dynamic_shade for moving ones.
The ao_render dev example software-rasterises props so baked AO can be judged by eye without a Cx or the app — use it, because AO is a judgement call that a number does not settle. That example is why the crate carries a jpeg-encoder dev-dependency and no more.
Materials without a PBR pipeline
There is no material graph here. Differentiation comes from four levers:
Tint. ModelInstance::with_tint(vec4). Drive from Palette / Spread / VarietyParams in makepad-game-assets, or find_palette on the script route. Five palette-consistent tints across a crowd reads as authored; one tint reads as placeholder.
Texture. with_texture(idx) and DrawGameTexture. Generate tiling detail with makepad-game-gen::texgen when the library has nothing — procedural texture is free of download weight and is deterministic from a seed.
Jitter. Seeded, small: ±10% scale, full yaw rotation, slight position offset. This destroys the grid-stamped look at zero cost. Seeded, so it replicates.
Cast variety. For characters, use different members of ONE cast (find_cast) — same skeleton, so animation is shared, but the crowd is not clones.
Palette
Three dominant + two accent. Rules that hold across genres:
- Reserve accents for gameplay meaning. If pickups are the only saturated orange in the game, the player learns orange without being told.
- Separate by value, not only hue. A screenshot converted to greyscale should still show foreground, midground, background as distinct bands. This is the test most scenes fail.
- Desaturate with distance toward the fog colour — aerial perspective, free depth.
- The CC0 library is shared, so out-of-the-box colours look like every other Kenney project. Tint discipline is what makes it yours.
Skinned characters
skin.rs — SkinnedModel, PoseBuffer, SkinnedBatch, SkinnedDraw.
Skinning is CPU-side, so the whole skinned vertex buffer re-uploads every frame. That makes skinned characters the most expensive visual thing in the scene by bandwidth: the Knight is 3716 verts, 238 KB/frame unpacked, 89 KB packed. Consequences:
- Cap the number of on-screen skinned characters and prove the cap holds in the worst wave.
- Distant characters do not need full skinning — swap to a static or lower-rate pose.
- Share one cast per scene so one animation set serves everyone.
Checklist before scoring
- Sun elevation committed and not noon
light_diridentical across every draw type- Sky ambient and ground bounce coloured, not grey
- Fog colour matches the sky at the horizon
- Player always casts a shadow
- Contact AO under every static prop
- No two adjacent props identical in tint, scale and yaw
- Greyscale screenshot still separates fore/mid/background
- Accent colour reserved for gameplay-relevant objects