Buy fleet berths with Fleet Offices

#219: fleet capacity is a built, supplied thing rather than a researched
one. The eight fleet-size doctrines are gone; capacity is one berth free
plus one per Fleet Office standing. An office charges every 25s for the
vessel in its berth, priced off that vessel's own build cost so an expensive
hull is expensive to keep, and drawn from its own store the way a gas burner
draws gas. An office that cannot pay goes dark, its vessel is scuttled, and
the player is told through the same queue quest lines use - which reaches
them on a planet surface too.

An empty berth is idle rather than starved: an office is only failing while
there is something in it to fail, and holding it disabled would leave a
berth that could never be crewed and so could never be paid for again.

Ships have no hit points and a shield absorbs a hit wholesale, so the lost
vessel is scuttled rather than damaged - otherwise a shielded hull would
survive its own eviction.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019AJMdB7iuHuLFZM1aBu3GD
This commit is contained in:
Loïc Wisniewski 2026-09-05 17:09:27 +02:00
commit 1f5fecd371
60 changed files with 695 additions and 243 deletions

View file

@ -35,6 +35,9 @@ const PLANNING_COLOR: Color = Color(0.62, 0.74, 0.92)
# #116. Warm steel: the workshop is the only structure whose whole job is
# looking after the others, and it should read as a yard rather than a plant.
const WORKSHOP_COLOR: Color = Color(0.5, 0.95, 0.8)
# #219: the fleet office. A cool administrative blue, deliberately unlike
# the crafter's amber - one builds hulls, this one pays for them.
const FLEET_OFFICE_COLOR: Color = Color(0.45, 0.78, 1.0)
# Workshop: an open service gantry with a cradle under it and drone berths
# either side. Deliberately unenclosed - what it holds is other people's
@ -434,6 +437,37 @@ func _draw_command_center() -> void:
NeonDraw.draw_glowing_polygon(self, _diamond(Vector2.ZERO, CMD_SCREEN_RADIUS), readout, 0.9)
func _draw_fleet_office() -> void:
# A berth, and the ledger that keeps it. The frame is the berth - an open
# bay with a hull sitting in it - and the stack of bars beside it is the
# supply the office is spending. Read together they say "this structure
# holds a place in the fleet, and it costs something".
var c: Color = FLEET_OFFICE_COLOR
var lit: Color = Color(0.88, 0.97, 1.0)
# The berth: three sides, open at the top, so what sits in it reads as
# parked rather than enclosed.
NeonDraw.draw_glowing_path(self, PackedVector2Array([
Vector2(-52.0, -46.0), Vector2(-52.0, 34.0),
Vector2(18.0, 34.0), Vector2(18.0, -46.0),
]), c, 0.95, 0.5)
# The hull in it, small and lit: the vessel this office is paying for.
NeonDraw.draw_glowing_polygon(self, PackedVector2Array([
Vector2(-17.0, -22.0), Vector2(-3.0, 14.0),
Vector2(-17.0, 6.0), Vector2(-31.0, 14.0),
]), lit, 0.9)
# The ledger: four bars of decreasing length, the running cost.
for i in range(4):
var y: float = -34.0 + float(i) * 20.0
var length: float = 44.0 - float(i) * 7.0
NeonDraw.draw_glowing_line(self, Vector2(34.0, y),
Vector2(34.0 + length, y), c, 0.8 - float(i) * 0.12, 0.32)
# The spine they hang off, tying the ledger to the berth.
NeonDraw.draw_glowing_line(self, Vector2(30.0, -42.0),
Vector2(30.0, 34.0), c, 0.7, 0.3)
func _draw_workshop() -> void:
var c: Color = WORKSHOP_COLOR
var lit: Color = Color(0.86, 1.0, 0.95)