Space-time distorder drains energy while boosting (#62)

GameState._advance_distorder_drain() runs in GameState._process() -
not the distorder component's tick() - alongside extractor mining and
production, so it (and the fleet's travel) keeps working across the
space<->surface scene swap. Drain scales with how far above 1.0 the
multiplier is: (fleet_speed_multiplier - 1.0) / (MAX - 1.0) *
ENERGY_DRAIN_PER_SECOND (2.0 at full boost), accumulated fractionally
the same way extractor mining_progress is so small multipliers still
drain a nonzero amount instead of rounding to zero every frame.

Running the fleet hold's energy to exactly zero force-resets
fleet_speed_multiplier to 1.0 and raises a one-shot
boost_depleted_notice flag, since GameState can't reach into whichever
scene's SpeedFader may or may not currently exist. SpeedFader.gd
consumes the flag on its next _process(), snaps its knob down (it was
already reading the multiplier live, so this falls out for free) and
shows "Out of energy!" - also clearing active_touch_index so a
still-held drag can't immediately re-boost from the position the
finger never moved away from.

test_space_time_distorder.gd (#59) updated to stock fleet energy
first, for the same reason #60/#61 needed it: boosting is no longer
free, and that test's own multi-second boosted phases would otherwise
get cut short mid-measurement by running out.
This commit is contained in:
Loïc Wisniewski 2026-08-16 19:21:54 +02:00
commit 651f8b787e
4 changed files with 211 additions and 1 deletions

View file

@ -22,6 +22,7 @@ extends Control
var active_touch_index: int = -1
# 0 = bottom of the track (1.0x), 1 = top (GameState.MAX_FLEET_SPEED_MULTIPLIER).
var knob_t: float = 0.0
var status_message_until: int = 0
func _ready() -> void:
@ -44,7 +45,21 @@ func _process(_delta: float) -> void:
return
knob_t = (GameState.fleet_speed_multiplier - 1.0) \
/ maxf(GameState.MAX_FLEET_SPEED_MULTIPLIER - 1.0, 0.001)
label.text = "x%.1f" % GameState.fleet_speed_multiplier
# #62: GameState._process() (not this node's own _process()) is what
# drains energy and force-resets the multiplier, since it has to keep
# running across the space<->surface swap and while this control might
# not even be in the current scene tree. It leaves a one-shot flag for
# whichever SpeedFader picks it up next.
if GameState.boost_depleted_notice:
GameState.boost_depleted_notice = false
# Still holding the drag at the moment energy ran out would
# otherwise re-boost on the very next drag event, from a knob
# position the finger never actually moved away from.
active_touch_index = -1
label.text = "Out of energy!"
status_message_until = Time.get_ticks_msec() + 3000
elif Time.get_ticks_msec() >= status_message_until:
label.text = "x%.1f" % GameState.fleet_speed_multiplier
queue_redraw()