design config

This commit is contained in:
2026-06-12 18:00:04 +02:00
parent 1641189b75
commit 3dc503606c
5 changed files with 685 additions and 129 deletions

View File

@@ -1,130 +1,37 @@
[[module]] # modules.toml
id = "armor_plate" #
unlock_at_station_level = -1 # First real-content iteration: module ids and surface masks are the designed
surface_mask = ["OO"] # content; stats, materials, and threat costs are placeholders until the
materials = [{item = "armor_plate_module", amount = 1}] # recipe and balancing passes.
player_production_level = 1 #
production_time_seconds = 3 # Surface mask footprint ladder — footprints gate which hulls can mount a
threat_cost = 20.0 # module, purely through geometry (see ships.toml for the matching hull
fill_color = "#808080" # grids):
glyph = "A" #
# 1x1 laser_cannon_s, salvager, repair_tool fits every hull, incl. drones
[module.health] # 1x2 maneuvering_thrusters, sensor_booster,
added_hp_formula = "40" # armor_plates frigate and up
# 1x3 afterburner frigate and up (eats most of a frigate)
# L-shape weapon_stabilizer, weapon_primer,
# weapon_upgrade frigate and up
# 2x2 laser_cannon_m, drone_bay cruiser and up (no 2x2 area on s hulls)
# 3x3 laser_cannon_l battleship and up (no 3x3 area on m hulls)
# 2x6 drone_hangar dreadnought and carrier only
# -----------------------------------------------------------------------------
# Weapons
# -----------------------------------------------------------------------------
[[module]] [[module]]
id = "sensor_booster" id = "laser_cannon_s"
unlock_at_station_level = -1 unlock_at_station_level = -1
surface_mask = ["O"] surface_mask = ["O"]
materials = [{item = "sensor_booster_module", amount = 1}] materials = [{item = "laser_cannon_s_module", amount = 1}]
player_production_level = 1
production_time_seconds = 2
threat_cost = 1.0
fill_color = "#40A0FF"
glyph = "S"
[module.sensor]
added_sensor_range_m_formula = "50"
[[module]]
id = "manuvering_thrusters"
unlock_at_station_level = -1
surface_mask = ["O"]
materials = [{item = "manuvering_thrusters_module", amount = 1}]
player_production_level = 1
production_time_seconds = 2
threat_cost = 1.0
fill_color = "#40A0FF"
glyph = "Mt"
[module.movement]
multiplied_speed_mps_formula = "1.2"
added_maneuvering_acceleration_mpss_formula = "10"
[[module]]
id = "afterburner"
unlock_at_station_level = -1
surface_mask = ["O"]
materials = [{item = "afterburner_module", amount = 1}]
player_production_level = 1
production_time_seconds = 2
threat_cost = 1.0
fill_color = "#40A0FF"
glyph = "Ab"
[module.movement]
multiplied_speed_mps_formula = "1.6"
added_main_acceleration_mpss_formula = "60"
[[module]]
id = "weapon_upgrade"
unlock_at_station_level = -1
surface_mask = [
"OO",
"O ",
]
materials = [{item = "weapon_upgrade_module", amount = 1}]
player_production_level = 1
production_time_seconds = 4
threat_cost = 10.0
fill_color = "#FF4040"
glyph = "Wu"
[module.weapon]
multiplied_damage_formula = "1.2"
[[module]]
id = "weapon_primer"
unlock_at_station_level = -1
surface_mask = [
"OO",
"O ",
]
materials = [{item = "weapon_primer_module", amount = 1}]
player_production_level = 1
production_time_seconds = 4
threat_cost = 10.0
fill_color = "#FF4040"
glyph = "Wp"
[module.weapon]
multiplied_attack_rate_hz_formula = "1.2"
[[module]]
id = "weapon_stabilizer"
unlock_at_station_level = -1
surface_mask = [
"OO",
"O ",
]
materials = [{item = "weapon_stabilizer_module", amount = 1}]
player_production_level = 1
production_time_seconds = 4
threat_cost = 10.0
fill_color = "#FF4040"
glyph = "Ws"
[module.weapon]
multiplied_attack_range_m_formula = "1.5"
multiplied_attack_rate_hz_formula = "0.8"
[[module]]
id = "laser_cannon_xs"
unlock_at_station_level = -1
surface_mask = ["O"]
materials = [{item = "laser_cannon_xs_module", amount = 1}]
player_production_level = 1 player_production_level = 1
production_time_seconds = 0.5 production_time_seconds = 0.5
threat_cost = 5.0 threat_cost = 5.0
fill_color = "#FF8040" fill_color = "#FF8040"
glyph = "L" glyph = "Ls"
[module.weapon] [module.weapon]
damage_formula = "2" damage_formula = "2"
@@ -133,17 +40,17 @@ attack_rate_hz_formula = "2.0"
[[module]] [[module]]
id = "laser_cannon_s" id = "laser_cannon_m"
unlock_at_station_level = -1 unlock_at_station_level = -1
surface_mask = [ surface_mask = [
"OO", "OO",
"OO"] "OO"]
materials = [{item = "laser_cannon_s_module", amount = 1}] materials = [{item = "laser_cannon_m_module", amount = 1}]
player_production_level = 1 player_production_level = 1
production_time_seconds = 0.5 production_time_seconds = 2
threat_cost = 30.0 threat_cost = 30.0
fill_color = "#FF8040" fill_color = "#FF8040"
glyph = "L" glyph = "Lm"
[module.weapon] [module.weapon]
damage_formula = "10" damage_formula = "10"
@@ -151,6 +58,29 @@ attack_range_m_formula = "70"
attack_rate_hz_formula = "1.5" attack_rate_hz_formula = "1.5"
[[module]]
id = "laser_cannon_l"
unlock_at_station_level = -1
surface_mask = [
"OOO",
"OOO",
"OOO"]
materials = [{item = "laser_cannon_l_module", amount = 1}]
player_production_level = 1
production_time_seconds = 8
threat_cost = 150.0
fill_color = "#FF8040"
glyph = "Ll"
[module.weapon]
damage_formula = "40"
attack_range_m_formula = "100"
attack_rate_hz_formula = "0.8"
# -----------------------------------------------------------------------------
# Utility tools
# -----------------------------------------------------------------------------
[[module]] [[module]]
id = "salvager" id = "salvager"
unlock_at_station_level = -1 unlock_at_station_level = -1
@@ -182,3 +112,163 @@ glyph = "Rp"
[module.repair] [module.repair]
repair_rate_hz_formula = "5 + x" repair_rate_hz_formula = "5 + x"
repair_range_m_formula = "800" repair_range_m_formula = "800"
# -----------------------------------------------------------------------------
# Propulsion
# -----------------------------------------------------------------------------
[[module]]
id = "afterburner"
unlock_at_station_level = -1
surface_mask = ["OOO"]
materials = [{item = "afterburner_module", amount = 1}]
player_production_level = 1
production_time_seconds = 2
threat_cost = 1.0
fill_color = "#40A0FF"
glyph = "Ab"
[module.movement]
multiplied_speed_mps_formula = "1.6"
added_main_acceleration_mpss_formula = "60"
[[module]]
id = "maneuvering_thrusters"
unlock_at_station_level = -1
surface_mask = ["OO"]
materials = [{item = "maneuvering_thrusters_module", amount = 1}]
player_production_level = 1
production_time_seconds = 2
threat_cost = 1.0
fill_color = "#40A0FF"
glyph = "Mt"
[module.movement]
multiplied_speed_mps_formula = "1.2"
added_maneuvering_acceleration_mpss_formula = "10"
# -----------------------------------------------------------------------------
# Defense & sensors
# -----------------------------------------------------------------------------
[[module]]
id = "armor_plates"
unlock_at_station_level = -1
surface_mask = ["OO"]
materials = [{item = "armor_plates_module", amount = 1}]
player_production_level = 1
production_time_seconds = 3
threat_cost = 20.0
fill_color = "#808080"
glyph = "A"
[module.health]
added_hp_formula = "40"
[[module]]
id = "sensor_booster"
unlock_at_station_level = -1
surface_mask = ["OO"]
materials = [{item = "sensor_booster_module", amount = 1}]
player_production_level = 1
production_time_seconds = 2
threat_cost = 1.0
fill_color = "#40A0FF"
glyph = "S"
[module.sensor]
added_sensor_range_m_formula = "50"
# -----------------------------------------------------------------------------
# Weapon modifiers
# -----------------------------------------------------------------------------
[[module]]
id = "weapon_upgrade"
unlock_at_station_level = -1
surface_mask = [
"OO",
"OX",
]
materials = [{item = "weapon_upgrade_module", amount = 1}]
player_production_level = 1
production_time_seconds = 4
threat_cost = 10.0
fill_color = "#FF4040"
glyph = "Wu"
[module.weapon]
multiplied_damage_formula = "1.2"
[[module]]
id = "weapon_primer"
unlock_at_station_level = -1
surface_mask = [
"OO",
"OX",
]
materials = [{item = "weapon_primer_module", amount = 1}]
player_production_level = 1
production_time_seconds = 4
threat_cost = 10.0
fill_color = "#FF4040"
glyph = "Wp"
[module.weapon]
multiplied_attack_rate_hz_formula = "1.2"
[[module]]
id = "weapon_stabilizer"
unlock_at_station_level = -1
surface_mask = [
"OO",
"OX",
]
materials = [{item = "weapon_stabilizer_module", amount = 1}]
player_production_level = 1
production_time_seconds = 4
threat_cost = 10.0
fill_color = "#FF4040"
glyph = "Ws"
[module.weapon]
multiplied_attack_range_m_formula = "1.5"
multiplied_attack_rate_hz_formula = "0.8"
# -----------------------------------------------------------------------------
# Drone modules
#
# Footprint-only placeholders: the drone launching capability is not
# implemented yet, so these modules define no capability section.
# -----------------------------------------------------------------------------
[[module]]
id = "drone_bay"
unlock_at_station_level = -1
surface_mask = [
"OO",
"OO"]
materials = [{item = "drone_bay_module", amount = 1}]
player_production_level = 1
production_time_seconds = 5
threat_cost = 15.0
fill_color = "#CC66FF"
glyph = "Db"
[[module]]
id = "drone_hangar"
unlock_at_station_level = -1
surface_mask = [
"OOOOOO",
"OOOOOO"]
materials = [{item = "drone_hangar_module", amount = 1}]
player_production_level = 1
production_time_seconds = 20
threat_cost = 100.0
fill_color = "#9933CC"
glyph = "Dh"

