Repair a broken working tree, and make every crafter press report

The crafter buttons doing nothing was not the crafter: Ship.gd was left
mid-edit and failed to parse (undeclared SHIELD_COLOR/SHIELD_RADIUS, and
a spawn() that only exists on the concrete VFX subclass). A script that
does not compile takes Main.tscn's whole node tree with it, so every
button in the game was dead. The project directory is the one being
played from, so an unfinished edit there is a broken build - finish or
revert before stopping.

With that fixed, the real gap underneath: an order the crafter cannot
pay for is ACCEPTED and queued (#16), which is indistinguishable from a
dead button. Ordering now reports either "building now" or "queued - N
more ore must be delivered here", and the transient message is rendered
LAST so it is the first line read rather than buried under the standing
fleet-capacity note.

test_crafter_feedback covers all three presses and asserts the message
survives the per-frame refresh, which is the specific way this looked
broken before.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Loïc Wisniewski 2026-08-11 22:50:09 +02:00
commit 004808f067
6 changed files with 413 additions and 14 deletions

View file

@ -564,17 +564,22 @@ func _refresh_craft_status() -> void:
craft_interceptor_button.queue_redraw()
# One statement of the fleet count, either way round: the capacity line
# replaces the plain readout rather than being bolted in front of it.
if room:
craft_status.text += " Fleet %d/%d" % [fleet.ships.size(), GameState.max_fleet_size()]
else:
var queued_ships: int = GameState.pending_orders_of(craft_building_id, GameState.PRODUCT_SHIP)
var owed: int = GameState.ships_owed + queued_ships
var pending_note: String = "" if owed == 0 else " (%d already on order)" % owed
craft_status.text = "No room in the fleet: %d/%d%s - research capacity at the mothership\n%s" % [
fleet.ships.size(), GameState.max_fleet_size(), pending_note, craft_status.text
]
# LAST, so a message about what just happened is the first line the
# player reads rather than being buried under the standing state.
if craft_message != "":
if Time.get_ticks_msec() < craft_message_until:
craft_status.text = "%s\n%s" % [craft_message, craft_status.text]
else:
craft_message = ""
if room:
craft_status.text += " Fleet %d/%d" % [fleet.ships.size(), GameState.max_fleet_size()]
else:
craft_status.text = "Fleet full %d/%d - research capacity at the mothership\n%s" % [
fleet.ships.size(), GameState.max_fleet_size(), craft_status.text
]
func _on_craft_interceptor() -> void:
@ -588,9 +593,11 @@ func _on_craft_interceptor() -> void:
_say("Fleet is full (%d slots)" % GameState.max_fleet_size())
return
# No affordability check: an order the crafter cannot pay for yet is
# QUEUED, and completes by itself once ore is delivered here (#16).
# QUEUED, and completes by itself once ore is delivered here (#16). But
# queueing silently looks identical to a dead button, so it says which
# happened and what the crafter is still short of.
GameState.queue_order(craft_building_id)
_refresh_craft_status()
_report_order(GameState.PRODUCT_SHIP)
func _refresh_load_ore() -> void:
@ -604,6 +611,16 @@ func _on_load_ore() -> void:
_refresh_load_ore()
func _report_order(product: String) -> void:
var short: int = GameState.outstanding_cost(craft_building_id)
if short > 0:
_say("%s queued - %d more ore must be delivered here" % [
GameState.VESSEL_NAMES.get(product, product), short
])
else:
_say("%s ordered - building now" % GameState.VESSEL_NAMES.get(product, product))
func _on_store_ore() -> void:
if craft_building_id == 0:
return