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.
88 lines
3.6 KiB
Markdown
88 lines
3.6 KiB
Markdown
# Texture workflows
|
||
|
||
## Pipeline
|
||
|
||
```
|
||
texgen (seeded) -> packed texture -> DrawGameTexture -> ModelInstance::with_texture(idx)
|
||
```
|
||
|
||
Generate at load, cache by `(preset, seed)` in `makepad-game-gen::cache`, and bound the cache. Generating textures during play is a stutter source; an unbounded cache is a leak.
|
||
|
||
## Layer order
|
||
|
||
Always build in this order — later layers depend on earlier ones being settled:
|
||
|
||
1. Base value
|
||
2. Large low-frequency variation
|
||
3. Structure (planks, bricks, grain)
|
||
4. Small detail (grit, scratches)
|
||
5. Edge wear
|
||
|
||
If a texture is not working, the fault is almost always layer 1 or 2. Adding more detail to a wrong base value never fixes it, and detail is the layer that costs the most to compute.
|
||
|
||
## Seamless tiling
|
||
|
||
Wrap the noise domain so opposite edges match. Test the tile by rendering it 4×4 and looking for:
|
||
|
||
- A visible grid → base contrast too high, or a distinctive feature repeating
|
||
- A diagonal → directional noise not wrapped in both axes
|
||
- Bright/dark blocks → low-frequency layer wavelength larger than the tile
|
||
|
||
Fixes, cheapest first: lower the base contrast; move the distinctive feature to a per-instance decal instead of into the tile; add per-instance yaw and tint jitter; only then increase tile size.
|
||
|
||
## Texel density
|
||
|
||
Pick one target — say 256 texels per world metre — and derive every tiling scale from it. A crisp crate beside a blurry wall is a defect everyone sees and few can name. Write the target into `artifacts/game-progress.md` beside the palette.
|
||
|
||
## Value structure
|
||
|
||
Convert a gameplay screenshot to greyscale. Foreground, midground and background must read as three distinct bands. If they merge, adjust *value*, not hue — hue changes alone will not fix a flat read, and this is the most common mistake when a scene "looks muddy".
|
||
|
||
## Palettes in code
|
||
|
||
`Palette`, `Spread`, `VarietyParams` from `makepad-game-assets`; `find_palette` on the script route.
|
||
|
||
```rust
|
||
let tint = palette.sample(&variety, seed_for(entity_id));
|
||
ModelInstance::new(key, verts, idx, xform).with_tint(tint)
|
||
```
|
||
|
||
Seed the sample per entity so it is stable across frames and identical on every client. A tint that changes each frame flickers; a tint derived from an unseeded RNG desyncs in netplay.
|
||
|
||
## Resolution guidance
|
||
|
||
| Surface | Size |
|
||
| --- | --- |
|
||
| Large ground / terrain, tiled | 512² tiled, not one huge map |
|
||
| Building walls | 512² |
|
||
| Props | 256² |
|
||
| Distant scenery | 128², or vertex colour only |
|
||
| HUD icons | drawn geometry, not a bitmap |
|
||
|
||
Textures are bandwidth, and Quest is bandwidth-bound before ALU-bound. Match resolution to on-screen size; a 2048² map on a distant prop is pure cost.
|
||
|
||
## Sky and fog
|
||
|
||
```rust
|
||
SkyConfig { /* horizon colour, zenith colour, sun disc */ }
|
||
```
|
||
|
||
Checks that catch most sky problems:
|
||
|
||
- Fog colour equals the sky colour **at the horizon**, not at the zenith
|
||
- Sun disc position agrees with `light_dir` on every draw type
|
||
- Horizon gradient band is wide enough not to show a hard line
|
||
- Sky brightness matches the time of day the shadows imply
|
||
|
||
## Icons
|
||
|
||
Draw as geometry or SDF in the widget layer. Checklist: readable at 24 px; meaning never carried by hue alone; consistent stroke weight and corner radius across the set; control glyphs matching the active input device.
|
||
|
||
## Verification
|
||
|
||
- View in-engine at the real distance and angle — not in a texture viewer
|
||
- 4×4 tile test for seams
|
||
- Greyscale test on a gameplay screenshot
|
||
- Texel density compared against an adjacent surface
|
||
- Memory: total texture bytes against the device budget
|
||
- Score scorecard categories 3 (materials), 4 (ground), 6 (colour), 9 (sky)
|