makepad/skills/makepad-image-generator/references/texture-workflows.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

88 lines
3.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.

# 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)