Initial commit: SpaceshipTest, a top-down space RTS in Godot 4.7.1

A fleet of neon-outlined ships explores a procedurally generated, seeded
infinite world: tap/joystick steering, pinch zoom, formation pivoting,
planet landings, an ore economy with extractors and haulers, and player
built structures (mothership, ship crafter, command centre).

All art is hand-drawn with draw_* calls rather than textures, and the
backgrounds are camera-relative shaders so they stay precise at large
world coordinates.

Includes a 35-test headless suite (tests/run_tests.sh) plus screenshot
tooling that renders real frames through Xvfb and Mesa softpipe, since
--headless has no GPU.

Excluded from version control: .godot/ (import cache, and it holds
export credentials), builds/, android/build/ and packaged APKs - all
regenerable, and ~325 MB combined.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Loïc Wisniewski 2026-08-10 18:41:58 +02:00
commit 85814ce88c
192 changed files with 9602 additions and 0 deletions

698
Main.tscn Normal file
View file

@ -0,0 +1,698 @@
[gd_scene load_steps=20 format=3]
[ext_resource type="Script" path="res://Starfield.gd" id="1"]
[ext_resource type="Script" path="res://Fleet.gd" id="2"]
[ext_resource type="Script" path="res://GameController.gd" id="3"]
[ext_resource type="Script" path="res://EnemySpawner.gd" id="4"]
[ext_resource type="Shader" path="res://starfield.gdshader" id="5"]
[ext_resource type="Script" path="res://ExplorationTracker.gd" id="6"]
[ext_resource type="Script" path="res://AsteroidField.gd" id="7"]
[ext_resource type="Script" path="res://WorldMap.gd" id="8"]
[ext_resource type="Script" path="res://WorldMapContent.gd" id="9"]
[ext_resource type="Script" path="res://IconButton.gd" id="10"]
[ext_resource type="Script" path="res://PlanetField.gd" id="11"]
[ext_resource type="Script" path="res://PlanetAtmosphereController.gd" id="12"]
[ext_resource type="Script" path="res://TouchJoystick.gd" id="13"]
[ext_resource type="Script" path="res://BuildingField.gd" id="14"]
[ext_resource type="Script" path="res://BuildController.gd" id="15"]
[ext_resource type="Script" path="res://ResourceCounter.gd" id="16"]
[ext_resource type="Script" path="res://FormationEditor.gd" id="17"]
[ext_resource type="Script" path="res://HaulerField.gd" id="18"]
[ext_resource type="Script" path="res://NeonNumber.gd" id="19"]
[ext_resource type="Script" path="res://NeonPanel.gd" id="20"]
[sub_resource type="ShaderMaterial" id="1"]
shader = ExtResource("5")
shader_parameter/camera_pos = Vector2(0, 0)
shader_parameter/camera_zoom = 1.0
shader_parameter/viewport_size = Vector2(720, 1280)
shader_parameter/cell_size = 60.0
shader_parameter/bg_color = Color(0.02, 0.02, 0.08, 1)
[node name="Main" type="Node2D"]
script = ExtResource("3")
[node name="BackgroundLayer" type="CanvasLayer" parent="."]
layer = -10
[node name="Starfield" type="ColorRect" parent="BackgroundLayer"]
material = SubResource("1")
mouse_filter = 2
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
script = ExtResource("1")
[node name="Fleet" type="Node2D" parent="."]
script = ExtResource("2")
[node name="Camera2D" type="Camera2D" parent="."]
position = Vector2(0, 0)
zoom = Vector2(1, 1)
[node name="EnemySpawner" type="Node2D" parent="."]
script = ExtResource("4")
[node name="ExplorationTracker" type="Node2D" parent="."]
script = ExtResource("6")
[node name="AsteroidField" type="Node2D" parent="."]
script = ExtResource("7")
[node name="PlanetField" type="Node2D" parent="."]
script = ExtResource("11")
[node name="BuildingField" type="Node2D" parent="."]
script = ExtResource("14")
[node name="HaulerField" type="Node2D" parent="."]
script = ExtResource("18")
[node name="BuildController" type="Node2D" parent="."]
script = ExtResource("15")
[node name="LandingController" type="Node2D" parent="."]
script = ExtResource("12")
[node name="UI" type="CanvasLayer" parent="."]
layer = 1
[node name="ResourceCounter" type="Control" parent="UI"]
mouse_filter = 2
offset_left = 28
offset_top = 24
offset_right = 520
offset_bottom = 140
script = ExtResource("16")
digit_height = 100.0
[node name="PlanetNameLabel" type="Label" parent="UI"]
visible = false
offset_left = 24
offset_top = 156
offset_right = 696
offset_bottom = 282
text = ""
horizontal_alignment = 1
[node name="EnterAtmosphereButton" type="Control" parent="UI"]
visible = false
anchor_top = 1.0
anchor_bottom = 1.0
offset_left = 24
offset_right = 172
offset_top = -720
offset_bottom = -572
script = ExtResource("10")
icon = 3
[node name="BuildButton" type="Control" parent="UI"]
anchor_top = 1.0
anchor_bottom = 1.0
offset_left = 24
offset_right = 172
offset_top = -890
offset_bottom = -742
script = ExtResource("10")
icon = 5
[node name="BuildActionButton" type="Control" parent="UI"]
visible = false
anchor_top = 1.0
anchor_bottom = 1.0
offset_left = 24
offset_right = 172
offset_top = -720
offset_bottom = -572
script = ExtResource("10")
icon = 2
[node name="BuildActionLabel" type="Label" parent="UI"]
visible = false
mouse_filter = 2
anchor_top = 1.0
anchor_bottom = 1.0
anchor_right = 1.0
offset_left = 24
offset_right = -24
offset_top = -566
offset_bottom = -440
text = ""
horizontal_alignment = 2
[node name="MapButton" type="Control" parent="UI"]
anchor_left = 1.0
anchor_right = 1.0
offset_left = -172
offset_right = -24
offset_top = 24
offset_bottom = 172
script = ExtResource("10")
icon = 0
[node name="KeyboardHintLabel" type="Label" parent="UI"]
visible = false
mouse_filter = 2
anchor_top = 1.0
anchor_bottom = 1.0
offset_left = 28
offset_right = 360
offset_top = -300
offset_bottom = -120
theme_override_font_sizes/font_size = 36
autowrap_mode = 2
text = "WASD / arrows move Q / E pivot wheel zoom"
[node name="Joystick" type="Control" parent="UI"]
mouse_filter = 2
anchor_top = 1.0
anchor_bottom = 1.0
offset_left = 24
offset_right = 424
offset_top = -424
offset_bottom = -24
script = ExtResource("13")
[node name="PivotCCWButton" type="Control" parent="UI"]
mouse_filter = 2
anchor_left = 1.0
anchor_right = 1.0
anchor_top = 1.0
anchor_bottom = 1.0
offset_left = -344
offset_right = -196
offset_top = -172
offset_bottom = -24
script = ExtResource("10")
icon = 7
[node name="PivotCWButton" type="Control" parent="UI"]
mouse_filter = 2
anchor_left = 1.0
anchor_right = 1.0
anchor_top = 1.0
anchor_bottom = 1.0
offset_left = -172
offset_right = -24
offset_top = -172
offset_bottom = -24
script = ExtResource("10")
icon = 6
[node name="NavLabel" type="Label" parent="UI"]
mouse_filter = 2
anchor_left = 1.0
anchor_right = 1.0
anchor_top = 1.0
anchor_bottom = 1.0
offset_left = -344
offset_right = -24
offset_top = -322
offset_bottom = -196
text = "Pivot"
horizontal_alignment = 1
[node name="WorldMap" type="Control" parent="UI"]
visible = false
anchor_right = 1.0
anchor_bottom = 1.0
script = ExtResource("8")
[node name="Backdrop" type="ColorRect" parent="UI/WorldMap"]
anchor_right = 1.0
anchor_bottom = 1.0
color = Color(0.03, 0.03, 0.08, 0.96)
[node name="MapContent" type="Node2D" parent="UI/WorldMap"]
script = ExtResource("9")
[node name="RecenterButton" type="Control" parent="UI/WorldMap"]
anchor_top = 1.0
anchor_bottom = 1.0
offset_left = 24
offset_right = 172
offset_top = -620
offset_bottom = -472
script = ExtResource("10")
icon = 2
[node name="CloseButton" type="Control" parent="UI/WorldMap"]
anchor_left = 1.0
anchor_right = 1.0
offset_left = -172
offset_right = -24
offset_top = 24
offset_bottom = 172
script = ExtResource("10")
icon = 1
[node name="BuildMenu" type="Control" parent="UI"]
visible = false
anchor_right = 1.0
anchor_bottom = 1.0
[node name="Backdrop" type="ColorRect" parent="UI/BuildMenu"]
anchor_right = 1.0
anchor_bottom = 1.0
color = Color(0.03, 0.03, 0.08, 0.94)
[node name="TitleLabel" type="Label" parent="UI/BuildMenu"]
mouse_filter = 2
anchor_right = 1.0
offset_left = 24
offset_top = 70
offset_right = -24
offset_bottom = 196
text = "Build"
horizontal_alignment = 1
[node name="StatusLabel" type="Label" parent="UI/BuildMenu"]
mouse_filter = 2
anchor_right = 1.0
offset_left = 24
offset_top = 206
offset_right = -24
offset_bottom = 330
theme_override_font_sizes/font_size = 40
autowrap_mode = 2
text = ""
horizontal_alignment = 1
[node name="MothershipButton" type="Control" parent="UI/BuildMenu"]
anchor_left = 0.5
anchor_right = 0.5
anchor_top = 0.5
anchor_bottom = 0.5
offset_left = -214
offset_right = -66
offset_top = -224
offset_bottom = -76
script = ExtResource("10")
icon = 8
glow_color = Color(0.45, 0.9, 0.55, 1)
[node name="MothershipLabel" type="Label" parent="UI/BuildMenu"]
mouse_filter = 2
anchor_left = 0.5
anchor_right = 0.5
anchor_top = 0.5
anchor_bottom = 0.5
offset_left = -290
offset_right = 10
offset_top = -70
offset_bottom = 60
theme_override_font_sizes/font_size = 44
autowrap_mode = 2
text = "Mothership"
horizontal_alignment = 1
[node name="MothershipCost" type="Control" parent="UI/BuildMenu"]
mouse_filter = 2
anchor_left = 0.5
anchor_right = 0.5
anchor_top = 0.5
anchor_bottom = 0.5
offset_left = -220
offset_right = -60
offset_top = 70
offset_bottom = 150
script = ExtResource("19")
amount = 20
digit_height = 66.0
[node name="CrafterButton" type="Control" parent="UI/BuildMenu"]
anchor_left = 0.5
anchor_right = 0.5
anchor_top = 0.5
anchor_bottom = 0.5
offset_left = 66
offset_right = 214
offset_top = -224
offset_bottom = -76
script = ExtResource("10")
icon = 9
glow_color = Color(1, 0.72, 0.25, 1)
[node name="CrafterLabel" type="Label" parent="UI/BuildMenu"]
mouse_filter = 2
anchor_left = 0.5
anchor_right = 0.5
anchor_top = 0.5
anchor_bottom = 0.5
offset_left = -10
offset_right = 290
offset_top = -70
offset_bottom = 60
theme_override_font_sizes/font_size = 44
autowrap_mode = 2
text = "Ship Crafter"
horizontal_alignment = 1
[node name="CrafterCost" type="Control" parent="UI/BuildMenu"]
mouse_filter = 2
anchor_left = 0.5
anchor_right = 0.5
anchor_top = 0.5
anchor_bottom = 0.5
offset_left = 60
offset_right = 220
offset_top = 70
offset_bottom = 150
script = ExtResource("19")
amount = 12
digit_height = 66.0
[node name="CommandButton" type="Control" parent="UI/BuildMenu"]
anchor_left = 0.5
anchor_right = 0.5
anchor_top = 0.5
anchor_bottom = 0.5
offset_left = -214
offset_right = -66
offset_top = 175
offset_bottom = 323
script = ExtResource("10")
icon = 10
glow_color = Color(0.55, 0.6, 1, 1)
[node name="CommandLabel" type="Label" parent="UI/BuildMenu"]
mouse_filter = 2
anchor_left = 0.5
anchor_right = 0.5
anchor_top = 0.5
anchor_bottom = 0.5
offset_left = -290
offset_right = 10
offset_top = 333
offset_bottom = 463
theme_override_font_sizes/font_size = 44
autowrap_mode = 2
text = "Command Center"
horizontal_alignment = 1
[node name="CommandCost" type="Control" parent="UI/BuildMenu"]
mouse_filter = 2
anchor_left = 0.5
anchor_right = 0.5
anchor_top = 0.5
anchor_bottom = 0.5
offset_left = -220
offset_right = -60
offset_top = 473
offset_bottom = 553
script = ExtResource("19")
amount = 15
digit_height = 66.0
[node name="ExtractorButton" type="Control" parent="UI/BuildMenu"]
anchor_left = 0.5
anchor_right = 0.5
anchor_top = 0.5
anchor_bottom = 0.5
offset_left = 66
offset_right = 214
offset_top = 175
offset_bottom = 323
script = ExtResource("10")
icon = 11
glow_color = Color(0, 0.62, 0.7, 1)
[node name="ExtractorLabel" type="Label" parent="UI/BuildMenu"]
mouse_filter = 2
anchor_left = 0.5
anchor_right = 0.5
anchor_top = 0.5
anchor_bottom = 0.5
offset_left = -10
offset_right = 290
offset_top = 333
offset_bottom = 463
theme_override_font_sizes/font_size = 44
autowrap_mode = 2
text = "Extractor"
horizontal_alignment = 1
[node name="ExtractorCost" type="Control" parent="UI/BuildMenu"]
mouse_filter = 2
anchor_left = 0.5
anchor_right = 0.5
anchor_top = 0.5
anchor_bottom = 0.5
offset_left = 60
offset_right = 220
offset_top = 473
offset_bottom = 553
script = ExtResource("19")
amount = 25
digit_height = 66.0
[node name="CloseButton" type="Control" parent="UI/BuildMenu"]
anchor_left = 1.0
anchor_right = 1.0
offset_left = -172
offset_right = -24
offset_top = 24
offset_bottom = 172
script = ExtResource("10")
icon = 1
[node name="InfoPopup" type="Control" parent="UI/BuildMenu"]
visible = false
anchor_right = 1.0
anchor_bottom = 1.0
[node name="Dim" type="ColorRect" parent="UI/BuildMenu/InfoPopup"]
anchor_right = 1.0
anchor_bottom = 1.0
color = Color(0.01, 0.01, 0.03, 0.55)
[node name="Panel" type="Control" parent="UI/BuildMenu/InfoPopup"]
mouse_filter = 2
anchor_left = 0.5
anchor_right = 0.5
anchor_top = 0.5
anchor_bottom = 0.5
offset_left = -352
offset_right = 352
offset_top = -600
offset_bottom = 600
script = ExtResource("20")
glow_color = Color(0, 0.62, 0.7, 1)
[node name="TitleLabel" type="Label" parent="UI/BuildMenu/InfoPopup/Panel"]
mouse_filter = 2
anchor_right = 1.0
offset_left = 44
offset_right = -44
offset_top = 30
offset_bottom = 150
text = ""
horizontal_alignment = 1
[node name="MessageLabel" type="Label" parent="UI/BuildMenu/InfoPopup/Panel"]
mouse_filter = 2
anchor_right = 1.0
anchor_bottom = 1.0
offset_left = 44
offset_right = -44
offset_top = 160
offset_bottom = -440
theme_override_font_sizes/font_size = 48
text = ""
horizontal_alignment = 1
vertical_alignment = 1
autowrap_mode = 2
[node name="CostNumber" type="Control" parent="UI/BuildMenu/InfoPopup/Panel"]
mouse_filter = 2
anchor_left = 0.5
anchor_right = 0.5
anchor_top = 1.0
anchor_bottom = 1.0
offset_left = -70
offset_right = 90
offset_top = -424
offset_bottom = -334
script = ExtResource("19")
amount = 0
digit_height = 78.0
[node name="BuildButton" type="Control" parent="UI/BuildMenu/InfoPopup/Panel"]
anchor_left = 0.5
anchor_right = 0.5
anchor_top = 1.0
anchor_bottom = 1.0
offset_left = -200
offset_right = -40
offset_top = -300
offset_bottom = -140
script = ExtResource("10")
icon = 5
glow_color = Color(0.45, 0.9, 0.55, 1)
[node name="CloseButton" type="Control" parent="UI/BuildMenu/InfoPopup/Panel"]
anchor_left = 0.5
anchor_right = 0.5
anchor_top = 1.0
anchor_bottom = 1.0
offset_left = 40
offset_right = 200
offset_top = -300
offset_bottom = -140
script = ExtResource("10")
icon = 1
glow_color = Color(0, 0.62, 0.7, 1)
[node name="CraftMenu" type="Control" parent="UI"]
visible = false
anchor_right = 1.0
anchor_bottom = 1.0
[node name="Backdrop" type="ColorRect" parent="UI/CraftMenu"]
anchor_right = 1.0
anchor_bottom = 1.0
color = Color(0.03, 0.03, 0.08, 0.94)
[node name="TitleLabel" type="Label" parent="UI/CraftMenu"]
mouse_filter = 2
anchor_right = 1.0
offset_left = 24
offset_top = 70
offset_right = -24
offset_bottom = 196
text = "Build a ship"
horizontal_alignment = 1
[node name="StatusLabel" type="Label" parent="UI/CraftMenu"]
mouse_filter = 2
anchor_right = 1.0
offset_left = 24
offset_top = 206
offset_right = -24
offset_bottom = 360
theme_override_font_sizes/font_size = 40
autowrap_mode = 2
text = ""
horizontal_alignment = 1
[node name="InterceptorButton" type="Control" parent="UI/CraftMenu"]
anchor_left = 0.5
anchor_right = 0.5
anchor_top = 0.5
anchor_bottom = 0.5
offset_left = -74
offset_right = 74
offset_top = -74
offset_bottom = 74
script = ExtResource("10")
icon = 2
[node name="InterceptorLabel" type="Label" parent="UI/CraftMenu"]
mouse_filter = 2
anchor_left = 0.5
anchor_right = 0.5
anchor_top = 0.5
anchor_bottom = 0.5
offset_left = -260
offset_right = 260
offset_top = 100
offset_bottom = 200
theme_override_font_sizes/font_size = 60
text = "Interceptor"
horizontal_alignment = 1
[node name="CloseButton" type="Control" parent="UI/CraftMenu"]
anchor_left = 1.0
anchor_right = 1.0
offset_left = -172
offset_right = -24
offset_top = 24
offset_bottom = 172
script = ExtResource("10")
icon = 1
[node name="FormationMenu" type="Control" parent="UI"]
visible = false
mouse_filter = 2
anchor_right = 1.0
anchor_bottom = 1.0
[node name="Backdrop" type="ColorRect" parent="UI/FormationMenu"]
mouse_filter = 2
anchor_right = 1.0
anchor_bottom = 1.0
color = Color(0.03, 0.03, 0.08, 0.94)
[node name="TitleLabel" type="Label" parent="UI/FormationMenu"]
mouse_filter = 2
anchor_right = 1.0
offset_left = 24
offset_top = 70
offset_right = -24
offset_bottom = 220
theme_override_font_sizes/font_size = 44
autowrap_mode = 2
text = "Fleet formation - drag to arrange"
horizontal_alignment = 1
[node name="Editor" type="Control" parent="UI/FormationMenu"]
mouse_filter = 2
anchor_left = 0.5
anchor_right = 0.5
anchor_top = 0.5
anchor_bottom = 0.5
offset_left = -300
offset_right = 300
offset_top = -300
offset_bottom = 300
script = ExtResource("17")
[node name="ResetButton" type="Control" parent="UI/FormationMenu"]
anchor_left = 0.5
anchor_right = 0.5
anchor_top = 1.0
anchor_bottom = 1.0
offset_left = -74
offset_right = 74
offset_top = -270
offset_bottom = -122
script = ExtResource("10")
icon = 3
[node name="ResetLabel" type="Label" parent="UI/FormationMenu"]
mouse_filter = 2
anchor_left = 0.5
anchor_right = 0.5
anchor_top = 1.0
anchor_bottom = 1.0
offset_left = -180
offset_right = 180
offset_top = -114
offset_bottom = -8
theme_override_font_sizes/font_size = 60
text = "Reset"
horizontal_alignment = 1
[node name="CloseButton" type="Control" parent="UI/FormationMenu"]
anchor_left = 1.0
anchor_right = 1.0
offset_left = -172
offset_right = -24
offset_top = 24
offset_bottom = 172
script = ExtResource("10")
icon = 1
[node name="FadeOverlay" type="CanvasLayer" parent="."]
layer = 10
[node name="FadeRect" type="ColorRect" parent="FadeOverlay"]
mouse_filter = 2
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
color = Color(0, 0, 0, 0)