View File

@@ -1,8 +1,26 @@
# ships.toml
#
# First real-content iteration: ship ids and layout grids are the designed
# content; stats, materials, and production times are placeholders until the
# recipe and balancing passes.
#
# Size classes:
# xs drone 1 cell — exactly one 1x1 module
# s frigate, destroyer no 2x2 area anywhere: only 1x1/1x2/1x3/L modules fit
# m cruiser, battlecruiser 2x2 areas (m guns, drone bays) but no 3x3 area
# l battleship fits exactly one 3x3 l gun, at heavy opportunity cost
# xl dreadnought, carrier dreadnought fits three l guns; carrier fits one
# drone hangar (2x6) but no l gun (its deck rows
# are broken up by elevator shafts)
#
# All new hulls have threat cost_formula = "0" so enemy waves do not spawn
# them until the balancing pass gives them real stats and default loadouts.
[[ship]] [[ship]]
id = "drone" id = "drone"
unlock_at_station_level = -1 unlock_at_station_level = -1
layout = ["O"] layout = ["O"]
default_modules = [{type = "laser_cannon_xs", x = 0, y = 0, rotation = "east"}] default_modules = [{type = "laser_cannon_s", x = 0, y = 0, rotation = "east"}]
[ship.schematic] [ship.schematic]
materials = [{item = "drone_hull", amount = 1}] materials = [{item = "drone_hull", amount = 1}]
@@ -27,3 +45,272 @@ sensor_range_m_formula = "150"
[ship.loot] [ship.loot]
scrap_drop = 2 scrap_drop = 2
# Frigate — 5 cells in a plus shape. Holds a couple of small guns plus at
# most one 1x2 support (every 1x2 placement crosses the center cell), or one
# L-shaped weapon modifier, or an afterburner spanning the full center line.
[[ship]]
id = "frigate"
unlock_at_station_level = -1
layout = [
"XOX",
"OOO",
"XOX",
]
[ship.schematic]
materials = [{item = "frigate_hull", amount = 1}]
player_production_level = 1
production_time_seconds = 10
[ship.threat]
cost_formula = "0"
[ship.health]
hp_formula = "30"
[ship.movement]
speed_mps_formula = "30"
main_acceleration_mpss_formula = "50"
maneuvering_acceleration_mpss_formula = "25"
angular_acceleration_radpss_formula = "8"
max_rotation_speed_radps_formula = "4"
[ship.sensor]
sensor_range_m_formula = "200"
[ship.loot]
scrap_drop = 5
# Destroyer — 8 cells: a long gun deck with three turret bumps on top.
# Still no 2x2 area, so it packs more small guns than a frigate but can never
# mount medium hardware.
[[ship]]
id = "destroyer"
unlock_at_station_level = -1
layout = [
"OXOXO",
"OOOOO",
]
[ship.schematic]
materials = [{item = "destroyer_hull", amount = 1}]
player_production_level = 1
production_time_seconds = 15
[ship.threat]
cost_formula = "0"
[ship.health]
hp_formula = "50"
[ship.movement]
speed_mps_formula = "25"
main_acceleration_mpss_formula = "40"
maneuvering_acceleration_mpss_formula = "20"
angular_acceleration_radpss_formula = "6"
max_rotation_speed_radps_formula = "3"
[ship.sensor]
sensor_range_m_formula = "220"
[ship.loot]
scrap_drop = 8
# Cruiser — 12 cells with notched corners. Fits at most two 2x2 m guns
# (stacked through the middle), leaving the four side cells for small
# supports; no 3x3 area exists for an l gun.
[[ship]]
id = "cruiser"
unlock_at_station_level = -1
layout = [
"XOOX",
"OOOO",
"OOOO",
"XOOX",
]
[ship.schematic]
materials = [{item = "cruiser_hull", amount = 1}]
player_production_level = 1
production_time_seconds = 25
[ship.threat]
cost_formula = "0"
[ship.health]
hp_formula = "120"
[ship.movement]
speed_mps_formula = "20"
main_acceleration_mpss_formula = "30"
maneuvering_acceleration_mpss_formula = "15"
angular_acceleration_radpss_formula = "4"
max_rotation_speed_radps_formula = "2"
[ship.sensor]
sensor_range_m_formula = "250"
[ship.loot]
scrap_drop = 15
# Battlecruiser — 16 cells: a wide bow split into two gun cheeks, tapering
# toward the stern. Fits three 2x2 m guns (two in the cheeks, one through
# the middle) with small support slots left over; the split bow and tapered
# stern leave no 3x3 area for an l gun and no 2x6 area for a drone hangar.
[[ship]]
id = "battlecruiser"
unlock_at_station_level = -1
layout = [
"OOXXOO",
"OOOOOO",
"XOOOOX",
"XXOOXX",
]
[ship.schematic]
materials = [{item = "battlecruiser_hull", amount = 1}]
player_production_level = 1
production_time_seconds = 35
[ship.threat]
cost_formula = "0"
[ship.health]
hp_formula = "180"
[ship.movement]
speed_mps_formula = "18"
main_acceleration_mpss_formula = "25"
maneuvering_acceleration_mpss_formula = "12"
angular_acceleration_radpss_formula = "3"
max_rotation_speed_radps_formula = "1.5"
[ship.sensor]
sensor_range_m_formula = "260"
[ship.loot]
scrap_drop = 20
# Battleship — 20 cells, 5 wide: at most ONE 3x3 l gun fits (the hull is too
# narrow for two), and mounting it consumes nearly half the grid, squeezing
# supports into the remaining strips. Without the l gun it flexibly fits
# several m guns instead. Too narrow for a drone hangar.
[[ship]]
id = "battleship"
unlock_at_station_level = -1
layout = [
"XOOOX",
"OOOOO",
"OOOOO",
"OOOOO",
"XOXOX",
]
[ship.schematic]
materials = [{item = "battleship_hull", amount = 1}]
player_production_level = 1
production_time_seconds = 60
[ship.threat]
cost_formula = "0"
[ship.health]
hp_formula = "350"
[ship.movement]
speed_mps_formula = "14"
main_acceleration_mpss_formula = "18"
maneuvering_acceleration_mpss_formula = "8"
angular_acceleration_radpss_formula = "2"
max_rotation_speed_radps_formula = "1"
[ship.sensor]
sensor_range_m_formula = "280"
[ship.loot]
scrap_drop = 35
# Dreadnought — 42 cells: an 11-wide, 3-deep main battery deck that fits
# three 3x3 l guns side by side with spacer columns left over, plus bow and
# stern strips for supports.
[[ship]]
id = "dreadnought"
unlock_at_station_level = -1
layout = [
"XXXOOOOOXXX",
"OOOOOOOOOOO",
"OOOOOOOOOOO",
"OOOOOOOOOOO",
"XXOOXXXOOXX",
]
[ship.schematic]
materials = [{item = "dreadnought_hull", amount = 1}]
player_production_level = 1
production_time_seconds = 120
[ship.threat]
cost_formula = "0"
[ship.health]
hp_formula = "800"
[ship.movement]
speed_mps_formula = "8"
main_acceleration_mpss_formula = "10"
maneuvering_acceleration_mpss_formula = "5"
angular_acceleration_radpss_formula = "1"
max_rotation_speed_radps_formula = "0.5"
[ship.sensor]
sensor_range_m_formula = "300"
[ship.loot]
scrap_drop = 60
# Carrier — 37 cells: the top flight deck (rows 0-1) is the only place wide
# enough for the 2x6 drone hangar, and exactly one fits. The middle deck row
# is broken up by elevator shafts (the X cells) so no 3x3 l gun can ever fit;
# the lower decks hold supports and 2x2 point-defense m guns.
[[ship]]
id = "carrier"
unlock_at_station_level = -1
layout = [
"XOOOOOOOOX",
"OOOOOOOOOO",
"OOXOOXOOXO",
"XOOOOOOOOX",
"XXXOOOOXXX",
]
[ship.schematic]
materials = [{item = "carrier_hull", amount = 1}]
player_production_level = 1
production_time_seconds = 120
[ship.threat]
cost_formula = "0"
[ship.health]
hp_formula = "700"
[ship.movement]
speed_mps_formula = "9"
main_acceleration_mpss_formula = "10"
maneuvering_acceleration_mpss_formula = "5"
angular_acceleration_radpss_formula = "1"
max_rotation_speed_radps_formula = "0.5"
[ship.sensor]
sensor_range_m_formula = "350"
[ship.loot]
scrap_drop = 60

