Ship Lab: per-vessel research, and the shield vessel

Forgejo #5. A new building gated behind a "Vessel Science" research
node. Its own screen upgrades each vessel type - weapon, movement,
shield and freight - and unlocks the shield vessel, which the ship
crafter can then build.

Vessel research is deliberately NOT more nodes in the mothership tree:
that tree gates what may be built at all and is a strategic spine, while
these are repeatable tuning on vessels already owned. Levels cost
base * (level + 1), so the third point in something is not the price of
the first. Upgrades are read live rather than baked in at build time, so
researching one improves the ships already flying.

The shield is personal, not a bubble: it absorbs a hit that would
destroy the vessel - ships have no health, contact kills - and is then
down until it cycles. Its ring is a NeonPiece child toggled with
`visible` per #10, not a redraw of the hull.

The build menu now holds six entries across three rows, which the #21
repacking already handles.

Enemies still have no weapon, so "blocks shots" has nothing to block
yet; that is filed separately rather than widened into this ticket.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Loïc Wisniewski 2026-08-11 23:31:49 +02:00
commit 1cbae8ff70
13 changed files with 876 additions and 5 deletions

226
Main.tscn
View file

@ -479,6 +479,48 @@ script = ExtResource("19")
amount = 30
digit_height = 40.0
[node name="ShipLabButton" type="Control" parent="UI/BuildMenu"]
anchor_left = 0.5
anchor_right = 0.5
anchor_top = 0.5
anchor_bottom = 0.5
offset_left = 76
offset_right = 204
offset_top = 280
offset_bottom = 408
script = ExtResource("10")
icon = 13
glow_color = Color(0.55, 0.95, 0.9, 1)
[node name="ShipLabLabel" 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 = 414
offset_bottom = 480
theme_override_font_sizes/font_size = 32
autowrap_mode = 2
text = "Ship Lab"
horizontal_alignment = 1
[node name="ShipLabCost" 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 = 80
offset_right = 200
offset_top = 484
offset_bottom = 536
script = ExtResource("19")
amount = 35
digit_height = 40.0
[node name="CloseButton" type="Control" parent="UI/BuildMenu"]
anchor_left = 1.0
anchor_right = 1.0
@ -576,6 +618,162 @@ script = ExtResource("10")
icon = 1
glow_color = Color(0, 0.62, 0.7, 1)
[node name="LabMenu" type="Control" parent="UI" groups=["modal_menus"]]
visible = false
mouse_filter = 2
anchor_right = 1.0
anchor_bottom = 1.0
[node name="Backdrop" type="ColorRect" parent="UI/LabMenu"]
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/LabMenu"]
mouse_filter = 2
anchor_right = 1.0
offset_left = 24
offset_top = 60
offset_right = -24
offset_bottom = 170
text = "Ship Lab"
horizontal_alignment = 1
[node name="VesselA" type="Control" parent="UI/LabMenu"]
anchor_left = 0.5
anchor_right = 0.5
offset_left = -290
offset_right = -170
offset_top = 190
offset_bottom = 310
script = ExtResource("10")
icon = 2
glow_color = Color(0.25, 0.85, 1, 1)
[node name="VesselB" type="Control" parent="UI/LabMenu"]
anchor_left = 0.5
anchor_right = 0.5
offset_left = -60
offset_right = 60
offset_top = 190
offset_bottom = 310
script = ExtResource("10")
icon = 2
glow_color = Color(0.45, 0.8, 1, 1)
[node name="VesselC" type="Control" parent="UI/LabMenu"]
anchor_left = 0.5
anchor_right = 0.5
offset_left = 170
offset_right = 290
offset_top = 190
offset_bottom = 310
script = ExtResource("10")
icon = 12
glow_color = Color(0.95, 0.55, 0.85, 1)
[node name="VesselLabel" type="Label" parent="UI/LabMenu"]
mouse_filter = 2
anchor_right = 1.0
offset_left = 24
offset_top = 318
offset_right = -24
offset_bottom = 380
theme_override_font_sizes/font_size = 34
horizontal_alignment = 1
text = ""
[node name="UpgradeList" type="Label" parent="UI/LabMenu"]
mouse_filter = 2
anchor_right = 1.0
anchor_bottom = 1.0
offset_left = 32
offset_top = 396
offset_right = -32
offset_bottom = -470
theme_override_font_sizes/font_size = 30
autowrap_mode = 2
text = ""
[node name="DetailLabel" type="Label" parent="UI/LabMenu"]
mouse_filter = 2
anchor_right = 1.0
anchor_top = 1.0
anchor_bottom = 1.0
offset_left = 32
offset_top = -460
offset_right = -32
offset_bottom = -330
theme_override_font_sizes/font_size = 32
autowrap_mode = 2
horizontal_alignment = 1
text = ""
[node name="StatusLabel" type="Label" parent="UI/LabMenu"]
mouse_filter = 2
anchor_right = 1.0
anchor_top = 1.0
anchor_bottom = 1.0
offset_left = 32
offset_top = -324
offset_right = -32
offset_bottom = -256
theme_override_font_sizes/font_size = 30
autowrap_mode = 2
horizontal_alignment = 1
text = ""
[node name="NextButton" type="Control" parent="UI/LabMenu"]
anchor_left = 0.5
anchor_top = 1.0
anchor_right = 0.5
anchor_bottom = 1.0
offset_left = -230
offset_right = -110
offset_top = -240
offset_bottom = -120
script = ExtResource("10")
icon = 6
glow_color = Color(0.55, 0.95, 0.9, 1)
[node name="BuyButton" type="Control" parent="UI/LabMenu"]
anchor_left = 0.5
anchor_top = 1.0
anchor_right = 0.5
anchor_bottom = 1.0
offset_left = 110
offset_right = 230
offset_top = -240
offset_bottom = -120
script = ExtResource("10")
icon = 4
glow_color = Color(0.45, 0.9, 0.55, 1)
[node name="HintLabel" type="Label" parent="UI/LabMenu"]
mouse_filter = 2
anchor_right = 1.0
anchor_top = 1.0
anchor_bottom = 1.0
offset_left = 24
offset_top = -110
offset_right = -24
offset_bottom = -20
theme_override_font_sizes/font_size = 28
autowrap_mode = 2
horizontal_alignment = 1
text = "Next upgrade Buy"
[node name="CloseButton" type="Control" parent="UI/LabMenu"]
anchor_left = 1.0
anchor_right = 1.0
offset_left = -172
offset_top = 24
offset_right = -24
offset_bottom = 172
script = ExtResource("10")
icon = 1
glow_color = Color(0.55, 0.95, 0.9, 1)
[node name="CraftMenu" type="Control" parent="UI" groups=["modal_menus"]]
visible = false
anchor_right = 1.0
@ -662,6 +860,34 @@ autowrap_mode = 2
text = "Transporter"
horizontal_alignment = 1
[node name="ShieldButton" 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 = -260
offset_bottom = -112
script = ExtResource("10")
icon = 2
glow_color = Color(0.45, 0.8, 1, 1)
[node name="ShieldLabel" 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 = -160
offset_right = 160
offset_top = -104
offset_bottom = -44
theme_override_font_sizes/font_size = 32
autowrap_mode = 2
text = "Shield Vessel"
horizontal_alignment = 1
[node name="StoreOreButton" type="Control" parent="UI/CraftMenu"]
anchor_left = 0.5
anchor_top = 1.0