Skip to content

Station Protection

Status: 🚧 Partial β€” station-defense drone tiers and attack_port deterrence kernel shipped; capture/disable and full player-facing defense UI remain open. (re-verified 2026-08-21 vs Sectorwars2102 HEAD 46bce720.)

The third pillar of universe-level security alongside police forces (faction-driven, jurisdiction-based) and player-built sector defenses (drone blocks, mines per ../galaxy/sectors.md). Station protection is station-driven β€” paid for by the station's docking-fee revenue, run by the station's owner, and bounded by the station's perimeter. It exists for one core purpose: ships docked at a protected station are safe.

When a player docks at a Standard-tier or Premium-tier station, they don't have to worry that their hull will be salvaged while they sleep, that a thief will steal their ship from the docking ring, or that a hostile player will attack them while they're inside the station's bar. The station has security guards walking the docking ring, defense drones patrolling the local sector, and a station-level tractor beam strong enough to stop a stolen ship from leaving β€” and the docking fee they paid is what funds it.

What station protection covers

Three distinct guarantees for any ship docked at a station with security_level >= basic:

  1. No external attack on docked ships. A hostile player in the same sector cannot target a docked ship. The combat-resolver rejects attack attempts with ERR_DOCKED_SHIP_PROTECTED. This complements (not replaces) the NPC-barracks shield rule from ../gameplay/police-forces.md β€” barracks shielding applies to NPC ships specifically; station protection applies to any docked ship (including player-owned).
  2. Anti-theft tractor lock on undock. When a ship attempts to undock, the station checks the pilot's status. If the ship is Ship.stolen_status = true, or the pilot is Wanted at a tier above the station's threshold, or the pilot is on the station's deny-list, the station's tractor beam locks the ship to the docking ring and a station-security response fires. Strong stations can hold the ship indefinitely.
  3. Anti-board protection. The hatch-pin / salvage-break mechanic from ../../SYSTEMS/ship-registry.md only applies to Drifting ships in space. A docked ship at a protected station cannot be boarded β€” the station's airlocks gate access to security-cleared visitors only.

Stations at security_level = none (frontier outposts, abandoned hulks, lawless ports) provide none of these guarantees. Players who dock there are taking the same risk as parking in space.

Security tiers

Four tiers of station protection. Each tier is funded by a portion of the station's docking-fee revenue and configured by the station's owner (or by faction policy for operator-managed stations).

Tier Drones Hired guards Tractor strength Defense budget share Player guarantees
None 0 0 None 0% (no defenses) None β€” docked ships are at risk
Basic 4 0 Weak (75% engine + 10 turns to break) ~5% of revenue No-attack on docked ships; weak tractor on stolen-ship undock
Standard 8 2 named guards Strong (90% engine + 20 turns to break) ~10% of revenue All three guarantees fully enforced
Premium 12 4 named guards + 1 Captain Immobilizing (cannot break) ~20% of revenue Full guarantees; stolen ships cannot escape; security responds within 1 turn

Operator-managed stations (Federation Capital station, Nexus Starport Prime, Terran Space hub stations) are seeded at Standard or Premium tier by the galaxy generator. Player-owned stations default to Basic if the owner wishes to keep operating costs low; the owner can upgrade tier at any time by paying the upgrade fee.