View File

@@ -146,6 +146,10 @@ outline = "#1402b3"
fill = "#691313" fill = "#691313"
outline = "#f3ff4f" outline = "#f3ff4f"
[items.laser_cannon_s_module]
fill = "#691313"
outline = "#f3ff4f"
[items.salvager_module] [items.salvager_module]
fill = "#b2cfdd" fill = "#b2cfdd"
outline = "#236137" outline = "#236137"
@@ -164,6 +168,34 @@ outline = "#689275"
fill = "#3366ff" fill = "#3366ff"
outline = "#ffffff" outline = "#ffffff"
[ships.frigate]
fill = "#44aaff"
outline = "#ffffff"
[ships.destroyer]
fill = "#33ccaa"
outline = "#ffffff"
[ships.cruiser]
fill = "#66cc33"
outline = "#ffffff"
[ships.battlecruiser]
fill = "#cccc33"
outline = "#ffffff"
[ships.battleship]
fill = "#ff9933"
outline = "#ffffff"
[ships.dreadnought]
fill = "#ff5533"
outline = "#ffffff"
[ships.carrier]
fill = "#cc66ff"
outline = "#ffffff"
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
# Laser beams (REQ-SHP-FIRING-BEAM) # Laser beams (REQ-SHP-FIRING-BEAM)
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------

