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 Node2D
|
|
|
|
|
|
|
|
|
|
# Preview, not a test. A transporter mid-run between the mothership and a
|
|
|
|
|
# building it is supplying, so the #19 vessel can actually be looked at
|
|
|
|
|
# alongside the hub that stations it. Headless draws no pixels.
|
|
|
|
|
#
|
|
|
|
|
# bash tests/screenshot.sh res://tests/_transporter_preview.tscn /tmp/t.png 25 1280x720
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func _ready() -> void:
|
|
|
|
|
GameState.buildings.clear()
|
|
|
|
|
GameState.extractors.clear()
|
|
|
|
|
GameState.transporters.clear()
|
|
|
|
|
GameState.rocks = 200
|
|
|
|
|
GameState.add_building(GameState.BUILDING_MOTHERSHIP, Vector2(-420.0, 0.0))
|
|
|
|
|
GameState.add_building(GameState.BUILDING_TRANSPORT_HUB, Vector2(420.0, 0.0))
|
|
|
|
|
|
2026-08-15 00:09:10 +02:00
|
|
|
# The hub already provisioned these two. Put one laden mid-leg and one on
|
|
|
|
|
# its way home empty so both visual states show.
|
|
|
|
|
var laden: Dictionary = GameState.transporters[0]
|
|
|
|
|
laden.state = GameState.TRANSPORTER_TO_BUILDING
|
|
|
|
|
laden.target_id = 2
|
|
|
|
|
laden.carrying = 8
|
|
|
|
|
laden.progress = 0.45
|
|
|
|
|
laden.from = Vector2(-420.0, 0.0)
|
|
|
|
|
laden.to = Vector2(420.0, 0.0)
|
|
|
|
|
var returning: Dictionary = GameState.transporters[1]
|
|
|
|
|
returning.state = GameState.TRANSPORTER_RETURNING
|
|
|
|
|
returning.progress = 0.5
|
|
|
|
|
returning.from = Vector2(-380.0, 150.0)
|
|
|
|
|
returning.to = Vector2(420.0, 150.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
|
|
|
|
#84: move 215 root files into a folder hierarchy
Everything lived in one flat directory, so a diff gave no clue what area it
touched and finding the file you wanted meant knowing its exact name. Twelve
folders now, grouped by what a thing IS rather than what type it is - a
vessel's definition, its component scenes and its upgrade resources sit
together, because that is the set you read when you change one of them.
buildings core controllers enemies logistics planets
resources shaders surface ui vessels vfx world
332 files moved and every res:// reference rewritten - 306 files touched,
including the autoload and main-scene paths in project.godot. Nothing renamed:
this is purely where files sit, so the diff is a pile of pure moves and no
behaviour is buried in it. ui_theme.tres, icon.svg and web_shell.html stay at
the root, where Godot and the export preset expect them.
Verified three ways, because a suite alone would not have caught all of it:
the full 117 pass, the web export builds clean, and the game renders.
The export is why that matters. The FIRST export after the move failed with
"Attempt to open script 'res://GameState.gd'" - the old path - while
project.godot on disk plainly said res://core/GameState.gd. That is this
project's documented Android FUSE mtime trap: Godot served a cached copy of a
file whose content had changed. A `touch` fixed it. Nothing in the test suite
would have found that, because the suite runs from a copy on a native
filesystem - the one place the bug cannot happen.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-21 19:44:14 +02:00
|
|
|
var main: Node = load("res://world/Main.tscn").instantiate()
|
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
|
|
|
add_child(main)
|
|
|
|
|
main.get_node("AsteroidField").set_process(false)
|
|
|
|
|
main.get_node("EnemySpawner").set_process(false)
|
|
|
|
|
# Freeze the simulation so the vessels stay where they were placed.
|
|
|
|
|
GameState.set_process(false)
|
|
|
|
|
main.get_node("Fleet").move_to(Vector2(0.0, 260.0))
|
|
|
|
|
var cam: Camera2D = main.get_node("Camera2D")
|
|
|
|
|
cam.zoom = Vector2(0.85, 0.85)
|