3.8 KiB
| 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 |
|
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.gd→draw_circlefor city marker +draw_rectfor barsunit_renderer.gd→draw_circlefor unit + centered combat-type letter (F/W/R/S/^/M/C/N/V) +draw_rectfor HP bar + yellow selection ring
- Sprite path already partly wired:
unit_renderer.gd:304-321has_cache_unit_sprite+_get_unit_spriteviaThemeAssets.load_sprite("sprites/units/<type_id>.png"). When a sprite file exists at that path,_draw()usesdraw_textureinstead 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.gdrendersdraw_circleFIRST (unconditional baseline), then OPTIONALLY overlays/replaces with<unit_id>_<race>_<sex>.pngfromassets/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 viaThemeAssets.resolve(path). - ✗
city_renderer.gdrendersdraw_circle+draw_rectbars FIRST (unconditional baseline), then OPTIONALLY overlays<building_id>.png(or per-tier variant) fromassets/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_circlestill 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).