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

3.6 KiB
Raw Permalink Blame History

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.

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

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)