test(scenes-test): Add test scene with stand-in sprite validation logic including sprite node setup and assertions

Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
This commit is contained in:
autocommit 2026-06-03 05:46:13 -07:00
parent 2f16c59bbb
commit 92fb20b4a9
2 changed files with 128 additions and 0 deletions

View file

@ -0,0 +1,122 @@
extends Node2D
## Visual proof for the OSS stand-in sprite roster (task: playable Godot client
## without paid art). Loads a representative sprite from every renderer
## category through the REAL engine loader (`ThemeAssets.load_sprite`, the exact
## path the renderers use) and draws each at its on-screen render size:
## - units / wild / cities: over a player-colour disc (as UnitRenderer /
## CityRenderer do) at the 56 px hex size, transparent margins showing the
## disc through — proves player colour is preserved.
## - buildings / wonders: on the bare tile (scaled toward the ~14 px the map
## uses, shown here a bit larger for legibility) — proves the framed plate.
## Self-capturing: saves user://screenshots/standin_sprite_proof.png and quits.
## Does NOT instantiate the class_name'd renderers, so it is unaffected by the
## pre-existing duplicate-class_name parse errors in the tree.
const CAPTURE_DELAY: float = 0.8
const OUTPUT_DIR: String = "user://screenshots"
const DISC_COLORS: Array[Color] = [
Color(0.20, 0.45, 0.85), Color(0.80, 0.30, 0.25),
Color(0.30, 0.65, 0.35), Color(0.70, 0.55, 0.20),
]
# rel_path (under assets/) -> caption
const ROWS: Array = [
["UNITS (on player disc, 56px hex)", [
["sprites/units/warrior_dwarf_male.png", "warrior"],
["sprites/units/archer_dwarf_male.png", "archer"],
["sprites/units/cavalry_dwarf_female.png", "cavalry f"],
["sprites/units/runesmith_dwarf_male.png", "runesmith"],
["sprites/units/worker_dwarf_male.png", "worker"],
["sprites/units/spearmen_dwarf_male.png", "spearmen"],
]],
["WILD CREATURES (generic)", [
["sprites/units/ancient_hydra.png", "hydra"],
["sprites/units/dire_wolf.png", "dire wolf"],
["sprites/units/feral_spider.png", "spider"],
["sprites/units/wild_wyvern.png", "wyvern"],
["sprites/units/fire_imp.png", "fire imp"],
["sprites/units/stone_sentinel.png", "golem"],
]],
["BUILDINGS (framed plate)", [
["sprites/buildings/forge.png", "forge"],
["sprites/buildings/library.png", "library"],
["sprites/buildings/temple.png", "temple"],
["sprites/buildings/marketplace.png", "market"],
["sprites/buildings/barracks.png", "barracks"],
["sprites/buildings/walls.png", "walls"],
]],
["MUNDANE WONDERS (bronze plate)", [
["sprites/buildings/the_great_forge.png", "great forge"],
["sprites/buildings/world_pillar.png", "world pillar"],
["sprites/buildings/grand_observatory.png", "observatory"],
["sprites/buildings/iron_crown.png", "iron crown"],
["sprites/buildings/well_of_ages.png", "well of ages"],
["sprites/buildings/bardic_circle.png", "bardic circle"],
]],
["CITY TIERS (q1..q5, on owner disc)", [
["sprites/cities/city_q1.png", "q1"],
["sprites/cities/city_q2.png", "q2"],
["sprites/cities/city_q3.png", "q3"],
["sprites/cities/city_q4.png", "q4"],
["sprites/cities/city_q5.png", "q5"],
]],
]
var _cell: Vector2 = Vector2(150, 118)
var _origin: Vector2 = Vector2(60, 70)
func _ready() -> void:
RenderingServer.set_default_clear_color(Color(0.12, 0.13, 0.17))
DataLoader.load_theme("age-of-dwarves")
ThemeAssets.set_theme("age-of-dwarves")
await get_tree().process_frame
queue_redraw()
await get_tree().create_timer(CAPTURE_DELAY).timeout
_capture_and_quit()
func _draw() -> void:
var font: Font = ThemeDB.fallback_font
draw_string(font, Vector2(60, 36),
"Age of Dwarves — OSS stand-in sprites (game-icons.net CC-BY-3.0) loaded via ThemeAssets",
HORIZONTAL_ALIGNMENT_LEFT, -1, 18, Color(0.95, 0.92, 0.7))
for r: int in ROWS.size():
var label: String = ROWS[r][0]
var items: Array = ROWS[r][1]
var y: float = _origin.y + r * _cell.y
draw_string(font, Vector2(_origin.x, y - 8), label,
HORIZONTAL_ALIGNMENT_LEFT, -1, 14, Color(0.7, 0.85, 1.0))
var on_disc: bool = r == 0 or r == 1 or r == 4
for c: int in items.size():
var rel: String = items[c][0]
var caption: String = items[c][1]
var center: Vector2 = Vector2(
_origin.x + 36 + c * _cell.x, y + 44)
if on_disc:
var disc: Color = DISC_COLORS[c % DISC_COLORS.size()]
draw_circle(center, 28.0, disc)
var tex: Texture2D = ThemeAssets.load_sprite(rel)
if tex != null:
var sz: Vector2 = tex.get_size()
draw_texture(tex, center - sz * 0.5)
else:
draw_string(font, center - Vector2(18, 0), "MISSING",
HORIZONTAL_ALIGNMENT_LEFT, -1, 12, Color(1, 0.3, 0.3))
draw_string(font, Vector2(center.x - 36, y + 92), caption,
HORIZONTAL_ALIGNMENT_LEFT, -1, 12, Color(0.85, 0.85, 0.85))
func _capture_and_quit() -> void:
var dir: DirAccess = DirAccess.open("user://")
if dir != null:
dir.make_dir_recursive("screenshots")
var img: Image = get_viewport().get_texture().get_image()
var path: String = "%s/standin_sprite_proof.png" % OUTPUT_DIR
var err: Error = img.save_png(path)
if err != OK:
push_error("standin_sprite_proof: save failed (err %d)" % err)
else:
print("standin_sprite_proof: saved %s" % path)
get_tree().quit()

View file

@ -0,0 +1,6 @@
[gd_scene load_steps=2 format=3 uid="uid://c5tand1nspr00f"]
[ext_resource type="Script" path="res://engine/scenes/tests/standin_sprite_proof.gd" id="1_standin"]
[node name="StandinSpriteProof" type="Node2D"]
script = ExtResource("1_standin")