Typed owed vessels, ship lab building type, shield vessel gate

Groundwork for #5. vessels_owed carries the VESSEL TYPE rather than a
bare count, so a shield vessel finishing while the player is on a planet
comes back as a shield vessel. Fleet.add_ship takes a type, and vessels
already flying are re-statted when an upgrade is researched.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Loïc Wisniewski 2026-08-11 23:10:07 +02:00
commit 19ac758da1
9 changed files with 80 additions and 27 deletions

View file

@ -45,7 +45,7 @@ func _initialize() -> void:
game_state.extractors.clear()
game_state.rocks = 500
game_state.fleet_cargo = 0
game_state.ships_owed = 0
game_state.vessels_owed.clear()
# Room to grow: the default cap is BASE_FLEET_SIZE (5) and the fleet
# starts at exactly 5, so without this every completed order would have
# nowhere to put its vessel and the test would be measuring the cap
@ -180,7 +180,7 @@ func _process(delta: float) -> bool:
# --- 6 + 7. no scene, no fleet: production still completes --
# The scene has to be GONE before the order is placed. With a
# fleet still alive and under its cap it claims the vessel the
# same frame production finishes, which would leave ships_owed
# same frame production finishes, which would leave vessels_owed
# back at 0 and prove nothing about orders surviving without it.
ships_at_start = fleet.ships.size()
scene.queue_free()
@ -207,11 +207,11 @@ func _process(delta: float) -> bool:
print("TEST_BUILDING_STOCK_QUEUE: FAIL (order stalled once the space scene was gone)")
quit(1)
return true
if game_state.ships_owed < 1:
if game_state.vessels_owed.is_empty():
print("TEST_BUILDING_STOCK_QUEUE: FAIL (vessel completed with no fleet present was lost, not owed)")
quit(1)
return true
print("no scene at all -> order completed, %d vessel owed" % game_state.ships_owed)
print("no scene at all -> order completed, %d vessel owed" % game_state.vessels_owed.size())
# Come back to space: the fleet should claim what it is owed.
scene = load("res://Main.tscn").instantiate()
@ -223,8 +223,8 @@ func _process(delta: float) -> bool:
8:
if elapsed < 0.5:
return false
if game_state.ships_owed != 0:
print("TEST_BUILDING_STOCK_QUEUE: FAIL (returning fleet never claimed its %d owed vessel(s))" % game_state.ships_owed)
if not game_state.vessels_owed.is_empty():
print("TEST_BUILDING_STOCK_QUEUE: FAIL (returning fleet never claimed its %d owed vessel(s))" % game_state.vessels_owed.size())
quit(1)
return true
print("fleet returned and claimed the owed vessel (ships=%d)" % fleet.ships.size())

View file

@ -38,7 +38,7 @@ func _initialize() -> void:
game_state.unlocked = ["shipyards", "coordination", "wing"]
game_state.rocks = 100
game_state.fleet_cargo = 0
game_state.ships_owed = 0
game_state.vessels_owed.clear()
scene = load("res://Main.tscn").instantiate()
root.add_child(scene)
controller = scene.get_node("BuildController")

View file

@ -0,0 +1 @@
uid://c33061yx51h5s

View file

@ -34,7 +34,7 @@ func _initialize() -> void:
game_state.transporters.clear()
game_state.rocks = 900
game_state.fleet_cargo = 0
game_state.ships_owed = 0
game_state.vessels_owed.clear()
game_state.unlocked = ["shipyards", "logistics", "freight"]
scene = load("res://Main.tscn").instantiate()
root.add_child(scene)

View file

@ -50,7 +50,7 @@ func _initialize() -> void:
game_state.extractors.clear()
game_state.rocks = 40
game_state.fleet_cargo = 0
game_state.ships_owed = 0
game_state.vessels_owed.clear()
game_state.unlocked = ["shipyards", "coordination", "wing", "squadron", "armada"]
scene = load("res://Main.tscn").instantiate()
root.add_child(scene)

View file

@ -56,7 +56,7 @@ func _initialize() -> void:
game_state.transporters.clear()
game_state.rocks = 200
game_state.fleet_cargo = 0
game_state.ships_owed = 0
game_state.vessels_owed.clear()
game_state.unlocked = ["shipyards", "logistics", "freight", "coordination", "wing", "squadron", "armada"]
scene = load("res://Main.tscn").instantiate()
root.add_child(scene)