The previous ten tickets shipped with almost no coverage - only #109, #113,
#115 and #117 touched a test. That was a gap, not a decision: everything
before it had its behaviour pinned, and #116 in particular added a whole
subsystem nothing was watching.
Four new files and one extended case:
test_spacial_workshop #116 - the repair economy end to end: the
cost of a repair scales with the damage, the
workshop asks logistics for that ore and
stops at its buffer, a drone spends when it
LEAVES so two cannot double-charge one wall,
and a target levelled in flight sends its
load home rather than swallowing it
test_desktop_controls #118/#121 - both driven through the real
routing, because the routing is what was
missing; a test calling handle_mouse_button()
itself would have passed against both reports
test_enemy_bomber #114 - it flies, it faces where it flies, its
bombs arrive, and it bombs structures with no
fleet in sight
test_menu_polish #111/#112/#119/#120 - what each panel shows
test_wave_system (case G) #110 - the dev button, and that it does not
exist outside dev mode
One assertion worth recording: the craft caption is checked as an EXACT
match against the vessel's display name rather than by hunting for resource
words in it. The first version failed on "Gas Bomber" - a vessel named after
a resource, and always will be. What #111 removed was the price spelled out
underneath, not the name.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The old spawner put one enemy on the map every 3-6 seconds for ever. There
was no rhythm to the danger and nothing to prepare for. Enemies now arrive
in waves: a long quiet, a warning, an attack, and quiet again once the wave
is dead.
The clock lives in GameState, because Main.tscn is destroyed on every trip
to a planet surface and a wave must not be cancelled, nor restarted from
zero, by a landing. The spawning does not: GameState cannot see the world,
so EnemySpawner reads the phase and puts the enemies in it. That also
settles what happens when a wave turns while the player is on a surface -
the wave is waiting in space when they come back.
EnemySpawner keeps its name deliberately. It is still the thing that puts
enemies in the world, and 88 test files already say
`get_node("EnemySpawner").set_process(false)` to ask for a quiet map.
Strength is a function of the FLEET, per the ticket, with the wave number as
a slower second term so a player who never grows still meets escalation. The
budget is spent most-expensive-first, so a large wave is heavier rather than
merely longer, and min_strength keeps the first waves to chasers whatever
the arithmetic says.
"No timer should be visible" is enforced rather than merely observed:
GameState offers wave_warning_pulse(), a 0..1 throb, and no
remaining-seconds accessor at all, so the alert cannot drift into being a
countdown. The test pins both - that no such accessor exists, and that the
alert's own text contains no digits.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>