ship layout blueprints

This commit is contained in:
2026-05-19 21:01:10 +02:00
parent d08bf5d37b
commit d397b9969a
14 changed files with 511 additions and 7 deletions

View File

@@ -11,6 +11,7 @@ Config files use the TOML format. The following config files drive game paramete
- **modules.toml** — per module type: id, surface mask, materials list, player production level, production time, threat cost, fill color, glyph, and stat modifier formulas (additive and/or multiplicative per stat).
- **stations.toml** — HP, damage, range, fire rate, and scrap drop for player and enemy defence stations, defined as formulas of station level.
- **visuals.toml** — rendering-only config (not game parameters): fill and outline colors and glyphs for every building type, item type, ship role, and station type; beam color and width; overlay and toast colors. Loaded by the UI at startup; the simulation does not read it.
- **ship_layouts.toml** — named layout blueprints per ship type; written and read by the application to persist the layout blueprint panel (REQ-MOD-UI-BLUEPRINT-PANEL through REQ-MOD-UI-BLUEPRINT-FILE-LOAD). Not a game parameter file; the simulation does not read it.
- REQ-CFG-RELOAD: When the player triggers a Restart (REQ-UI-GAME-MENU), all config files are reloaded from disk before the simulation is reset to its initial state. Formula strings are recompiled at that point. This allows config edits made while the application is running to take effect without a full application restart.
@@ -37,6 +38,26 @@ Ships in `ships.toml` define a `layout` — a list of strings that describes the
The layout grid determines which cells are available for module placement in the layout configuration dialog.
### Layout Blueprint TOML Format
Each entry in `ship_layouts.toml` represents a named layout blueprint:
```toml
[[blueprint]]
name = "Heavy Shields" # display name; must be unique within a ship type
ship_type = "fighter" # matches a schematic id in ships.toml
modules = [
{type = "shield_module", x = 0, y = 0, rotation = 0},
{type = "cannon_module", x = 2, y = 1, rotation = 90},
]
```
- `name` — human-readable display name. Must be unique within a ship type; need not be globally unique.
- `ship_type` — the schematic id this blueprint belongs to. Must match a schematic defined in `ships.toml`.
- `modules` — array of placed module instances. Each entry: `type` (module id from `modules.toml`), `x` and `y` (zero-based column/row in the ship's layout grid), `rotation` (0, 90, 180, or 270 degrees clockwise). If `modules` is absent or empty, the blueprint represents an empty layout.
The `modules` array format is reused verbatim in `balancing.toml` ship entries (see REQ-BAL-TEAM).
### Module Surface Mask Format
Modules in `modules.toml` define a `surface_mask` — a list of strings that describes the module's tile footprint within the ship layout grid. Each character occupies one cell:
@@ -187,12 +208,25 @@ Modules in `modules.toml` define a `surface_mask` — a list of strings that des
- REQ-MOD-UI-DIALOG: Clicking the "Configure" button opens the **layout configuration dialog** as a modal. While the dialog is open, the game is paused (speed set to 0×). On close, the game speed is restored to what it was before the dialog was opened.
The dialog contains:
- **Left side**: The ship's layout grid rendered at full scale. Buildable cells are white; non-buildable cells are black. Placed modules are rendered with their `fill_color` and `glyph`. The ghost of the currently selected module is shown at the cursor position when in placement mode.
- **Right side**: A grid of module selection buttons (one per module type defined in `modules.toml`) plus a "Remove" button. Each module button shows the module id and its glyph.
- **Left**: The ship's layout grid rendered at full scale. Buildable cells are white; non-buildable cells are black. Placed modules are rendered with their `fill_color` and `glyph`. The ghost of the currently selected module is shown at the cursor position when in placement mode.
- **Center**: A grid of module selection buttons (one per module type defined in `modules.toml`) plus a "Remove" button. Each module button shows the module id and its glyph.
- **Right**: The layout blueprint panel (see REQ-MOD-UI-BLUEPRINT-PANEL through REQ-MOD-UI-BLUEPRINT-FILE-LOAD).
- **Bottom**: A "Confirm" button and a "Cancel" button. Cancel discards all changes made in this dialog session and closes the dialog. Confirm applies the changes: the shipyard's configured layout is updated, the required materials and cycle time displayed in the selected building panel are recalculated, and the ship layout preview is refreshed.
- REQ-MOD-UI-LAYOUT-SIZE: Ship layouts are small enough to display in the layout configuration dialog without scrolling (maximum grid size fits within the dialog).
### Layout Blueprints
- REQ-MOD-UI-BLUEPRINT-PANEL: The right column of the layout configuration dialog is the layout blueprint panel. It shows only blueprints whose `ship_type` matches the schematic of the shipyard for which the dialog was opened. The panel contains, from top to bottom: a "Create Blueprint" button, followed by a scrollable list of blueprint entries (one per matching blueprint, in creation order).
- REQ-MOD-UI-BLUEPRINT-CREATE: Clicking "Create Blueprint" opens a modal dialog prompting for a name. The dialog has Confirm and Cancel buttons. Clicking Cancel closes the dialog with no effect. Clicking Confirm with a non-empty name creates a blueprint from the module layout currently shown in the left-side layout grid (the in-progress state of the dialog, not the previously confirmed shipyard layout) and appends it to the blueprint list.
- REQ-MOD-UI-BLUEPRINT-ENTRY: Each blueprint entry shows the blueprint name and a delete icon ("×") to the right of the name. Clicking the entry (name area) loads that blueprint's module list into the left-side layout grid, replacing all currently placed modules. Module instances that are invalid for the current ship layout (unknown module type, position outside the grid, position on a non-buildable cell, or overlapping another module in the same blueprint) are silently skipped; the remaining valid instances are placed. Clicking the delete icon ("×") removes that blueprint entry from the list immediately.
- REQ-MOD-UI-BLUEPRINT-STARTUP: At application startup, layout blueprints are loaded from `ship_layouts.toml` in the same directory as the application executable. Blueprint entries missing required fields (`name` or `ship_type`) are silently skipped. If the file does not exist, the blueprint list starts empty with no error. If the file exists but cannot be parsed (malformed TOML), a modal error dialog describes the failure and the blueprint list starts empty.
- REQ-MOD-UI-BLUEPRINT-SHUTDOWN: On application shutdown, all layout blueprints (across all ship types) are written to `ship_layouts.toml` in the same directory as the application executable. The TOML structure matches the Layout Blueprint TOML Format. Write errors are silently ignored on shutdown.
## Defence Stations
- REQ-DEF-PLAYER-PLACEMENT: 2 player defence stations are pre-placed in space at the start. Their positions are determined by `world.toml [regions].asteroid_width` and `player_buffer_width`.
@@ -334,7 +368,7 @@ A separate executable target (`balancing`) that links against `lib` but contains
- **World height** (in tiles).
- Exactly **two teams**, each with a human-readable **team name**.
- REQ-BAL-TEAM: Each team defines:
- A list of **ship entries**, each specifying: ship schematic (type), level, and count.
- A list of **ship entries**, each specifying: ship schematic (type), level, count, and an optional `modules` array defining the module layout applied to every ship of that entry. The `modules` array format is identical to that used in `ship_layouts.toml` (see Layout Blueprint TOML Format). If `modules` is omitted, ships of that entry have no modules. Invalid module instances (unknown type, position outside the grid, position on a non-buildable cell, or overlapping another module in the same entry) are silently skipped during loading.
- An optional list of **defence station entries**, each specifying: station type (`player_station` or `enemy_station` from `stations.toml`), level, and tile position (x, y).
- REQ-BAL-HQ: Each team has an HQ placed automatically at the vertical center of the arena at the far end of that team's buffer zone. HQ stats are read from `stations.toml [hq]` at level 1. Team 1's HQ is at the left edge; team 2's HQ is at the right edge.
- REQ-BAL-SPAWN: Team 1's ships spawn in team 1's buffer zone (left side); team 2's ships spawn in team 2's buffer zone (right side). Spawn positions are uniformly random within the respective buffer zone.