Ordinary NPC-seeded ports (any StationClass, in any region, that isn't one of the named operator-managed anchors above) are seeded per a class-based security gradient (ratified 2026-08-04, Max β€” replacing an earlier uniform Basic floor), matching the docking-slips per-class banding: CLASS_1-6 (basic/mid-tier trading) seed at Basic; CLASS_7-11 (premium/refining, Tech Specialist) seed at Standard. Premium is never granted by class alone β€” reserved for the three literal operator-managed anchors above.

Tier upgrade cost

Upgrade One-time cost Recurring upkeep Construction time
None β†’ Basic 50,000 cr ~5% of station revenue 24 real-time hours
Basic β†’ Standard 200,000 cr ~10% of station revenue (cumulative) 72 real-time hours
Standard β†’ Premium 750,000 cr ~20% of station revenue (cumulative) 7 real-time days

Downgrading is free but takes 24 hours (the dismissal of guards, decommissioning of drones, and tractor-beam shutdown).

Hired security guards (STATION_SECURITY archetype)

The station-paid security force is a new NPC archetype within the unified NPC lifecycle framework: STATION_SECURITY. Distinct from LAW_ENFORCEMENT (police, who are faction-funded and faction-jurisdictioned) and FACTION_PATROL (Federation Navy, AM enforcers β€” also faction-driven). Security guards are station-funded, station-jurisdictioned: they patrol the station's docking ring, the station's host sector, and the immediately adjacent ring (1 hop), but no further.

Roster

Per Station.security_level:

  • Basic: zero named guards. The 4 defense drones are anonymous; threat response is automated.
  • Standard: 2 named NPC guards on staggered shifts (12-hour shifts with 1-hour overlap for handoff briefing per the shift-handoff design). Capacity in the station's NPCBarracks is 2.
  • Premium: 4 named guards + 1 named Captain. The Captain handles serious incidents (any combat in the host sector, any attempted theft of a docked ship); guards handle routine docking-ring patrols. Barracks capacity 5.

Guards have names, careers, and the same lifecycle features as Marshals β€” they can be promoted (Guard β†’ Senior Guard β†’ Captain), retire, or be killed in action by hostile players. KIA cooldown is shorter than for Marshals (3 days vs. 7) since guards are private hires that the station can replace faster.

Ships

STATION_SECURITY NPCs fly standard ship classes β€” usually a Defender or Light Freighter, depending on the station's defense budget and posture. They do not fly NPC-only Interdictor hulls; that special-issue hardware is reserved for actual law enforcement. A Guard-Captain at a Premium station may fly a Defender with a custom paint scheme; routine guards fly Light Freighters.

Ships are 1:1 lifetime-assigned per the same rules as Marshals (per ../gameplay/police-forces.md), park at the station's NPCBarracks when off-duty, and shielded from player attack while there.

Engagement triggers

A STATION_SECURITY NPC engages on any of:

  • Combat against a docked ship β€” instant response; the perpetrator gets a station-tractor lock plus the named-guard squad on top.
  • Stolen-ship undock attempt β€” see Anti-theft tractor below.
  • Attack against the station itself β€” full security response per ./port-ownership.md#takeover-defense.
  • Brawl in the station bar / docking ring β€” flavor scene; routine guards intervene; combat resolves without ship-to-ship escalation.
  • Wanted-Status pilot on station property β€” at Premium tier, guards detain the pilot for the duration of their stay; at Standard tier, they merely watch the pilot. (Wanted Status is otherwise a Federation-Marshal concern, not station security's; the overlap is a Premium-tier perk.)

Guards do not patrol outside the station's host sector + 1-hop ring. A pirate fleeing a Premium-tier station's tractor lock who escapes to 2 hops away is no longer pursued by station security; they're in Federation-Marshal territory now (or in lawless space, where the offense is moot).

Anti-theft tractor beam

The station-level tractor beam is the load-bearing mechanic for "ships docked here are safe." When any ship attempts to undock, the station runs a fast deny-list check:

  1. Is Ship.stolen_status = true? (per the existing stolen-report flow in ../../SYSTEMS/ship-registry.md)
  2. Is the pilot's Player.personal_reputation < station.wanted_threshold?
  3. Is the pilot on the station's deny_list_player_ids (set by owner; defaults empty)?

If any check hits, the undock is rejected with tractor lock:

ERR_STATION_TRACTOR_LOCK
{
  "station_id": "<uuid>",
  "tractor_strength": "weak | strong | immobilizing",
  "reason": "stolen_ship | wanted_pilot | deny_listed",
  "break_attempt_cost": "75-pct engine + 10 turns | 90-pct engine + 20 turns | impossible"
}

The pilot has three options:

  1. Surrender. Abandon the ship at the station; security takes custody. The owner of the stolen ship is notified via the realtime bus; the ship is held for retract / transfer. The thief is fined 15% of cargo value plus a reputation hit β€” the four provisional tractor-lock numbers (15% cargo fine, βˆ’100 failed-break reputation hit, βˆ’500 auto-wanted threshold, and the tier percentages below) were ratified as canon by ADR-0093 item 5 (folded from ADR-0093, re-verified 2026-08-07); serious violations result in arrest and detention (βœ… Shipped β€” Player.detained_until for stolen_ship / wanted_pilot lock reasons: 6h / 3h canonical via game_time.scaled_deadline [NO-CANON exact hours within the 1–6h band]; turn regen freezes; non-Escape-Pod ship boarding gated ERR_DETAINED until expiry. deny_listed surrender does not detain).
  2. Attempt to break free. Pour 75% / 90% of engine power into the tractor for 10 / 20 turns (90% engine / ~20 turns at Premium β€” see Tractor strength tiers below); success rolls against tractor strength. Premium tier is immobilizing β€” break attempts always fail. Each failed break costs the turns regardless and carries a βˆ’100 reputation hit; repeated failed breaks can push personal_reputation under the auto-Wanted threshold (βˆ’500, per ../gameplay/police-forces.md). While breaking, the pilot is also engaged by the security squad (which the station dispatches on tractor activation).
  3. Be destroyed. The security squad attacks the locked ship; the player can fight back (combat resolves normally) but cannot escape. If the ship is destroyed, the standard destruction handler fires; if the pilot ejects to escape pod, the pod is locked too (Premium tier) or escapes (Basic / Standard tier).

The tractor lock applies only at undock. Players moving around inside the station, dining at the cafeteria, browsing the market β€” all unaffected. The tractor activates only when the engines fire to leave the docking ring.

Tractor strength tiers

  • Weak (Basic): 25% chance per turn that a 75%-engine break attempt succeeds; expected break time ~10 turns. Used by frontier-zone budget stations.
  • Strong (Standard): 10% chance per turn at 90% engine; expected break time ~20 turns. Used by typical Federation-zone stations.
  • Immobilizing (Premium): a break attempt costs the same investment as Strong (90% engine, ~20 turns) but rolls 0% chance per turn β€” the ship cannot escape under any circumstances. Used by Capital stations, Nexus Starport Prime, fortress-grade industrial hubs.

A team of players cannot stack break attempts β€” the tractor locks one ship at a time and the station can lock multiple ships independently. A coordinated extraction (decoy + tractor-cut sabotage) is πŸ“ future content; not at launch.

Docking fee economics

Docking fees are paid on the dock attempt, separate from any trade tariffs. They fund the station's security infrastructure (drones, guards, tractor beam upkeep) plus a cut to the owner.

Base fee structure

Ship size Base docking fee
Tiny (Escape Pod) 0 cr (free)
Small (Scout, Fast Courier) 100 cr
Medium (Light Freighter, Defender) 250 cr
Large (Cargo Hauler, Colony Ship, Warp Jumper) 500 cr
Capital (Carrier) 1,000 cr

Multiplied by the station's security tier:

Tier Multiplier
None 0Γ— (free dock; you get what you pay for)
Basic 1.0Γ— base
Standard 1.5Γ— base
Premium 3.0Γ— base

A Cargo Hauler docking at a Premium-tier Capital station thus pays 1,500 cr per dock. The fee is collected on dock-arrival (POST /api/v1/stations/{id}/dock) before the player is granted docking-ring access.

Fee distribution

Each docking fee is split three ways:

Bucket Share Purpose
Defense fund 40% Drone replenishment, guard wages, tractor-beam upkeep, security barracks operating costs
Owner cut 30% Goes to the player or team that owns the station; revenue flows into team treasury or player wallet
Operating cost 30% Station maintenance, faction taxes, ambient operating overhead

Operator-managed stations (Federation Capital, Nexus Starport Prime) split 70% defense / 30% operating with no owner cut β€” there is no owner. The operator-managed cut is sunk into the station's treasury for ambient infrastructure.

The owner can adjust the split within bounds (πŸ“): - Defense fund: 30%–60% (lower starves defenses; eventually downgrades the security tier) - Owner cut: 10%–50% (higher extracts more profit; eventually triggers Federation-faction attention if perceived as predatory) - Operating: fixed at 30% (non-negotiable)

Defense-fund accounting

The defense fund is tracked on Station.defense_budget (Integer, credits). Drone replenishment, guard wages, and tractor upkeep are paid from this budget on a daily tick.

Defense underfunding cascade (reconciled with ./port-ownership.md per ADR-0093): defense_pct < 0.35 (i.e. the defense bucket falls under 35% of revenue) defines underfunding. 3 consecutive deficit days β†’ the station auto-downgrades by one tier, with an owner warning notification fired on day 1 of the deficit. 7 consecutive deficit days β†’ the station downgrades to none, triggering a forced "your station is undefended" notification.

The owner can directly inject credits into the defense fund (POST /api/v1/stations/{id}/defense-budget/contribute) β€” useful for surge defense ahead of a known threat (e.g., a hostile team is staging in adjacent sectors).

Free-dock exemptions

A docking fee is waived for: - Owner of the station. - Owner's team-mates (configurable per station; defaults to free). - Allied-faction NPCs (e.g., Federation Marshals dock free at Federation-aligned stations). - Players with active docking contracts (πŸ“ future β€” pre-paid bulk docking deals).

The owner can add per-player exemptions via the station governance UI; abuse-prevention rate-limits per the warp-gate-toll bypass mitigation in DECISIONS SK10.

Schema impact

Station fields

Station schema (DATA_MODELS/stations.md) gains:

Field Type Notes
security_level Enum station_security_tier none / basic / standard / premium
defense_budget Integer Credits; ticks down daily by tier upkeep
tractor_strength Enum tractor_strength none / weak / strong / immobilizing (derived from security_level)
wanted_threshold Integer Personal-rep cutoff for tractor activation; default βˆ’500
deny_list_player_ids JSONB array Owner-set blocklist
fee_distribution JSONB {defense_pct: float, owner_pct: float, operating_pct: float} (sum = 1.0)

Station.security JSONB shape

A new Station.security JSONB column carries the live security state:

{
  "tier": "standard",
  "defense_drones_active": 8,
  "defense_drones_max": 8,
  "guard_npc_ids": ["<uuid>", "<uuid>"],
  "guard_captain_npc_id": null,
  "barracks_id": "<npc_barracks_uuid>",
  "tractor_lock_active": false,
  "tractor_locked_ship_id": null,
  "tractor_locked_at": null,
  "last_attack_at": null,
  "last_tractor_event_at": null
}

Updated by the security service on every drone replenishment, guard spawn / KIA, tractor activation / release, and incident response.

Sector and station relationships

Sector.defenses (per ../../DATA_MODELS/jsonb-schema.md) gains entries for station guards in the existing patrol_ships array β€” squad_kind = "station_security", faction_code = "<station_owner_or_faction>". Guards on patrol around the station's host sector are visible to players in that sector.

Off-duty guards' ships dock at the station's NPCBarracks and land in Sector.defenses.docked_npc_ships per the standard pattern β€” shielded from player attack like other off-duty NPC ships.

NPC lifecycle integration

STATION_SECURITY is added to the npc_archetype enum (per ../../DATA_MODELS/npcs.md). The lifecycle framework handles guard spawning, schedules (12-hour shifts), promotions (Guard β†’ Senior Guard β†’ Captain), KIA, and succession identically to other archetypes. The only differences: shorter respawn cooldown (3 days vs 7), station-funded rather than faction-funded (the station's defense_budget pays guard wages, not the faction treasury), and station-jurisdictioned (the host sector + 1-hop ring, not a regional patrol route).

Player-side experience

Honesty vs origin/feat 46bce720 (docs↔code status, not a new game rule). Design copy below is not unmarked live product.

A player docking at a Premium-tier Capital station:

  • On dock β€” security-tier banner πŸ“ design-only / not player-live. Example copy ("Docked at Capital Station Prime. Security tier: Premium. Guards on duty: 5. Defense drones: 12/12. Anti-theft tractor: armed.") is not rendered on tip. git grep "Guards on duty"|"Security tier" under player-client/src is empty; StatusBar title="Defense drones" is player-hull drone count, not a station dock banner. Do not read this as a live dock security banner.
  • Inside the station πŸ“ flavor / not verified player HUD β€” guards walking the docking ring, bar scenes. Market access and "no ship-attack risk while docked" follow the GS docked-ship protection path, not a dedicated in-station security UI.
  • On undock / stolen-ship tractor βœ… player-live β€” TractorLockPrompt.tsx plus stationSecurityAPI break/surrender routes; WS impound copy in WebSocketContext.tsx. Dialogue: "This vessel matches a stolen-report flag. Surrender, attempt break-free, or fight."

A player attempting to attack a docked ship at a protected station:

  • Targeting attempt βœ… GS shipped β€” rejected before any turn charge (ERR_DOCKED_SHIP_PROTECTED / WO-CB1). Do not invent a player toast beyond that GS error path.
  • Persistent attempts / guards engage the attacker πŸ“ design-only β€” named-guard roster wiring is still πŸ“ (see Status); do not treat as player-live.

A station owner security monitoring pane (live tier, named guard roster, defense budget + 7-day burn, incidents log, tier upgrade controls) is πŸ“ design-only / not player-live on 46bce720 β€” no player-client wiring for that pane. Matches Status (defense_budget column + named-guard roster still πŸ“).

Player-facing affordances

  • βœ… Anti-theft tractor lock on undock β€” TractorLockPrompt.tsx + stationSecurityAPI break/surrender routes; GS check_tractor_lock at undock (trading.py); WS impound copy in WebSocketContext.tsx (origin/feat 5f4d750c).
  • βœ… Docked-ship attack block β€” GS rejects targeting docked ships at protected stations with ERR_DOCKED_SHIP_PROTECTED (combat_service.py:933-955, WO-CB1).
  • πŸ“ On-dock security-tier banner β€” example copy in Β§ Player-side experience is design-only; git grep "Guards on duty"|"Security tier" under player-client/src empty on tip.
  • πŸ“ Owner security monitoring pane β€” tier roster, defense budget burn, incidents log, tier upgrade controls not wired in player-client on tip.
  • πŸ“ Named-guard roster / STATION_SECURITY patrol UI β€” archetype declared; no player-visible guard roster or barracks wiring on tip.

Status

🚧 Partial. The security-tier + anti-theft tractor-lock core is βœ… shipped: Station.security JSONB (models/station.py:371) backs the security_level property (station.py:441, tier string via security_tier_rank) and a full station_security_service.py (get/upgrade/downgrade tier, tractor_lock_reason/check_tractor_lock/attempt_tractor_break/surrender_tractor_locked_ship, per-ship security["tractor_locks"] entries), routed at POST/GET /stations/{id}/... (api/routes/station_security.py, registered api/api.py:163) and enforced at the real undock choke point β€” check_tractor_lock is called from api/routes/trading.py:2005. Guarantee #1 attack-targeting block against docked ships at a protected station is also βœ… shipped (combat_service.py:933-955, ERR_DOCKED_SHIP_PROTECTED / WO-CB1 β€” rejects before any turn charge when defender_station.security_rank >= SECURITY_TIER_PROTECTED_MIN_RANK). The Station.defenses JSONB (defense_drones / auto_turrets / defense_grid / shield_strength / patrol_ships / military_contract, v1 schema) stays the separate station-vs-ship siege-infrastructure block per ./port-ownership.md β€” security is the docked-ship-protection/anti-theft block; the two are complementary, both funded from station revenue, different threats. Still πŸ“ design-only: a dedicated defense_budget column (port_ownership_service.py flags it as a "would be cleaner" future field, not present today), the named-guard roster wiring (the NPCBarracks model exists at models/npc_barracks.py from WO-BUILD-NPC-LODGING-FOUNDATION, but is not yet linked into Station.security β€” no barracks_id / guard_npc_ids / guard_captain_npc_id fields β€” and the STATION_SECURITY archetype has no wage/roster consumer yet per station_security_service.py:64), and the dock/undock flavor dialogue. The STATION_SECURITY NPC archetype is declared in the enum (models/npc_character.py:74) but still has no consumer. (Re-verified 2026-08-20 vs Sectorwars2102 5f4d750c β€” PF section added; dock banner + owner pane + named-guard roster remain design-only. Prior "no protected-station gate / no NPCBarracks model" Status claims are stale; attack-block shipped, model exists, guard-roster wiring remains the gap. See Β§ Player-facing affordances.)

Cross-references