Transporter vessels, an explicit store button, and bottom-anchored menus
Forgejo #19, part 6 of #12. Transporters are built at the ship crafter,
fly themselves to the nearest hub and wait there. When a building is
short of what its queue needs, the nearest idle transporter runs
hub -> mothership -> building -> hub. Ore leaves the bank when it is
loaded and lands in the building's stock on arrival, so what is drawn
and what happens are the same event - the extractor hauler's rule.
Production orders are now TYPED (interceptor / transporter) rather than
a bare count, since the crafter builds two different things. One at a
time is dispatched per building: without that, every idle transporter
chases the same shortfall and they all arrive carrying ore nobody needs.
Three fixes from play-testing feedback:
- Storing ore into a building is now a deliberate button press, not a
side effect of opening the menu.
- The mothership's load-ore controls were positioned from the TOP of the
screen, so on any viewport shorter than ~1300px the label fell off the
bottom. They are anchored to the bottom edge now, and the label had no
explicit font size so it inherited the theme's 78px and wrapped off
screen. Checked at 720x960 and 720x1280.
- The craft button looked live and did nothing. It was not the transport
work: BASE_FLEET_SIZE is 5 and a new game starts with exactly 5 ships,
so the fleet is at its cap from the first frame and every interceptor
order was refused. The button is now visibly disabled and says why.
The underlying balance (crafter useless until Wing Doctrine) is left
alone - that is a design call, not a bug to quietly change.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-11 19:14:27 +02:00
|
|
|
extends SceneTree
|
|
|
|
|
|
Build the logistics crews, and let them burn energy
#216: transport hubs and spacial workshops no longer conjure their crews.
Transporters and repair drones are ordered at a ship crafter, assigned per
building through a new Station menu, flown out from the mothership hangar,
and spent by the work they do - 20 runs, 12 repairs, counted where the run
ENDS so nothing retires with cargo in the air or a building half repaired.
A spent vessel is gone, so the structure is short again and the player has
to build another. The menu shows what each one has left, worst first.
Craftability needed its own flag: "the crafter can make it" and "it can take
a berth in the fleet" stopped being the same question.
#217: transporters crawl at 120 rather than 150, and a Burn Drive lets them
carry energy and spend it to travel far faster. Fetching it is a leg of its
own, to the nearest store that has any - so a refuelling transporter cannot
be dispatched mid-errand - and the leg flown to COLLECT fuel is not charged
for it. Unresearched, nothing detours and nothing changes.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019AJMdB7iuHuLFZM1aBu3GD
2026-09-05 19:09:35 +02:00
|
|
|
# Forgejo #216: a transport hub used to conjure its own transporters, free and
|
|
|
|
|
# permanent. They are built at a ship crafter now, flown out from the
|
|
|
|
|
# mothership hangar to whichever hub asked for them, and worn out by the runs
|
|
|
|
|
# they make.
|
|
|
|
|
#
|
|
|
|
|
# Covers:
|
|
|
|
|
# A. a new hub stands empty - nothing is provisioned with the structure
|
|
|
|
|
# B. the crafter accepts a transporter order, which it used to refuse
|
|
|
|
|
# C. one assigned and one in the hangar puts it at the hub, and a hub that
|
|
|
|
|
# was asked for nothing stays empty however many are sitting there
|
|
|
|
|
# D. the transporter then does the job the old free ones did: it supplies a
|
|
|
|
|
# queued order, without ore being created or destroyed
|
|
|
|
|
# E. it wears out, and the spent vessel is gone rather than returned
|
Transporter vessels, an explicit store button, and bottom-anchored menus
Forgejo #19, part 6 of #12. Transporters are built at the ship crafter,
fly themselves to the nearest hub and wait there. When a building is
short of what its queue needs, the nearest idle transporter runs
hub -> mothership -> building -> hub. Ore leaves the bank when it is
loaded and lands in the building's stock on arrival, so what is drawn
and what happens are the same event - the extractor hauler's rule.
Production orders are now TYPED (interceptor / transporter) rather than
a bare count, since the crafter builds two different things. One at a
time is dispatched per building: without that, every idle transporter
chases the same shortfall and they all arrive carrying ore nobody needs.
Three fixes from play-testing feedback:
- Storing ore into a building is now a deliberate button press, not a
side effect of opening the menu.
- The mothership's load-ore controls were positioned from the TOP of the
screen, so on any viewport shorter than ~1300px the label fell off the
bottom. They are anchored to the bottom edge now, and the label had no
explicit font size so it inherited the theme's 78px and wrapped off
screen. Checked at 720x960 and 720x1280.
- The craft button looked live and did nothing. It was not the transport
work: BASE_FLEET_SIZE is 5 and a new game starts with exactly 5 ships,
so the fleet is at its cap from the first frame and every interceptor
order was refused. The button is now visibly disabled and says why.
The underlying balance (crafter useless until Wing Doctrine) is left
alone - that is a design call, not a bug to quietly change.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-11 19:14:27 +02:00
|
|
|
|
2026-08-15 00:09:10 +02:00
|
|
|
var state: Node
|
|
|
|
|
var crafter_id: int
|
Build the logistics crews, and let them burn energy
#216: transport hubs and spacial workshops no longer conjure their crews.
Transporters and repair drones are ordered at a ship crafter, assigned per
building through a new Station menu, flown out from the mothership hangar,
and spent by the work they do - 20 runs, 12 repairs, counted where the run
ENDS so nothing retires with cargo in the air or a building half repaired.
A spent vessel is gone, so the structure is short again and the player has
to build another. The menu shows what each one has left, worst first.
Craftability needed its own flag: "the crafter can make it" and "it can take
a berth in the fleet" stopped being the same question.
#217: transporters crawl at 120 rather than 150, and a Burn Drive lets them
carry energy and spend it to travel far faster. Fetching it is a leg of its
own, to the nearest store that has any - so a refuelling transporter cannot
be dispatched mid-errand - and the leg flown to COLLECT fuel is not charged
for it. Unresearched, nothing detours and nothing changes.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019AJMdB7iuHuLFZM1aBu3GD
2026-09-05 19:09:35 +02:00
|
|
|
var hub_id: int
|
2026-08-15 00:09:10 +02:00
|
|
|
var total_at_start: int
|
|
|
|
|
var consumed: int = 0
|
Transporter vessels, an explicit store button, and bottom-anchored menus
Forgejo #19, part 6 of #12. Transporters are built at the ship crafter,
fly themselves to the nearest hub and wait there. When a building is
short of what its queue needs, the nearest idle transporter runs
hub -> mothership -> building -> hub. Ore leaves the bank when it is
loaded and lands in the building's stock on arrival, so what is drawn
and what happens are the same event - the extractor hauler's rule.
Production orders are now TYPED (interceptor / transporter) rather than
a bare count, since the crafter builds two different things. One at a
time is dispatched per building: without that, every idle transporter
chases the same shortfall and they all arrive carrying ore nobody needs.
Three fixes from play-testing feedback:
- Storing ore into a building is now a deliberate button press, not a
side effect of opening the menu.
- The mothership's load-ore controls were positioned from the TOP of the
screen, so on any viewport shorter than ~1300px the label fell off the
bottom. They are anchored to the bottom edge now, and the label had no
explicit font size so it inherited the theme's 78px and wrapped off
screen. Checked at 720x960 and 720x1280.
- The craft button looked live and did nothing. It was not the transport
work: BASE_FLEET_SIZE is 5 and a new game starts with exactly 5 ships,
so the fleet is at its cap from the first frame and every interceptor
order was refused. The button is now visibly disabled and says why.
The underlying balance (crafter useless until Wing Doctrine) is left
alone - that is a design call, not a bug to quietly change.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-11 19:14:27 +02:00
|
|
|
var elapsed: float = 0.0
|
Build the logistics crews, and let them burn energy
#216: transport hubs and spacial workshops no longer conjure their crews.
Transporters and repair drones are ordered at a ship crafter, assigned per
building through a new Station menu, flown out from the mothership hangar,
and spent by the work they do - 20 runs, 12 repairs, counted where the run
ENDS so nothing retires with cargo in the air or a building half repaired.
A spent vessel is gone, so the structure is short again and the player has
to build another. The menu shows what each one has left, worst first.
Craftability needed its own flag: "the crafter can make it" and "it can take
a berth in the fleet" stopped being the same question.
#217: transporters crawl at 120 rather than 150, and a Burn Drive lets them
carry energy and spend it to travel far faster. Fetching it is a leg of its
own, to the nearest store that has any - so a refuelling transporter cannot
be dispatched mid-errand - and the leg flown to COLLECT fuel is not charged
for it. Unresearched, nothing detours and nothing changes.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019AJMdB7iuHuLFZM1aBu3GD
2026-09-05 19:09:35 +02:00
|
|
|
var stage: int = 0
|
Transporter vessels, an explicit store button, and bottom-anchored menus
Forgejo #19, part 6 of #12. Transporters are built at the ship crafter,
fly themselves to the nearest hub and wait there. When a building is
short of what its queue needs, the nearest idle transporter runs
hub -> mothership -> building -> hub. Ore leaves the bank when it is
loaded and lands in the building's stock on arrival, so what is drawn
and what happens are the same event - the extractor hauler's rule.
Production orders are now TYPED (interceptor / transporter) rather than
a bare count, since the crafter builds two different things. One at a
time is dispatched per building: without that, every idle transporter
chases the same shortfall and they all arrive carrying ore nobody needs.
Three fixes from play-testing feedback:
- Storing ore into a building is now a deliberate button press, not a
side effect of opening the menu.
- The mothership's load-ore controls were positioned from the TOP of the
screen, so on any viewport shorter than ~1300px the label fell off the
bottom. They are anchored to the bottom edge now, and the label had no
explicit font size so it inherited the theme's 78px and wrapped off
screen. Checked at 720x960 and 720x1280.
- The craft button looked live and did nothing. It was not the transport
work: BASE_FLEET_SIZE is 5 and a new game starts with exactly 5 ships,
so the fleet is at its cap from the first frame and every interceptor
order was refused. The button is now visibly disabled and says why.
The underlying balance (crafter useless until Wing Doctrine) is left
alone - that is a design call, not a bug to quietly change.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-11 19:14:27 +02:00
|
|
|
var conservation_broken: bool = false
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func _initialize() -> void:
|
2026-08-15 00:09:10 +02:00
|
|
|
state = root.get_node("GameState")
|
|
|
|
|
state.buildings.clear()
|
|
|
|
|
state.extractors.clear()
|
|
|
|
|
state.transporters.clear()
|
|
|
|
|
state.stored_vessels.clear()
|
|
|
|
|
state.vessel_deliveries.clear()
|
|
|
|
|
state.reset_progression()
|
Build the logistics crews, and let them burn energy
#216: transport hubs and spacial workshops no longer conjure their crews.
Transporters and repair drones are ordered at a ship crafter, assigned per
building through a new Station menu, flown out from the mothership hangar,
and spent by the work they do - 20 runs, 12 repairs, counted where the run
ENDS so nothing retires with cargo in the air or a building half repaired.
A spent vessel is gone, so the structure is short again and the player has
to build another. The menu shows what each one has left, worst first.
Craftability needed its own flag: "the crafter can make it" and "it can take
a berth in the fleet" stopped being the same question.
#217: transporters crawl at 120 rather than 150, and a Burn Drive lets them
carry energy and spend it to travel far faster. Fetching it is a leg of its
own, to the nearest store that has any - so a refuelling transporter cannot
be dispatched mid-errand - and the leg flown to COLLECT fuel is not charged
for it. Unresearched, nothing detours and nothing changes.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019AJMdB7iuHuLFZM1aBu3GD
2026-09-05 19:09:35 +02:00
|
|
|
state.rocks = 400
|
2026-08-15 00:09:10 +02:00
|
|
|
state.build_time_scale = 0.02
|
|
|
|
|
state.unlocked = ["shipyards", "logistics", "freight"]
|
|
|
|
|
state.add_building(state.BUILDING_MOTHERSHIP, Vector2.ZERO)
|
|
|
|
|
crafter_id = state.add_building(state.BUILDING_SHIP_CRAFTER, Vector2(900, -300))
|
Build the logistics crews, and let them burn energy
#216: transport hubs and spacial workshops no longer conjure their crews.
Transporters and repair drones are ordered at a ship crafter, assigned per
building through a new Station menu, flown out from the mothership hangar,
and spent by the work they do - 20 runs, 12 repairs, counted where the run
ENDS so nothing retires with cargo in the air or a building half repaired.
A spent vessel is gone, so the structure is short again and the player has
to build another. The menu shows what each one has left, worst first.
Craftability needed its own flag: "the crafter can make it" and "it can take
a berth in the fleet" stopped being the same question.
#217: transporters crawl at 120 rather than 150, and a Burn Drive lets them
carry energy and spend it to travel far faster. Fetching it is a leg of its
own, to the nearest store that has any - so a refuelling transporter cannot
be dispatched mid-errand - and the leg flown to COLLECT fuel is not charged
for it. Unresearched, nothing detours and nothing changes.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019AJMdB7iuHuLFZM1aBu3GD
2026-09-05 19:09:35 +02:00
|
|
|
hub_id = state.add_building(state.BUILDING_TRANSPORT_HUB, Vector2(600, 200))
|
Transporter vessels, an explicit store button, and bottom-anchored menus
Forgejo #19, part 6 of #12. Transporters are built at the ship crafter,
fly themselves to the nearest hub and wait there. When a building is
short of what its queue needs, the nearest idle transporter runs
hub -> mothership -> building -> hub. Ore leaves the bank when it is
loaded and lands in the building's stock on arrival, so what is drawn
and what happens are the same event - the extractor hauler's rule.
Production orders are now TYPED (interceptor / transporter) rather than
a bare count, since the crafter builds two different things. One at a
time is dispatched per building: without that, every idle transporter
chases the same shortfall and they all arrive carrying ore nobody needs.
Three fixes from play-testing feedback:
- Storing ore into a building is now a deliberate button press, not a
side effect of opening the menu.
- The mothership's load-ore controls were positioned from the TOP of the
screen, so on any viewport shorter than ~1300px the label fell off the
bottom. They are anchored to the bottom edge now, and the label had no
explicit font size so it inherited the theme's 78px and wrapped off
screen. Checked at 720x960 and 720x1280.
- The craft button looked live and did nothing. It was not the transport
work: BASE_FLEET_SIZE is 5 and a new game starts with exactly 5 ships,
so the fleet is at its cap from the first frame and every interceptor
order was refused. The button is now visibly disabled and says why.
The underlying balance (crafter useless until Wing Doctrine) is left
alone - that is a design call, not a bug to quietly change.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-11 19:14:27 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
func _process(delta: float) -> bool:
|
|
|
|
|
elapsed += delta
|
Build the logistics crews, and let them burn energy
#216: transport hubs and spacial workshops no longer conjure their crews.
Transporters and repair drones are ordered at a ship crafter, assigned per
building through a new Station menu, flown out from the mothership hangar,
and spent by the work they do - 20 runs, 12 repairs, counted where the run
ENDS so nothing retires with cargo in the air or a building half repaired.
A spent vessel is gone, so the structure is short again and the player has
to build another. The menu shows what each one has left, worst first.
Craftability needed its own flag: "the crafter can make it" and "it can take
a berth in the fleet" stopped being the same question.
#217: transporters crawl at 120 rather than 150, and a Burn Drive lets them
carry energy and spend it to travel far faster. Fetching it is a leg of its
own, to the nearest store that has any - so a refuelling transporter cannot
be dispatched mid-errand - and the leg flown to COLLECT fuel is not charged
for it. Unresearched, nothing detours and nothing changes.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019AJMdB7iuHuLFZM1aBu3GD
2026-09-05 19:09:35 +02:00
|
|
|
match stage:
|
|
|
|
|
0:
|
|
|
|
|
# --- A. nothing comes with the structure ---------------------
|
|
|
|
|
if not state.transporters.is_empty():
|
|
|
|
|
return _fail("a new hub arrived with %d transporters" % state.transporters.size())
|
|
|
|
|
if state.station_desired(hub_id) != 0:
|
|
|
|
|
return _fail("a new hub already had a crew ordered")
|
|
|
|
|
print("a new hub stands empty")
|
|
|
|
|
|
|
|
|
|
# --- B. the crafter takes the order --------------------------
|
|
|
|
|
if not state.queue_order(crafter_id, state.VESSEL_TRANSPORTER):
|
|
|
|
|
return _fail("the crafter refused a transporter order")
|
|
|
|
|
state.find_building(crafter_id).orders.clear()
|
|
|
|
|
|
|
|
|
|
# --- C. assigned, and only then sent -------------------------
|
|
|
|
|
# One in the hangar and nothing asked for: it must stay there.
|
|
|
|
|
state.stored_vessels.append(state.VESSEL_TRANSPORTER)
|
|
|
|
|
state._advance_station_dispatch()
|
|
|
|
|
if not state.transporters.is_empty():
|
|
|
|
|
return _fail("a hub that asked for nothing took a transporter anyway")
|
|
|
|
|
if state.set_station_desired(hub_id, 1) != 1:
|
|
|
|
|
return _fail("the hub refused an order for one transporter")
|
|
|
|
|
state._advance_station_dispatch()
|
|
|
|
|
if state.stored_vessels.has(state.VESSEL_TRANSPORTER):
|
|
|
|
|
return _fail("the assigned transporter never left the hangar")
|
|
|
|
|
if state.vessel_deliveries.is_empty():
|
|
|
|
|
return _fail("nothing was sent to the hub")
|
|
|
|
|
elapsed = 0.0
|
|
|
|
|
stage = 1
|
|
|
|
|
return false
|
|
|
|
|
1:
|
|
|
|
|
if state.station_crew(hub_id) < 1:
|
|
|
|
|
if elapsed > 25.0:
|
|
|
|
|
return _fail("the transporter never reached the hub")
|
|
|
|
|
return false
|
|
|
|
|
var condition: Array = state.station_condition(hub_id)
|
|
|
|
|
if condition.size() != 1 or int(condition[0]) != GameState.TRANSPORTER_TRIPS:
|
|
|
|
|
return _fail("the arrived transporter reports %s trips, expected [%d]" \
|
|
|
|
|
% [condition, GameState.TRANSPORTER_TRIPS])
|
|
|
|
|
print("ordered, built and flown out: 1 at the hub with %d runs in it" \
|
|
|
|
|
% GameState.TRANSPORTER_TRIPS)
|
|
|
|
|
|
|
|
|
|
# --- D. and it does the work ---------------------------------
|
|
|
|
|
if not state.queue_order(crafter_id, state.PRODUCT_SHIP):
|
|
|
|
|
return _fail("crafter refused the combat-vessel order")
|
|
|
|
|
state.order_completed.connect(_on_order_completed)
|
|
|
|
|
total_at_start = _total()
|
|
|
|
|
elapsed = 0.0
|
|
|
|
|
stage = 2
|
|
|
|
|
return false
|
|
|
|
|
2:
|
|
|
|
|
if _total() + consumed != total_at_start:
|
|
|
|
|
conservation_broken = true
|
|
|
|
|
if state.pending_orders(crafter_id) > 0:
|
|
|
|
|
if elapsed > 25.0:
|
|
|
|
|
return _fail("the hub's transporter never supplied the queued order")
|
|
|
|
|
return false
|
|
|
|
|
if conservation_broken:
|
|
|
|
|
return _fail("ore was created or destroyed on the automatic route")
|
|
|
|
|
print("the hub's own transporter supplied the crafter")
|
|
|
|
|
|
|
|
|
|
elapsed = 0.0
|
|
|
|
|
stage = 3
|
|
|
|
|
return false
|
|
|
|
|
3:
|
|
|
|
|
# --- E. and it is used up by doing so ------------------------
|
|
|
|
|
# The run is spent when it gets HOME, not when the cargo lands, so
|
|
|
|
|
# this waits for the transporter to be idle at its hub again -
|
|
|
|
|
# which is also the rule that stops a vessel retiring with its
|
|
|
|
|
# cargo still in the air.
|
|
|
|
|
if state.transporters.is_empty():
|
|
|
|
|
return _fail("the transporter vanished before completing its run")
|
|
|
|
|
if String(state.transporters[0].state) != state.TRANSPORTER_IDLE:
|
|
|
|
|
if elapsed > 25.0:
|
|
|
|
|
return _fail("the transporter never got home")
|
|
|
|
|
return false
|
|
|
|
|
var worn: Array = state.station_condition(hub_id)
|
|
|
|
|
if worn.is_empty() or int(worn[0]) >= GameState.TRANSPORTER_TRIPS:
|
|
|
|
|
return _fail("a transporter that ran a supply route is still unworn (%s)" % [worn])
|
|
|
|
|
print("a completed run wore it to %d" % int(worn[0]))
|
|
|
|
|
# Wound down to its last run, so the next arrival home retires it.
|
|
|
|
|
state.transporters[0].trips_left = 1
|
|
|
|
|
elapsed = 0.0
|
|
|
|
|
stage = 4
|
|
|
|
|
return false
|
|
|
|
|
4:
|
|
|
|
|
if not state.transporters.is_empty():
|
|
|
|
|
if elapsed > 30.0:
|
|
|
|
|
return _fail("a transporter on its last run was never retired")
|
|
|
|
|
# Keep it working: an idle one at its hub never completes
|
|
|
|
|
# another leg, and it is the arrival home that spends the run.
|
|
|
|
|
state.deposit_resource_to_building(crafter_id, GameState.RESOURCE_ORE, 0)
|
|
|
|
|
state.queue_order(crafter_id, state.PRODUCT_SHIP)
|
|
|
|
|
return false
|
|
|
|
|
if state.stored_vessels.has(state.VESSEL_TRANSPORTER):
|
|
|
|
|
return _fail("a spent transporter went back to the hangar instead of being used up")
|
|
|
|
|
if state.station_crew(hub_id) != 0:
|
|
|
|
|
return _fail("the hub still counts a retired transporter")
|
|
|
|
|
print("spent after its last run: gone, and the hub is short again")
|
|
|
|
|
print("TEST_TRANSPORTER_SUPPLY: PASS")
|
|
|
|
|
quit(0)
|
|
|
|
|
return true
|
|
|
|
|
return false
|
Transporter vessels, an explicit store button, and bottom-anchored menus
Forgejo #19, part 6 of #12. Transporters are built at the ship crafter,
fly themselves to the nearest hub and wait there. When a building is
short of what its queue needs, the nearest idle transporter runs
hub -> mothership -> building -> hub. Ore leaves the bank when it is
loaded and lands in the building's stock on arrival, so what is drawn
and what happens are the same event - the extractor hauler's rule.
Production orders are now TYPED (interceptor / transporter) rather than
a bare count, since the crafter builds two different things. One at a
time is dispatched per building: without that, every idle transporter
chases the same shortfall and they all arrive carrying ore nobody needs.
Three fixes from play-testing feedback:
- Storing ore into a building is now a deliberate button press, not a
side effect of opening the menu.
- The mothership's load-ore controls were positioned from the TOP of the
screen, so on any viewport shorter than ~1300px the label fell off the
bottom. They are anchored to the bottom edge now, and the label had no
explicit font size so it inherited the theme's 78px and wrapped off
screen. Checked at 720x960 and 720x1280.
- The craft button looked live and did nothing. It was not the transport
work: BASE_FLEET_SIZE is 5 and a new game starts with exactly 5 ships,
so the fleet is at its cap from the first frame and every interceptor
order was refused. The button is now visibly disabled and says why.
The underlying balance (crafter useless until Wing Doctrine) is left
alone - that is a design call, not a bug to quietly change.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-11 19:14:27 +02:00
|
|
|
|
|
|
|
|
|
2026-08-15 00:09:10 +02:00
|
|
|
func _on_order_completed(_building_id: int, product: String) -> void:
|
|
|
|
|
consumed += state.product_cost(product)
|
Transporter vessels, an explicit store button, and bottom-anchored menus
Forgejo #19, part 6 of #12. Transporters are built at the ship crafter,
fly themselves to the nearest hub and wait there. When a building is
short of what its queue needs, the nearest idle transporter runs
hub -> mothership -> building -> hub. Ore leaves the bank when it is
loaded and lands in the building's stock on arrival, so what is drawn
and what happens are the same event - the extractor hauler's rule.
Production orders are now TYPED (interceptor / transporter) rather than
a bare count, since the crafter builds two different things. One at a
time is dispatched per building: without that, every idle transporter
chases the same shortfall and they all arrive carrying ore nobody needs.
Three fixes from play-testing feedback:
- Storing ore into a building is now a deliberate button press, not a
side effect of opening the menu.
- The mothership's load-ore controls were positioned from the TOP of the
screen, so on any viewport shorter than ~1300px the label fell off the
bottom. They are anchored to the bottom edge now, and the label had no
explicit font size so it inherited the theme's 78px and wrapped off
screen. Checked at 720x960 and 720x1280.
- The craft button looked live and did nothing. It was not the transport
work: BASE_FLEET_SIZE is 5 and a new game starts with exactly 5 ships,
so the fleet is at its cap from the first frame and every interceptor
order was refused. The button is now visibly disabled and says why.
The underlying balance (crafter useless until Wing Doctrine) is left
alone - that is a design call, not a bug to quietly change.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-11 19:14:27 +02:00
|
|
|
|
|
|
|
|
|
Build the logistics crews, and let them burn energy
#216: transport hubs and spacial workshops no longer conjure their crews.
Transporters and repair drones are ordered at a ship crafter, assigned per
building through a new Station menu, flown out from the mothership hangar,
and spent by the work they do - 20 runs, 12 repairs, counted where the run
ENDS so nothing retires with cargo in the air or a building half repaired.
A spent vessel is gone, so the structure is short again and the player has
to build another. The menu shows what each one has left, worst first.
Craftability needed its own flag: "the crafter can make it" and "it can take
a berth in the fleet" stopped being the same question.
#217: transporters crawl at 120 rather than 150, and a Burn Drive lets them
carry energy and spend it to travel far faster. Fetching it is a leg of its
own, to the nearest store that has any - so a refuelling transporter cannot
be dispatched mid-errand - and the leg flown to COLLECT fuel is not charged
for it. Unresearched, nothing detours and nothing changes.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019AJMdB7iuHuLFZM1aBu3GD
2026-09-05 19:09:35 +02:00
|
|
|
# Every place a rock can be while the route runs: the bank (the mothership's
|
|
|
|
|
# own store IS state.rocks, so counting the building too would double it), a
|
|
|
|
|
# building's local store, an order that has started and taken its cost, and a
|
|
|
|
|
# transporter's hold in mid-flight.
|
2026-08-15 00:09:10 +02:00
|
|
|
func _total() -> int:
|
|
|
|
|
var sum: int = state.rocks + state.fleet_cargo
|
|
|
|
|
for building in state.buildings:
|
|
|
|
|
if building.type != state.BUILDING_MOTHERSHIP:
|
|
|
|
|
sum += state.building_resource(int(building.id), state.RESOURCE_ORE)
|
|
|
|
|
for order in building.get("orders", []):
|
|
|
|
|
if bool(order.started):
|
|
|
|
|
sum += state.product_cost(String(order.product))
|
|
|
|
|
for transporter in state.transporters:
|
|
|
|
|
sum += int(transporter.get("carrying", 0))
|
|
|
|
|
return sum
|
Transporter vessels, an explicit store button, and bottom-anchored menus
Forgejo #19, part 6 of #12. Transporters are built at the ship crafter,
fly themselves to the nearest hub and wait there. When a building is
short of what its queue needs, the nearest idle transporter runs
hub -> mothership -> building -> hub. Ore leaves the bank when it is
loaded and lands in the building's stock on arrival, so what is drawn
and what happens are the same event - the extractor hauler's rule.
Production orders are now TYPED (interceptor / transporter) rather than
a bare count, since the crafter builds two different things. One at a
time is dispatched per building: without that, every idle transporter
chases the same shortfall and they all arrive carrying ore nobody needs.
Three fixes from play-testing feedback:
- Storing ore into a building is now a deliberate button press, not a
side effect of opening the menu.
- The mothership's load-ore controls were positioned from the TOP of the
screen, so on any viewport shorter than ~1300px the label fell off the
bottom. They are anchored to the bottom edge now, and the label had no
explicit font size so it inherited the theme's 78px and wrapped off
screen. Checked at 720x960 and 720x1280.
- The craft button looked live and did nothing. It was not the transport
work: BASE_FLEET_SIZE is 5 and a new game starts with exactly 5 ships,
so the fleet is at its cap from the first frame and every interceptor
order was refused. The button is now visibly disabled and says why.
The underlying balance (crafter useless until Wing Doctrine) is left
alone - that is a design call, not a bug to quietly change.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-11 19:14:27 +02:00
|
|
|
|
|
|
|
|
|
2026-08-15 00:09:10 +02:00
|
|
|
func _fail(message: String) -> bool:
|
|
|
|
|
print("TEST_TRANSPORTER_SUPPLY: FAIL (%s)" % message)
|
|
|
|
|
quit(1)
|
|
|
|
|
return true
|