spaceship/PlanetSetupEditor.tscn

247 lines
5.7 KiB
Text
Raw Normal View History

Share one backdrop between game and editor, and fix three input/economy bugs The setup editor and the landed surface drew different backgrounds for the same planet. Each scene carried its own hand-written ShaderMaterial, and only the game side ever swapped in a profile's shader, so a gas giant authored in the editor showed recoloured craters while the game showed cloud bands. Both now instance one SurfaceBackground.tscn and configure it through one method, and every profile names its own shader - the old "null means keep whatever the scene already had" convention was the drift, since each scene "already had" something different. The shared material is resource_local_to_scene, or two live surfaces would repaint each other. The gas giant's bands broke into disjoint segments once per cell: the second turbulence octave doubled only the INTEGER half of a lattice coordinate, which is a different point in every cell rather than the same point at twice the frequency. Measured, the old form steps 0.153 at a cell boundary against 0.0002 now. A second discontinuity went with it - the camera cell index arrives pre-wrapped, so hashing it raw rearranged the whole sky every 32 cells; hashes are now wrapped per octave and the field is exactly periodic. Bands also gained low-frequency octaves and per-row differential drift. WorldMap swallowed every touch in _input(), which runs before the GUI system, so CloseButton never saw one: the map could be opened and not closed. Android and desktop hid it behind Godot's emulated mouse event, which this never swallowed; a phone browser gives no such second chance. Its test had been closing the map by calling the method the button was failing to reach. Construction now draws on the fleet hold as well as the bank. With an empty starting bank and ore bankable only at a mothership, charging construction to the bank alone made the first mothership cost ore that could not yet exist. Also: a conquered planet no longer re-spawns its garrison (guarded on having capture points, since a setup with none registers as vacuously conquered); planets keep the map they drew, with the candidate list sorted rather than left in filesystem order and assignments pruned rather than cleared on rescan; and the map editor lists setups at a tappable size and can delete one, as an explicit armed mode rather than a tap away from destroying work. Full suite 106/106. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 11:16:38 +02:00
[gd_scene load_steps=4 format=3]
[ext_resource type="Script" path="res://PlanetSetupEditor.gd" id="1"]
Share one backdrop between game and editor, and fix three input/economy bugs The setup editor and the landed surface drew different backgrounds for the same planet. Each scene carried its own hand-written ShaderMaterial, and only the game side ever swapped in a profile's shader, so a gas giant authored in the editor showed recoloured craters while the game showed cloud bands. Both now instance one SurfaceBackground.tscn and configure it through one method, and every profile names its own shader - the old "null means keep whatever the scene already had" convention was the drift, since each scene "already had" something different. The shared material is resource_local_to_scene, or two live surfaces would repaint each other. The gas giant's bands broke into disjoint segments once per cell: the second turbulence octave doubled only the INTEGER half of a lattice coordinate, which is a different point in every cell rather than the same point at twice the frequency. Measured, the old form steps 0.153 at a cell boundary against 0.0002 now. A second discontinuity went with it - the camera cell index arrives pre-wrapped, so hashing it raw rearranged the whole sky every 32 cells; hashes are now wrapped per octave and the field is exactly periodic. Bands also gained low-frequency octaves and per-row differential drift. WorldMap swallowed every touch in _input(), which runs before the GUI system, so CloseButton never saw one: the map could be opened and not closed. Android and desktop hid it behind Godot's emulated mouse event, which this never swallowed; a phone browser gives no such second chance. Its test had been closing the map by calling the method the button was failing to reach. Construction now draws on the fleet hold as well as the bank. With an empty starting bank and ore bankable only at a mothership, charging construction to the bank alone made the first mothership cost ore that could not yet exist. Also: a conquered planet no longer re-spawns its garrison (guarded on having capture points, since a setup with none registers as vacuously conquered); planets keep the map they drew, with the candidate list sorted rather than left in filesystem order and assignments pruned rather than cleared on rescan; and the map editor lists setups at a tappable size and can delete one, as an explicit armed mode rather than a tap away from destroying work. Full suite 106/106. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 11:16:38 +02:00
[ext_resource type="PackedScene" path="res://SurfaceBackground.tscn" id="3"]
[ext_resource type="Script" path="res://IconButton.gd" id="4"]
[node name="PlanetSetupEditor" type="Node2D"]
script = ExtResource("1")
Share one backdrop between game and editor, and fix three input/economy bugs The setup editor and the landed surface drew different backgrounds for the same planet. Each scene carried its own hand-written ShaderMaterial, and only the game side ever swapped in a profile's shader, so a gas giant authored in the editor showed recoloured craters while the game showed cloud bands. Both now instance one SurfaceBackground.tscn and configure it through one method, and every profile names its own shader - the old "null means keep whatever the scene already had" convention was the drift, since each scene "already had" something different. The shared material is resource_local_to_scene, or two live surfaces would repaint each other. The gas giant's bands broke into disjoint segments once per cell: the second turbulence octave doubled only the INTEGER half of a lattice coordinate, which is a different point in every cell rather than the same point at twice the frequency. Measured, the old form steps 0.153 at a cell boundary against 0.0002 now. A second discontinuity went with it - the camera cell index arrives pre-wrapped, so hashing it raw rearranged the whole sky every 32 cells; hashes are now wrapped per octave and the field is exactly periodic. Bands also gained low-frequency octaves and per-row differential drift. WorldMap swallowed every touch in _input(), which runs before the GUI system, so CloseButton never saw one: the map could be opened and not closed. Android and desktop hid it behind Godot's emulated mouse event, which this never swallowed; a phone browser gives no such second chance. Its test had been closing the map by calling the method the button was failing to reach. Construction now draws on the fleet hold as well as the bank. With an empty starting bank and ore bankable only at a mothership, charging construction to the bank alone made the first mothership cost ore that could not yet exist. Also: a conquered planet no longer re-spawns its garrison (guarded on having capture points, since a setup with none registers as vacuously conquered); planets keep the map they drew, with the candidate list sorted rather than left in filesystem order and assignments pruned rather than cleared on rescan; and the map editor lists setups at a tappable size and can delete one, as an explicit armed mode rather than a tap away from destroying work. Full suite 106/106. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 11:16:38 +02:00
[node name="BackgroundLayer" parent="." instance=ExtResource("3")]
[node name="Camera2D" type="Camera2D" parent="."]
position = Vector2(0, 0)
zoom = Vector2(1, 1)
[node name="ItemHost" type="Node2D" parent="."]
[node name="UI" type="CanvasLayer" parent="."]
layer = 1
[node name="BackButton" type="Control" parent="UI"]
offset_left = 20
offset_top = 20
offset_right = 92
offset_bottom = 92
script = ExtResource("4")
icon = 1
glow_color = Color(0.9, 0.35, 0.35, 1)
[node name="BackCaption" type="Label" parent="UI"]
mouse_filter = 2
offset_left = 20
offset_top = 96
offset_right = 92
offset_bottom = 122
theme_override_font_sizes/font_size = 18
horizontal_alignment = 1
text = "Back"
[node name="ProfileButton" type="Control" parent="UI"]
offset_left = 110
offset_top = 20
offset_right = 182
offset_bottom = 92
script = ExtResource("4")
icon = 0
glow_color = Color(0.5, 0.75, 1, 1)
[node name="ProfileValueLabel" type="Label" parent="UI"]
mouse_filter = 2
offset_left = 190
offset_top = 36
offset_right = 340
offset_bottom = 76
theme_override_font_sizes/font_size = 26
text = "ROCKY"
[node name="NameInput" type="LineEdit" parent="UI"]
offset_left = 350
offset_top = 36
offset_right = 696
offset_bottom = 76
placeholder_text = "Setup name"
text = "Untitled"
[node name="NewButton" type="Control" parent="UI"]
offset_left = 20
offset_top = 140
offset_right = 92
offset_bottom = 212
script = ExtResource("4")
icon = 5
glow_color = Color(0.45, 0.9, 0.55, 1)
[node name="NewCaption" type="Label" parent="UI"]
mouse_filter = 2
offset_left = 20
offset_top = 216
offset_right = 92
offset_bottom = 242
theme_override_font_sizes/font_size = 18
horizontal_alignment = 1
text = "New"
[node name="SaveButton" type="Control" parent="UI"]
offset_left = 110
offset_top = 140
offset_right = 182
offset_bottom = 212
script = ExtResource("4")
icon = 4
glow_color = Color(0.45, 0.9, 0.55, 1)
[node name="SaveCaption" type="Label" parent="UI"]
mouse_filter = 2
offset_left = 110
offset_top = 216
offset_right = 182
offset_bottom = 242
theme_override_font_sizes/font_size = 18
horizontal_alignment = 1
text = "Save"
[node name="LoadButton" type="Control" parent="UI"]
offset_left = 200
offset_top = 140
offset_right = 272
offset_bottom = 212
script = ExtResource("4")
icon = 3
glow_color = Color(0.5, 0.75, 1, 1)
[node name="LoadCaption" type="Label" parent="UI"]
mouse_filter = 2
offset_left = 200
offset_top = 216
offset_right = 272
offset_bottom = 242
theme_override_font_sizes/font_size = 18
horizontal_alignment = 1
text = "Load"
[node name="DeleteButton" type="Control" parent="UI"]
offset_left = 290
offset_top = 140
offset_right = 362
offset_bottom = 212
script = ExtResource("4")
icon = 28
glow_color = Color(0.9, 0.35, 0.35, 1)
[node name="DeleteCaption" type="Label" parent="UI"]
mouse_filter = 2
offset_left = 290
offset_top = 216
offset_right = 362
offset_bottom = 242
theme_override_font_sizes/font_size = 18
horizontal_alignment = 1
text = "Delete"
[node name="StatusLabel" type="Label" parent="UI"]
mouse_filter = 2
offset_left = 380
offset_top = 140
offset_right = 696
offset_bottom = 242
theme_override_font_sizes/font_size = 20
autowrap_mode = 2
text = ""
Stacking distorders, menu layouts, lab rewards, enemy detail, artillery cross DISTORDER STACKING. Each space-time distorder vessel past the first raises the fleet's speed ceiling by 1.0, so a second one is worth crewing instead of being dead weight. GameState gains max_fleet_speed_multiplier, pushed by Fleet whenever composition changes - the same direction as every other fleet-derived figure, since GameState does not reach into the scene tree to count ships. The energy drain is normalised against the CURRENT ceiling, so full boost costs the same per second however wide it is: extra vessels buy more speed, not cheaper speed. Losing one re-clamps an over-ceiling boost rather than leaving the fleet travelling faster than its crew can sustain. TRANSFER MENU. Rows overlapped, and the last one ran into the hint text. row_height is divided from the available space, but each row's contents used a fixed pixel ladder - glyph at +10, buttons at +88, selector at +142 - which needs about 244px. Three resources fit; the fourth cut rows to 180 and every one spilled 64px into the next. Every offset is now a fraction of the row, so it cannot overflow. Also dropped the per-row AMOUNT caption (four copies of a word the footer hint already explains) and moved each glyph and name to the TOP of its row, where they read as its heading rather than the next row's. HANGAR. Six vessel types in one row gave each about 100px for a 155px label, so the names ran together. Now a 3x2 grid per section, sized from the space between the first heading and the status line, using the empty lower half. LAB RESEARCH REWARD. A harder enemy lab is worth more research points, and how hard a lab is depends on the layout authored for it - how many capture points, how many defenders - which the planet TYPE cannot know. PlanetSetup carries research_point_reward, set in the map editor, overriding the planet type's flat rate. 0 means "no opinion", so every map authored before this keeps its old value. RESEARCH LAB BACKGROUND. Its own shader instead of the crater field with a red tint, which read as "rocky planet, tinted" rather than someone's facility: plated floor, seams, service conduits, lit junctions. Loop-free by construction (#68's lesson applied up front) - conduits stay continuous across cells by keying a horizontal run to cell.y and a vertical to cell.x, so neighbouring cells agree without any cell scanning its neighbours. ENEMY DETAIL. Every enemy was a single flat outline, which left the artillery and the turret spawner as the same octagon at two sizes - the silhouette carried no information about what the thing did. EnemyDefinition gains detail_lines and detail_rings as DATA, so adding an enemy still means adding a definition rather than editing Enemy.gd, and the four non-default hulls are redrawn: a long-barrelled sniper, a squat mortar, a hive with launch bays, a capital ship with spine and ribs. Three things drew an enemy from its definition - the enemy, the map editor's markers, and the palette buttons - each reimplementing it from hull_points alone, so the new detail appeared in the game and nowhere else and an editor marker stopped matching what it placed. They now share EnemyDefinitions.draw_definition(). ARTILLERY. The 1.8s charge-up before the tower fired arrived long before the threat was legible and mostly read as the tower being stuck. It fires immediately now; the warning is the shell you can see in the air plus a small cross on the ground at the impact point. Deliberately not a blast-radius ring - a large translucent area was easy to read as the explosion having already happened, where the cross says "move off this spot". MAIN MENU. No Quit in any build (a web build has nothing to quit to, and Android's back gesture already does it), a plain black background, and the game is "Spaceship" - in the title and in config/name, which is what drives the browser tab for the web export. change_scene_to_file() returns an error and otherwise fails silently, leaving the menu up, which is indistinguishable from an unpressed button; it is now checked and reported on screen. Full suite green at 99/99. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-18 16:54:46 +02:00
[node name="RewardButton" type="Control" parent="UI"]
offset_left = 350
offset_top = 20
offset_right = 422
offset_bottom = 92
script = ExtResource("4")
icon = 29
glow_color = Color(0.55, 0.9, 0.65, 1)
[node name="RewardValueLabel" type="Label" parent="UI"]
mouse_filter = 2
offset_left = 430
offset_top = 36
offset_right = 690
offset_bottom = 76
theme_override_font_sizes/font_size = 26
theme_override_colors/font_color = Color(0.55, 0.9, 0.65, 1)
text = "DEFAULT RP"
[node name="SelectedLabel" type="Label" parent="UI"]
mouse_filter = 2
offset_left = 20
offset_top = 250
offset_right = 696
offset_bottom = 286
theme_override_font_sizes/font_size = 22
theme_override_colors/font_color = Color(1, 0.95, 0.9, 1)
autowrap_mode = 2
text = ""
[node name="PaletteRow" type="Control" parent="UI"]
anchor_top = 1.0
anchor_bottom = 1.0
offset_left = 20
offset_top = -110
offset_right = 696
offset_bottom = -20
[node name="LoadPanel" type="Control" parent="UI"]
visible = false
anchor_right = 1.0
anchor_bottom = 1.0
[node name="Backdrop" type="ColorRect" parent="UI/LoadPanel"]
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/LoadPanel"]
mouse_filter = 2
anchor_right = 1.0
offset_left = 24
offset_top = 36
offset_right = -24
offset_bottom = 90
theme_override_font_sizes/font_size = 34
horizontal_alignment = 1
text = "Load a setup"
[node name="List" type="ItemList" parent="UI/LoadPanel"]
offset_left = 24
offset_top = 110
offset_right = 696
Share one backdrop between game and editor, and fix three input/economy bugs The setup editor and the landed surface drew different backgrounds for the same planet. Each scene carried its own hand-written ShaderMaterial, and only the game side ever swapped in a profile's shader, so a gas giant authored in the editor showed recoloured craters while the game showed cloud bands. Both now instance one SurfaceBackground.tscn and configure it through one method, and every profile names its own shader - the old "null means keep whatever the scene already had" convention was the drift, since each scene "already had" something different. The shared material is resource_local_to_scene, or two live surfaces would repaint each other. The gas giant's bands broke into disjoint segments once per cell: the second turbulence octave doubled only the INTEGER half of a lattice coordinate, which is a different point in every cell rather than the same point at twice the frequency. Measured, the old form steps 0.153 at a cell boundary against 0.0002 now. A second discontinuity went with it - the camera cell index arrives pre-wrapped, so hashing it raw rearranged the whole sky every 32 cells; hashes are now wrapped per octave and the field is exactly periodic. Bands also gained low-frequency octaves and per-row differential drift. WorldMap swallowed every touch in _input(), which runs before the GUI system, so CloseButton never saw one: the map could be opened and not closed. Android and desktop hid it behind Godot's emulated mouse event, which this never swallowed; a phone browser gives no such second chance. Its test had been closing the map by calling the method the button was failing to reach. Construction now draws on the fleet hold as well as the bank. With an empty starting bank and ore bankable only at a mothership, charging construction to the bank alone made the first mothership cost ore that could not yet exist. Also: a conquered planet no longer re-spawns its garrison (guarded on having capture points, since a setup with none registers as vacuously conquered); planets keep the map they drew, with the candidate list sorted rather than left in filesystem order and assignments pruned rather than cleared on rescan; and the map editor lists setups at a tappable size and can delete one, as an explicit armed mode rather than a tap away from destroying work. Full suite 106/106. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 11:16:38 +02:00
offset_bottom = 1080
theme_override_font_sizes/font_size = 34
theme_override_constants/v_separation = 30
[node name="DeleteMapButton" type="Control" parent="UI/LoadPanel"]
offset_left = 24
offset_top = 1096
offset_right = 96
offset_bottom = 1168
script = ExtResource("4")
icon = 28
glow_color = Color(0.9, 0.35, 0.35, 1)
[node name="DeleteMapCaption" type="Label" parent="UI/LoadPanel"]
mouse_filter = 2
offset_left = 112
offset_top = 1108
offset_right = 690
offset_bottom = 1160
theme_override_font_sizes/font_size = 24
Share one backdrop between game and editor, and fix three input/economy bugs The setup editor and the landed surface drew different backgrounds for the same planet. Each scene carried its own hand-written ShaderMaterial, and only the game side ever swapped in a profile's shader, so a gas giant authored in the editor showed recoloured craters while the game showed cloud bands. Both now instance one SurfaceBackground.tscn and configure it through one method, and every profile names its own shader - the old "null means keep whatever the scene already had" convention was the drift, since each scene "already had" something different. The shared material is resource_local_to_scene, or two live surfaces would repaint each other. The gas giant's bands broke into disjoint segments once per cell: the second turbulence octave doubled only the INTEGER half of a lattice coordinate, which is a different point in every cell rather than the same point at twice the frequency. Measured, the old form steps 0.153 at a cell boundary against 0.0002 now. A second discontinuity went with it - the camera cell index arrives pre-wrapped, so hashing it raw rearranged the whole sky every 32 cells; hashes are now wrapped per octave and the field is exactly periodic. Bands also gained low-frequency octaves and per-row differential drift. WorldMap swallowed every touch in _input(), which runs before the GUI system, so CloseButton never saw one: the map could be opened and not closed. Android and desktop hid it behind Godot's emulated mouse event, which this never swallowed; a phone browser gives no such second chance. Its test had been closing the map by calling the method the button was failing to reach. Construction now draws on the fleet hold as well as the bank. With an empty starting bank and ore bankable only at a mothership, charging construction to the bank alone made the first mothership cost ore that could not yet exist. Also: a conquered planet no longer re-spawns its garrison (guarded on having capture points, since a setup with none registers as vacuously conquered); planets keep the map they drew, with the candidate list sorted rather than left in filesystem order and assignments pruned rather than cleared on rescan; and the map editor lists setups at a tappable size and can delete one, as an explicit armed mode rather than a tap away from destroying work. Full suite 106/106. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 11:16:38 +02:00
vertical_alignment = 1
text = "Delete a setup"
[node name="CloseButton" type="Control" parent="UI/LoadPanel"]
anchor_left = 1.0
anchor_right = 1.0
offset_left = -92
offset_top = 20
offset_right = -20
offset_bottom = 92
script = ExtResource("4")
icon = 1
glow_color = Color(0.9, 0.35, 0.35, 1)