magicciv/.project/objectives/p0-23-sprite-rendering-capability.md
Natalie 2d9554d9ff feat(@projects): update wasm build and guide deployment workflows
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
2026-04-17 13:06:14 -07:00

3.8 KiB
Raw Blame History

id title priority status scope owner updated_at evidence
p0-23 Sprite rendering capability — replace procedural draw_* with texture rendering p0 partial game1 shipwright 2026-04-17
src/game/engine/src/rendering/city_renderer.gd
src/game/engine/src/rendering/unit_renderer.gd
public/games/age-of-dwarves/assets/sprites/

Summary

Renderers currently draw units and cities with draw_circle / draw_rect (procedural, flat-color shapes). 7 sprite files exist in assets/sprites/{buildings,units}/ but aren't wired — the renderer path uses only primitives.

Parallel to the audio split (p0-21 capability / p2-16 assets): the rendering capability to use sprites when they exist is a P0 gate (must be wired before ship); the assets to cover every unit / building / tier / race combo is P2 (ship incrementally).

Design rule (user directive 2026-04-17): Do NOT replace draw_circle/draw_rect with sprites. Keep the procedural draw path as the always-working baseline that never deletes. Sprite rendering is an additive enhancement layer — when a matching sprite exists, it's drawn on top of or in place of the draw primitive for that frame; when absent, the draw primitive continues to render normally. The game is always playable with zero sprites in assets/sprites/.

Current state

  • Sprites present: 0. Prior 7 files were deleted 2026-04-17 per user directive (quality bar not met; slate is clean for retry via tools/sprite-generation/ pipeline or commissioned art).
  • Renderers using draw_* primitives (always-on baseline per design rule above):
    • city_renderer.gddraw_circle for city marker + draw_rect for bars
    • unit_renderer.gddraw_circle for unit + centered combat-type letter (F/W/R/S/^/M/C/N/V) + draw_rect for HP bar + yellow selection ring
  • Sprite path already partly wired: unit_renderer.gd:304-321 has _cache_unit_sprite + _get_unit_sprite via ThemeAssets.load_sprite("sprites/units/<type_id>.png"). When a sprite file exists at that path, _draw() uses draw_texture instead of the circle+letter. Fallback to procedural draw when file absent. Same pattern needed for city_renderer.
  • Lookup key mismatch: current lookup is bare <type_id>.png (e.g. bowmen.png). If art ever lands with race/sex suffix (e.g. bowmen_dwarves_f.png), the lookup needs to be updated to compose <type_id>_<race_id>_<sex>.png — but this is cosmetic routing, not a capability gap.

Acceptance

  • unit_renderer.gd renders draw_circle FIRST (unconditional baseline), then OPTIONALLY overlays/replaces with <unit_id>_<race>_<sex>.png from assets/sprites/units/ when the file exists. If sprite missing, draw_circle alone is the final visual — no error, no blank, no fallback-shim code path. No hardcoded paths — resolve via ThemeAssets.resolve(path).
  • city_renderer.gd renders draw_circle + draw_rect bars FIRST (unconditional baseline), then OPTIONALLY overlays <building_id>.png (or per-tier variant) from assets/sprites/buildings/ when present.
  • ✗ HP bar + owner-color tint always rendered (on top of whatever sprite or draw baseline was used) — owner state is a game-mechanics overlay, never driven by sprite presence.
  • ✗ GUT test: mock unit with KNOWN sprite path → assert sprite is drawn; mock unit with NO sprite path → assert draw_circle still rendered (no crash, no blank).
  • ✗ Screenshot proof: scene with 2 units side-by-side — 1 with sprite, 1 without — showing both are visible, colored correctly, with HP bars.

Non-goals

  • Every tier × race × sex combination authored (that's p2-17).
  • Animated sprites / sprite atlases (post-EA).
  • Terrain/tile sprites beyond current TileMap (p0-19 biome-economy covers tile yield visualization; raw terrain sprites are a separate concern tracked under the roadmap's Phase 5 entry).