View File

@@ -12,7 +12,7 @@ enemy_buffer_width_tiles = 10
level = 1 level = 1
count = 5 count = 5
modules = [ modules = [
{type = "laser_cannon_xs", x = 1, y = 1, rotation = "east"}, {type = "laser_cannon_s", x = 1, y = 1, rotation = "east"},
] ]
[[arena.team]] [[arena.team]]
@@ -22,7 +22,7 @@ enemy_buffer_width_tiles = 10
level = 1 level = 1
count = 2 count = 2
modules = [ modules = [
{type = "laser_cannon_xs", x = 1, y = 1, rotation = "east"}, {type = "laser_cannon_s", x = 1, y = 1, rotation = "east"},
{type = "weapon_stabilizer", x = 1, y = 1, rotation = "east"}, {type = "weapon_stabilizer", x = 1, y = 1, rotation = "east"},
{type = "weapon_stabilizer", x = 1, y = 1, rotation = "east"}, {type = "weapon_stabilizer", x = 1, y = 1, rotation = "east"},
{type = "weapon_upgrade", x = 1, y = 1, rotation = "east"}, {type = "weapon_upgrade", x = 1, y = 1, rotation = "east"},
@@ -44,7 +44,7 @@ enemy_buffer_width_tiles = 10
level = 1 level = 1
count = 5 count = 5
modules = [ modules = [
{type = "laser_cannon_xs", x = 1, y = 1, rotation = "east"}, {type = "laser_cannon_s", x = 1, y = 1, rotation = "east"},
] ]
[[arena.team]] [[arena.team]]
@@ -54,7 +54,7 @@ enemy_buffer_width_tiles = 10
level = 1 level = 1
count = 3 count = 3
modules = [ modules = [
{type = "laser_cannon_xs", x = 1, y = 1, rotation = "east"}, {type = "laser_cannon_s", x = 1, y = 1, rotation = "east"},
] ]
[[arena.team.ship]] [[arena.team.ship]]
@@ -79,7 +79,7 @@ enemy_buffer_width_tiles = 15
level = 1 level = 1
count = 3 count = 3
modules = [ modules = [
{type = "laser_cannon_xs", x = 1, y = 1, rotation = "east"}, {type = "laser_cannon_s", x = 1, y = 1, rotation = "east"},
] ]
[[arena.team.station]] [[arena.team.station]]
type = "player_station" type = "player_station"
@@ -99,5 +99,5 @@ enemy_buffer_width_tiles = 15
level = 1 level = 1
count = 8 count = 8
modules = [ modules = [
{type = "laser_cannon_xs", x = 1, y = 1, rotation = "east"}, {type = "laser_cannon_s", x = 1, y = 1, rotation = "east"},
] ]

147
docs/content_design.md Normal file
View File

@@ -0,0 +1,147 @@
# Content Design — Ships & Modules
First real-content iteration (June 2026). This pass defines ship hull grids
and module surface masks only. Stats, materials, recipes, and threat costs in
the config files are placeholders; the recipe pass and the balancing pass
come later.
## Design principle: footprint gating
Which module fits on which hull is controlled purely by geometry — no
explicit allow-lists. Each hull grid is shaped so that it physically cannot
contain the footprint of modules from a larger size class. This keeps the
rules transparent to the player ("it doesn't fit because there is no room")
and makes them trivially moddable through the config files alone.
### Module footprint ladder
| Footprint | Modules | Smallest hull that fits it |
|-----------|---------|----------------------------|
| 1x1 | laser_cannon_s, salvager, repair_tool | drone |
| 1x2 | maneuvering_thrusters, sensor_booster, armor_plates | frigate |
| 1x3 | afterburner | frigate (eats most of it) |
| L-shape (3 cells) | weapon_stabilizer, weapon_primer, weapon_upgrade | frigate |
| 2x2 | laser_cannon_m, drone_bay | cruiser |
| 3x3 | laser_cannon_l | battleship |
| 2x6 | drone_hangar | dreadnought / carrier |
### Hull grids
`O` = buildable cell, `X` = hull structure (not buildable).
**drone (xs, 1 cell)** — exactly one 1x1 module: a small gun, a salvager, or
a repair tool. This is what makes drone roles swappable.
O
**frigate (s, 5 cells)** — plus shape. Every 1x2 placement crosses the center
cell, so at most ONE 1x2 support fits; alternatively one L-shaped weapon
modifier or one afterburner through the center line. Gun-boat with one or two
support modules, as intended.
XOX
OOO
XOX
**destroyer (s, 8 cells)** — gun deck with three turret bumps. More cells
than the frigate (more small guns), but still no 2x2 area anywhere, so medium
hardware can never be mounted.
OXOXO
OOOOO
**cruiser (m, 12 cells)** — notched corners. Fits at most two 2x2 m guns
(stacked through the middle), leaving the side cells for supports. No 3x3
area.
XOOX
OOOO
OOOO
XOOX
**battlecruiser (m, 16 cells)** — split bow with two gun cheeks, tapered
stern. Fits three 2x2 m guns — one more than the cruiser — with small support
slots left over. The bow split and stern taper prevent any 3x3 area (no l
gun) and any 2x6 area (no drone hangar).
OOXXOO
OOOOOO
XOOOOX
XXOOXX
**battleship (l, 20 cells)** — 5 wide, so at most ONE 3x3 l gun fits, and
mounting it consumes nearly half the grid, leaving only narrow strips for
supports. Without an l gun it flexibly fits several m guns. Too narrow for a
drone hangar.
XOOOX
OOOOO
OOOOO
OOOOO
XOXOX
**dreadnought (xl, 42 cells)** — 11-wide, 3-deep main battery deck: three 3x3
l guns fit side by side with spacer columns to spare, plus bow/stern strips
for supports. Wide enough for a drone hangar too, if the player wants to
trade a gun battery for one.
XXXOOOOOXXX
OOOOOOOOOOO
OOOOOOOOOOO
OOOOOOOOOOO
XXOOXXXOOXX
**carrier (xl, 37 cells)** — the top flight deck (rows 01) is the only
region wide enough for the 2x6 drone hangar, and exactly one fits. The middle
deck row is broken up by elevator shafts (X cells placed so every 3-column
window hits one), which is what prevents any 3x3 l gun from ever fitting.
Lower decks hold supports and 2x2 point-defense m guns.
XOOOOOOOOX
OOOOOOOOOO
OOXOOXOOXO
XOOOOOOOOX
XXXOOOOXXX
### Verified gating matrix
Checked programmatically against the configs (all four mask rotations,
all placements):
| Footprint | drone | frigate | destroyer | cruiser | battlecruiser | battleship | dreadnought | carrier |
|-----------|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
| 1x1 | x | x | x | x | x | x | x | x |
| 1x2 | | x | x | x | x | x | x | x |
| 1x3 | | x | x | x | x | x | x | x |
| L-shape | | x | x | x | x | x | x | x |
| 2x2 | | | | x | x | x | x | x |
| 3x3 | | | | | | x | x | x* |
| 2x6 | | | | | | | x | x |
\* dreadnought only; the carrier's elevator shafts block all 3x3 placements.
Max disjoint l guns: battleship 1, dreadnought 3. Max disjoint m guns:
cruiser 2, battlecruiser 3.
## Deliberate placeholders / open questions for later passes
- All new hulls have `threat.cost_formula = "0"` so enemy waves do not spawn
them yet (WaveSystem treats any ship with positive threat cost as wave-
eligible, regardless of unlock level). The balancing pass should set real
threat costs together with `default_modules` loadouts so waves spawn them
armed.
- All new hulls are `unlock_at_station_level = -1` (available from the start)
to make layout testing easy; the progression pass should stagger these.
- Ship hull material items (`frigate_hull``carrier_hull`) and the new
module items (`laser_cannon_m_module`, `laser_cannon_l_module`,
`drone_bay_module`, `drone_hangar_module`, …) have no recipes yet — that is
the recipe pass. The old `laser_cannon_xs_module` recipe is orphaned (the
module was renamed to `laser_cannon_s`, consuming `laser_cannon_s_module`,
which already has a recipe).
- `drone_bay` and `drone_hangar` are footprint-only placeholders: the drone
launching capability does not exist in the simulation yet, so they define
no capability section.
- Renames in this pass: `laser_cannon_xs``laser_cannon_s` (the old 2x2
`laser_cannon_s` became `laser_cannon_m`), `armor_plate``armor_plates`,
`manuvering_thrusters``maneuvering_thrusters` (typo fix). Test data
under `bin/test/data/config` intentionally still uses the old ids — it is
an independent fixture set.