Police Forces¶
Two NPC-only enforcement bodies patrol the universe's protected spaces. Each is staffed by named individual NPCs of the LAW_ENFORCEMENT archetype within the wider NPC lifecycle framework — real persistent characters with single-place presence (one sector at a time), full daily schedules (8h patrol / 8h off-duty / 8h sleep), career progression (recruit → active → senior → decorated → retirement / KIA / succession), names players come to know, and identities that survive across encounters. Each force flies a special-issue Interdictor hull that no player can ever own — the Federation Marshal Interdictor for the Federation Police, the Nexus Sentinel Interdictor for the Sentinel Corps. Their job is to give the universe's positive-aligned spaces real teeth — Wanted Status, contraband detection, and protected-sector invariants stop being theoretical the moment a named Marshal or Sentinel arrives and intercepts.
Officers aren't anonymous squad slots and they aren't 24/7. Marshal Cassandra Vance patrols sectors 12–47 of your home region from 06:00–14:00 UTC; she's off-duty at the Capital station from 14:00–22:00, and asleep from 22:00–06:00. If you commit a crime in sector 47 at 03:00 UTC, she's not there — engagement-routing dispatches whoever is on shift. Sentinel-Captain Lyra Kett stands guard in Gateway Plaza on a different shift schedule that overlaps Vance's by design. Each region has its own roster of named officers across staggered shifts so coverage is continuous.
The data model lives in ../../DATA_MODELS/npcs.md; the lifecycle framework (schedules, career arcs, succession) lives in ../../SYSTEMS/npc-lifecycle.md; the scheduler that moves NPCs between sectors and routes engagement responses is in ../../SYSTEMS/npc-scheduler.md. Police are one specific archetype within that framework; pirates, station officials, traders, faction leaders, and other NPC types use the same lifecycle layer with different schedule templates and behavior trees.
Two forces at a glance¶
| Force | Jurisdiction | Affiliation | Mandate | Special-issue hull |
|---|---|---|---|---|
| Federation Police | Federation Zone of every region (sectors 1..floor(0.33 × total_sectors)) and all of Terran Space |
Terran Federation | Enforce Wanted Status, contraband interdiction, attacks-on-innocents response | Federation Marshal Interdictor |
| Nexus Sentinel Corps | Central Nexus (entire region, all 5,000 sectors) | Galactic Concord (operator-managed authority; not a player-targetable faction) | Protect Nexus governance, prevent warp-gate construction in protected sectors, intercept hostile inbound traffic, defend the Capital | Nexus Sentinel Interdictor |
Both forces are positive-aligned (lawful, not adversarial-by-default) — they leave compliant players alone. Players who keep a clean rep, dock with valid pins, and route around protected-sector restrictions never see one. Players who cross a line see the squad arrive, the Interdictor field engage, and a real combat encounter that ends with arrest, fine, or destruction depending on severity.
The two forces never share jurisdiction: a player in the Federation Zone of a player-owned region sees Federation Police only; a player in the Central Nexus sees Sentinels only. The two never coordinate operations and don't share intelligence — Federation Police records of a player's Wanted Status do not propagate into Nexus Sentinel pursuit (and vice versa). This is intentional: Federation enforcement is about player-level alignment; Nexus enforcement is about hub-level invariants.
Federation Police¶
Jurisdiction¶
Operates in the Federation Zone of every region (the first 33% of sector numbers per ../galaxy/sectors.md) plus the entirety of Terran Space (all 300 sectors are effectively Federation-policed at policing 9). The starter cluster (sectors 1..fedspaceSize, default 10) is the densest patrol coverage. Border and Frontier zones are out of jurisdiction — Federation Police never spawn there.
Engagement triggers¶
A Federation Police squad spawns and engages a player when any of the following fires inside its jurisdiction:
- Wanted Status active —
Player.personal_reputation < −500(Outlaw / Pirate / Criminal / Public Enemy tiers per./factions-and-teams.md#reputation-scale) or an active stolen-ship report on the player's current ship per SYSTEMS/ship-registry.md. - Attack on an innocent — an
attack_innocentreputation trigger fires (target had no bounty, defender was not Wanted) per./factions-and-teams.md. The squad arrives within 2 turns of the attack resolving — see Engagement dispatch and the 2-turn spawn delay below. - Contraband detected — the player carries
hazardous_transportcargo (per../economy/black-market.md) and is scanned by a passing patrol. Detection probability scales with the player'sShip.evasion(high evasion = lower detection rate). - Protected-sector incursion — the player breaches a Federation-protected sector with hostile intent (e.g., attempts to attack a Federation-flagged station's docked ships).
The squad does not engage on a Wanted player who keeps moving without committing a new offense — Wanted Status is the predicate for engagement, not a one-shot bounty trigger. The squad spawns when an offense fires, pursues until the player exits Federation jurisdiction, is destroyed, or surrenders.
Engagement dispatch and the 2-turn spawn delay¶
When an offense fires, engagement-routing commits the responding officer immediately but the squad's arrival is gated on the offending player consuming 2 turns. Delay is measured in the offender's own turn consumption — turns spent on movement, combat, or trade — not wall-clock time, so the chase stays in the game's native time unit. This gives the offender a real tactical window between the offense and the intercept.
Dispatch proceeds in two phases:
- Commit (at offense time). The router picks the eligible Marshal(s) per the routing rules (nearest-by-warp-hop, squad composition per offense severity) and atomically flips them to
engaged_pending_arrival. Theircurrent_sector_iddoes not change yet. APendingEngagementrow records(player_id, offense_sector_id, npc_squad_ids[], offense_at_turn_count, arrival_turn_threshold = offense_at_turn_count + 2), and the player client renders a "police en route" banner counting down the 2 remaining turns ("Marshal Vance is en route — 2 turns to arrival"). - Arrival (after 2 turns). When the player's
cumulative_turn_countreachesarrival_turn_threshold, the squad spawns in whatever sector the player is currently in — not the offense sector. This is the canonical "the police chase you" semantic: the squad'scurrent_sector_idis set to the player's current sector,statusflips toengaged, and the squad is handed to the combat resolver.
The engaged_pending_arrival status is distinct from engaged so a committed-but-not-yet-arrived Marshal is excluded from new offense responses — a Marshal already pending an arrival cannot be picked for a second offense; that offense falls through to the per-player cooldown or to a different officer.
A per-player offense cooldown of 5 turns applies between accepted offenses of the same type (attack_innocent, contraband_scan_hit, etc.). Offenses inside the cooldown still fire reputation hooks but do not dispatch a new squad — the existing pending or active squad's pursuit covers them. Different offense types stack normally, each with its own dispatch and its own per-type cooldown. This prevents griefing the routing system by stacking offenses faster than squads can arrive.
Jurisdiction exit before arrival. If the player exits Federation jurisdiction before the threshold is reached, the engagement resolves immediately on the boundary cross as jurisdiction_exit: the committed Marshals revert to on_duty, the PendingEngagement row is deleted, and personal reputation drops by −25 for evading arrest (see Engagement outcomes). Fleeing across a region boundary within 2 turns is a viable escape with this real reputation price.
Disconnect and expiry. If the player disconnects, the turn watcher pauses and the PendingEngagement row persists; on reconnect the watcher resumes from the player's then-current turn count. A pending engagement that sits idle for more than 24 hours of wall-clock time expires — the held Marshals release back to on_duty and a fresh squad spawns on the next offense. The 24-hour cap also bounds the worst case for a player who consumes turns very slowly.
PendingEngagement is a durable table row, not an in-memory queue, so dispatches survive scheduler restarts. The scheduler's Loop A sweeps pending rows to discharge any whose arrival threshold is reached, clear any whose player has exited jurisdiction, and expire any stale enough to release their held Marshals.
Roster, lodging, and squad composition¶
Each non-Nexus region has a permanent roster of named Federation Marshals maintained by the NPC scheduler:
- 8 Marshals + 1 Marshal-Captain per Standard-tier player region (target counts in
NPCRoster; tunable per region size). - 12 Marshals + 2 Marshal-Captains in Terran Space.
- Lodging: a single
NPCBarracksrow at the region's Capital station; capacity 9 (8 Marshals + 1 Captain).Station.services.npc_barracks = trueflags the Capital as a barracks host. Marshal-Captains who are promoted out of the shared barracks (📐 future) get a private-quartersNPCBarracksrow (capacity 1) at the same station. - Ship parking: each Marshal has a permanent 1:1 Marshal Interdictor assignment. When off-duty, the Interdictor docks at the Capital station and lands in
Sector.defenses.docked_npc_shipswithstatus = "docked_off_duty"— shielded from player attack while there. Auto-maintenance during sleep blocks repairs the hull to 90% if it dropped below 75%. - Shift overlap: consecutive Marshal shifts overlap for 30 minutes so the outgoing officer can brief the incoming officer (
shift_handoff_stateJSONB on the squad row passes threat notes about active investigations / Wanted players / pending pursuits). During the overlap, both Marshals are visible in the same patrol-route sectors withcurrent_activity = shift_handoff.
Each Marshal is a persistent NPCCharacter row — name, title, backstory, current sector, assigned Marshal Interdictor ship. They patrol on a 4-hour-per-sector cycle through 4–6 sectors of the region's Federation Zone, with ~20% off-duty rotation at any given time. Players in the Federation Zone may encounter the same Marshal repeatedly across sessions; engagement-routing picks the nearest available Marshal (not a fresh anonymous squad). Killing a Marshal removes that named individual from the roster permanently — a different named Marshal takes the seat after a 7-day cooldown.
Squad composition for an engagement scales with the offending player's threat tier and dispatches the named Marshals in pursuit:
| Threat tier | Player rep tier | Squad composition |
|---|---|---|
| Low | Suspicious / Questionable | 1 named Marshal |
| Medium | Smuggler / Outlaw | 2 named Marshals (nearest two) |
| High | Pirate / Criminal | 3 named Marshals + 1 NPC Defender escort |
| Public Enemy | Public Enemy | 3 named Marshals + 2 NPC Defender escorts |
The named threat tiers above are a descriptive shorthand. The decision variable the engagement router actually keys on is the player's personal alignment (Player.personal_reputation), graded by the 8-tier REPUTATION_TIERS scale in services/gameserver/src/services/personal_reputation_service.py (Villain / Criminal / Outlaw / Suspicious on the negative side) — not the separate 17-level per-faction ReputationLevel enum (services/gameserver/src/models/reputation.py) whose names (Questionable, Smuggler, Pirate, Public Enemy) the threat-tier column borrows. The two are distinct systems: personal alignment is a single signed score per player; ReputationLevel is a player's standing with one faction. Police squad scaling reads personal alignment only.
_federation_squad_size in services/gameserver/src/services/npc_engagement_service.py maps personal_reputation onto squad size at three thresholds, which canonically reconcile the named threat tiers to the live alignment bands as follows:
| Threat tier | personal_reputation band |
REPUTATION_TIERS name |
Named Marshals | Captain joins |
|---|---|---|---|---|
| Low | −249 … −1 (and ≥ 0) |
Suspicious / Neutral+ | 1 | no |
| Medium | −499 … −250 |
Outlaw | 2 | no |
| High | −749 … −500 |
Criminal | 3 | no |
| Public Enemy | ≤ −750 |
Villain | 3 | yes |
So "Smuggler / Outlaw" (Medium) corresponds to the Outlaw band crossing −250; "Pirate / Criminal" (High) to the Criminal band crossing −500; and "Public Enemy" to the Villain band crossing −750, which is also the only tier where the Marshal-Captain auto-joins (include_captain). The Wanted-Status engagement predicate in the trigger list above (personal_reputation < −500) sits at the High/Public-Enemy boundary on this same scale.
The escort NPCs in the table (📐 Design-only) are not yet dispatched — route_engagement commits only named officers today, so a High or Public-Enemy squad arrives as 3 (or 3 + Captain) named Marshals with the escort hulls flagged as a later slice. The escort NPCs (Defender / Light Freighter NPCs) are anonymous fleet support — only the Marshals carry persistent identity. The Marshal-Captain is the regional head; they personally respond to Public Enemy tier engagements and to any direct attack on a Marshal.
If every Marshal in the region is engaged, off_duty, or KIA, response falls back to the scheduler's regional grace window (5–15 minutes before the next available Marshal arrives) — see ../../SYSTEMS/npc-scheduler.md#engagement-routing. This is the canonical answer to "what if a player wipes out the Federation Police?" — they get a small window of effective lawlessness, then a new named Marshal takes over.
Engagement outcomes¶
When a Federation Police squad catches a player, three resolutions are possible:
- Surrender — player declines combat, accepts a credit fine (~10–25% of cargo value, scaled by offense severity) plus a +5 personal reputation nudge for compliance, and is released. The arrest is logged.
- Successfully flee — player escapes via Slipdrive, Quantum Jump, exiting the Federation Zone boundary, or destroying the squad. Personal reputation drops further (−25 for "evade arrest"). Squad de-spawns; a fresh squad respawns on next offense.
- Destruction — squad wins the combat. Player is destroyed normally per the canonical destruction handler. The player's cargo is confiscated to a Federation depot (📐 Design-only — recoverable via reputation rehabilitation), insurance pays out per
InsuranceTyperules.
Federation Police squads do not issue bounties on themselves and are not eligible bounty-collection targets. Killing a Marshal Interdictor crashes the player's Federation reputation by −250 per kill and immediately escalates the response squad.
Nexus Sentinel Corps¶
Jurisdiction¶
Operates in the Central Nexus exclusively. All 5,000 Nexus sectors are policed; the Gateway Plaza cluster (containing the Nexus Capital at sector 2251) carries the densest patrol coverage.
The Sentinel Corps does not operate in player-owned regions, Terran Space, or the Federation Zones of any player region — that's Federation Police's job. A player who flees a Sentinel pursuit by warping into a player region exits Sentinel jurisdiction (the squad does not pursue across the Nexus boundary).
Engagement triggers¶
The Sentinel mandate is hub-level invariant protection, not personal-rep policing. Triggers:
- Warp-gate Phase 1 deployment in a protected Nexus sector. This is the load-bearing case. Phase 1 of warp-gate construction (
POST /api/warp-gates/deploy-beaconper../galaxy/warp-gates.md) in any Nexus sector flaggedis_nexus_protected = true(✅ Shipped column, defaulttruefor the Capital sector 2251 and all sectors in the Gateway Plaza cluster, plus operator-configured additions) triggers immediate Sentinel response. The beacon deployment is rejected at the API layer — but the spawn fires anyway, so a player who attempts the deployment via direct DB manipulation or finds a validation bypass is intercepted. - Hostile combat in protected Nexus sectors. Any combat initiation against another player or a Nexus station inside a
is_nexus_protectedsector spawns a Sentinel squad regardless of the attacker's rep tier. - Contraband transit through the Nexus Capital. Same detection model as Federation Police — probability scales with
Ship.evasion. - Capital-sector incursion at Gateway Plaza. Any attempt to attack the Capital welcome planet (the TERRA planet at sector 2251 per ADR-0014) or to dock at Starport Prime with a Wanted-Status pilot.
- Smuggling Quantum Crystals in bulk through the Nexus (📐 Design-only) — bulk-Crystal transit is treated as preparation for unsanctioned gate construction and triggers a stop-and-search.
The Sentinel Corps does not engage on the standard Wanted Status reputation tiers — a player can be Public Enemy under Federation rep and still transit the Nexus unmolested as long as they don't trigger one of the above hub-invariant triggers. (Federation Police can't pursue across the Nexus boundary, and Sentinels don't enforce Federation rep — so the Nexus is a partial sanctuary for Wanted players who behave themselves while inside.)
Roster, lodging, and squad composition¶
The Central Nexus has a permanent Sentinel Corps roster maintained by the NPC scheduler:
- 24 Sentinels + 4 Sentinel-Captains in the Nexus (a single 5,000-sector region needs proportionally more officers than a player region).
- Lodging: a dedicated
NPCBarracksrow in a Gateway Plaza cluster sector — the Sentinel barracks sector — separate from Starport Prime so player traffic at the Capital isn't crowded by 28 docked Interdictors. The galaxy generator's Phase 12.5b setsSector.is_npc_barracks_sector = trueon this sector. Capacity 28; advisory (overflow logged). - Ship parking: each Sentinel has a permanent 1:1 Sentinel Interdictor assignment. When off-duty, the Interdictor docks at the Sentinel barracks sector and lands in
Sector.defenses.docked_npc_shipswithstatus = "docked_off_duty"— shielded from player attack while there. Auto-maintenance during sleep blocks repairs the hull to 90% if it dropped below 75%.
Each Sentinel is a persistent NPCCharacter row patrolling a 3-hour-per-sector cycle through 4–6 Gateway Plaza or adjacent-cluster sectors, with off-duty rotation at the Sentinel barracks (📐 Design-only — a designated rest sector in the Gateway Plaza cluster). Sentinel-Captains rotate through Gateway Plaza and the high-traffic clusters (Commerce Central Hub, Diplomatic Quarter).
A Sentinel response is always 4 named Sentinels dispatched by the scheduler. The dispatch picks the nearest 4 on-duty Sentinels in the Nexus by warp-graph hop distance from the offense sector. There is no scaling table — the Sentinel Corps treats every protected-sector violation as the same severity (the trigger itself is the severity grade).
If a Wanted-Status player attempts a warp-gate Phase 1 deployment in the Nexus Capital sector, the engagement routing dispatches Sentinel-Captain Lyra Kett (or whoever currently holds the Captain role) plus the 3 nearest Sentinels — the Captain personally handles every Capital-sector breach.
Killing a Sentinel removes the named individual permanently with the standard 7-day respawn cooldown. The escalated response (4 → 6 Sentinels) per the original police-forces.md design is now: dispatch the standard 4, plus the next 2 nearest Sentinels who would have been on patrol. The total is 6 named Sentinels in the engagement, drawn from the live roster.
Engagement outcomes¶
Same three-outcome model as Federation Police (surrender / flee / destruction), with one critical difference: a Sentinel intercept of a warp-gate Phase 1 deployment is non-negotiable. The player cannot surrender the deployment — the squad's mandate is to prevent the gate from existing, not to fine the player. The Phase 1 materials (turns, credits, ORE, EQUIPMENT, Crystal) are sunk. The player can still surrender the combat afterward (and pay a fine) or attempt to flee, but the gate construction is over the moment the Sentinels arrive.
This is the canonical answer to "what stops a player from anchoring a warp gate at the Nexus Capital": the Sentinel Corps. The Phase 1 API rejection is the first line of defense; the Sentinel intercept is the backup that makes the rejection load-bearing even if the validation has a bug or bypass.
Killing a Sentinel Interdictor crashes the player's standing with the Galactic Concord (📐 Design-only operator-managed faction; not in the standard 8-NPC-faction list) and triggers an escalated Sentinel response (4 → 6 Interdictors). Players cannot become friendly with the Galactic Concord — it has no positive reputation triggers. Negative standing only.
Interdictor hulls¶
Both ships are NPC-only special-issue hulls. They do not appear in the player-facing ship roster (ship-roster.md). Players cannot purchase, capture, salvage, or claim them — destruction creates no Cargo Wreck, and disabled-but-intact Interdictor abandonment is technically possible but the registry rejects player ownership transfer with ERR_NPC_ONLY_HULL.
Both Interdictors carry a unique Interdictor Field ability: when the field engages, the targeted player ship's WarpTunnel.turn_cost reads are clamped to infinity for 3 combat rounds. The targeted ship cannot warp out, cannot Quantum Jump (cooldown still ticks down but commit is rejected), and cannot use a player warp gate. The Interdictor Field also disables Slipdrive for the duration. The targeted ship can still fight, surrender, or attempt to escape via sector-edge proximity — but the easy outs are closed.
The Field is single-target per Interdictor — a 3-Marshal squad can pin three different ships, but a single ship is only pinned by one Field at a time (no stacking).
Federation Marshal Interdictor¶
| Stat | Value |
|---|---|
| Hull | 1,200 |
| Shields | 800 |
Speed (current_speed) |
1.5 |
| Evasion | 35 |
| Scanner range | 6 |
| Attack rating | 35 |
| Defense rating | 50 |
| Default weapon | Laser |
| Special abilities | Interdictor Field (3-round target lock); Contraband Scanner (probabilistic detection of hazardous_transport cargo) |
| Hull class | NPC-only npc_marshal_interdictor (extends ShipType enum); never serialized to player-facing ShipType lists |
The Marshal Interdictor is built for sustained pursuit through Federation Zone sectors. It outguns a Defender in 1v1 combat but loses to a Carrier; its design intent is "police squad backed by Federation Navy when needed", not "fleet flagship." The Contraband Scanner triggers on every sector entry while in jurisdiction; detection probability per scan is 0.3 / max(1, target.evasion / 10).
Nexus Sentinel Interdictor¶
| Stat | Value |
|---|---|
| Hull | 1,500 |
| Shields | 1,000 |
Speed (current_speed) |
1.5 |
| Evasion | 40 |
| Scanner range | 7 |
| Attack rating | 40 |
| Defense rating | 60 |
| Default weapon | Plasma |
| Special abilities | Interdictor Field (3-round target lock); Beacon Disruptor (cancels in-progress warp-gate Phase 1 within 1 sector on engagement); Concord Authorization (no toll on any warp gate, no whitelist requirement) |
| Hull class | NPC-only npc_sentinel_interdictor (extends ShipType enum); never serialized to player-facing ShipType lists |
The Sentinel Interdictor is tougher than the Marshal — its mandate is hub-level governance, and the squad must hold the line even against well-equipped player gate-builders sacrificing Warp Jumpers. The Beacon Disruptor is the unique signature ability: it cancels an in-progress warp-gate Phase 1 deployment in the engaged sector or any adjacent sector, refunding nothing to the player. Combined with the Interdictor Field, a single Sentinel can stop a gate-build attempt cold. The squad of 4 ensures the response is overwhelming even if one Interdictor is destroyed.
The Concord Authorization is a quality-of-life detail: Sentinels never pay tolls on player warp gates and never trigger access-control rejections, so a Sentinel pursuit cannot be evaded by ducking through a gate the Sentinels would normally be barred from.
Schema impact¶
Named-NPC integration¶
Both forces use the named-NPC schema at ../../DATA_MODELS/npcs.md. Each Marshal and Sentinel is a persistent NPCCharacter row with a stable identity, current sector, and assigned ship. The runtime scheduler (../../SYSTEMS/npc-scheduler.md) handles patrol movement, engagement routing, off-duty rotation, KIA processing, and roster maintenance.
Roster targets per region (in NPCRoster):
| Region kind | Faction | Role | Target count |
|---|---|---|---|
| Player-owned | Terran Federation | marshal |
8 |
| Player-owned | Terran Federation | marshal_captain |
1 |
| Terran Space | Terran Federation | marshal |
12 |
| Terran Space | Terran Federation | marshal_captain |
2 |
| Central Nexus | Galactic Concord | sentinel |
24 |
| Central Nexus | Galactic Concord | sentinel_captain |
4 |
Patrol-squad row coherence¶
The existing Sector.defenses.patrol_ships JSONB shape is extended with an npc_character_ids array that points at the specific named NPCs currently in the sector. The legacy ship_count field is preserved as a denormalized read-fast path (len(npc_character_ids)).
{
"patrol_id": "<uuid>",
"faction_code": "terran_federation" | "galactic_concord",
"squad_kind": "federation_marshal" | "nexus_sentinel",
"npc_character_ids": ["<npc-uuid-1>", "<npc-uuid-2>", "<npc-uuid-3>"],
"ship_count": 3,
"wanted_threshold": -500,
"deployed_at": "<iso8601>",
"scheduled_clear_at": null
}
The scheduler maintains a hard invariant: every NPC in npc_character_ids has current_sector_id matching the row's parent sector. When a Marshal moves on patrol, the scheduler atomically updates both the prior sector's squad row and the new sector's squad row, plus the per-NPC current_sector_id. Players see the Marshal arrive via realtime npc_arrived events.
squad_kind accepts the values federation_marshal and nexus_sentinel — the canonical patrol-kind enumeration in DATA_MODELS/jsonb-schema.md is extended accordingly.
Sector protection flag¶
A new boolean column Sector.is_nexus_protected (✅ Shipped) flags Nexus sectors that trigger the Sentinel response on warp-gate Phase 1 deployment. Default false. The galaxy generator's Phase 8 (long-distance warp tunnels) is extended to set is_nexus_protected = true on:
- The Nexus Capital sector (sector 2251).
- All sectors in the Gateway Plaza cluster (sectors 2251–2500 per
../../SYSTEMS/central-nexus-clusters.md). - A future operator-tunable list (likely Commerce Central Hub, Diplomatic Quarter, and other high-traffic Nexus clusters — to be tuned post-launch).
The same flag is read by POST /api/warp-gates/deploy-beacon in the Phase 1 validation path; deployment is rejected with ERR_NEXUS_PROTECTED_SECTOR before the Sentinel intercept fires.
Faction registration¶
The Galactic Concord is added as a 9th NPC faction (operator-managed, no player rep gain mechanics). Faction.faction_type = CONCORD is a new enum value (📐 Design-only — extends ADR-0033's MINING precedent). Faction.code = "galactic_concord".
The Federation Police are not a separate faction — they're the enforcement arm of the existing Terran Federation. Their patrol entries carry faction_code = "terran_federation"; their squad_kind = "federation_marshal" distinguishes them from generic Federation patrols.
NPC-only hull classes¶
ShipType enum extended with two NPC-only values:
NPC_MARSHAL_INTERDICTOR(✅ Shipped).NPC_SENTINEL_INTERDICTOR(✅ Shipped).
Both are filtered from any player-facing API that lists ship types (GET /api/v1/ships/types, the construction UI, the TradeDock catalog). The filter lives at the serializer layer; the model itself can hold them via the standard Ship table.
ShipSpecification.is_npc_only = true for both hull classes (✅ Shipped column). When set, the model layer rejects any registry-event that would transfer the ship to a player (ERR_NPC_ONLY_HULL).
Player interactions¶
Common-case rules of engagement¶
A compliant player should never see either force engage them. The mental model the docs should give players:
- "Stay out of trouble in Federation space — Federation Marshals don't bother lawful pilots."
- "Don't try to plant a warp gate at the Nexus Capital — the Sentinels will intercept and there's no negotiation."
- "If you're Wanted, the Federation Zone is dangerous; the Nexus is partially safer (Sentinels don't enforce personal rep) but still off-limits to anything that touches their hub-invariant triggers."
Nexus as a partial sanctuary for Wanted players¶
The deliberate design choice — Sentinels don't enforce personal reputation — gives Wanted players a transit route through the Nexus that Federation Police can't follow into. This is by design: the Nexus is the universal trade hub, and locking Wanted players out of it would degrade the hub's economic role. The price is that Wanted players cannot interact with the Nexus's protected-sector functions (warp-gate construction, Capital combat) — they can transit, trade, refuel, and leave.
A Wanted player attempting to transit the Federation Zone of a player region to reach the Nexus warp gate will get intercepted by Federation Police at some point during that transit; reaching the Nexus warp gate is itself the challenge. This is the intended pressure.
Bounty interaction¶
Players cannot place bounties on Interdictor hulls (the bounty-placement endpoint rejects with ERR_BOUNTY_NPC_ONLY_TARGET per ./bounties.md — 📐 Design-only validation). Players who destroy a Federation Marshal Interdictor or Nexus Sentinel Interdictor receive no bounty payout (the system-bounty path doesn't fire on NPC-only kills).
Generator integration¶
The galaxy generator's Phase 12.5 (per ../../SYSTEMS/galaxy-generator-design.md) hands off to the NPC scheduler rather than stamping anonymous patrol squads:
- Phase 12.5a — Region rosters (bang-stamped per ADR-0069). For each non-Nexus region,
NPCRosterrows with the target counts from the table above are emitted bysw2102-bangin the Universe payload and persisted by the gameserver on import (see../../SYSTEMS/bang-import-pipeline.md#135-import-npc-rosters). The scheduler's Loop B (roster maintenance) handles the actual NPC creation at runtime — bang and the gameserver do not create individualNPCCharacterrows. - Phase 12.5b — Nexus rosters (bang-stamped per ADR-0069).
NPCRosterrows for the Sentinel Corps are emitted bysw2102-bangand persisted by the gameserver on import. The gameserver setsSector.is_nexus_protected = trueon the Capital sector and Gateway Plaza cluster sectors during the import. - Phase 12.5c — Initial NPC bootstrap (post-import hook, gameserver-side). After the import transaction commits, the gameserver fires a one-time
npc_scheduler.bootstrap_region(region_id)call that spawns the initial roster of named NPCs from thename_poolof eachNPCRoster. This step happens outside the worldgen transaction so a roster-spawn failure doesn't block region creation; if it fails, Loop B picks up the slack on its next 10-minute tick.
Putting NPC creation behind the scheduler (rather than baking it into worldgen) means an operator can rebalance roster sizes, change name pools, or promote a Marshal to Captain without regenerating a region. The data model rule is clear: NPCRoster is worldgen-stamped; NPCCharacter is runtime-managed.
Status¶
🚧 Partial. Both police forces, the two Interdictor hull classes (Federation Marshal Interdictor and Nexus Sentinel Interdictor), the
Sector.is_nexus_protectedflag, theFaction.faction_type = CONCORDenum value, theShipSpecification.is_npc_onlyboolean, the Interdictor Field / Beacon Disruptor / Contraband Scanner abilities, and the Phase 12.5 generator extension are at mixed maturity. The Interdictor hull classes, theShipSpecification.is_npc_onlyboolean, theSector.is_nexus_protectedflag and its Phase 1 deploy-beacon rejection, the named-NPC rosters and scheduler-driven engagement routing, and the Marshal-kill Federation reputation hook are enforced in code; theFaction.faction_type = CONCORDenum value and Galactic Concord faction, the Interdictor Field / Beacon Disruptor / Contraband Scanner abilities, and the full Phase 12.5 generator extension are design targets with no behaviour wired. The existingSector.defenses.patrol_shipsJSONB shape is the integration point — squad records land there as the spawn / engagement / runtime services come online.
Cross-references¶
./factions-and-teams.md— reputation triggers, factional jurisdiction, Wanted Status definitions../faction-lore.md— Terran Federation lore that the Federation Police extend../bounties.md— bounty system that does not apply to Interdictor-hull kills../ship-roster.md— player-facing ship catalog (Federation Marshal and Nexus Sentinel Interdictors are absent)../ranking.md#wanted-status— Wanted Status mechanics that gate Federation Police engagement.../economy/black-market.md— contraband definitions used by the Contraband Scanner.../galaxy/warp-gates.md— Phase 1 deploy-beacon flow that the Sentinel Corps polices.../../SYSTEMS/central-nexus-clusters.md— Gateway Plaza cluster definition.../../SYSTEMS/galaxy-generator-design.md— Phase 12 / 12.5 patrol pre-seeding integration.../../SYSTEMS/sector-presence.md— encounter triggers (_check_for_encounters) that read the patrol_ships entries.../../DATA_MODELS/jsonb-schema.md—Sector.defenses.patrol_shipsshape extended with newsquad_kindvalues.../../DATA_MODELS/ships.md— ShipType enum extended with NPC-only Interdictor variants.- ADR-0033 —
FactionTypeenum expansion precedent for the newCONCORDvalue. - ADR-0034 — Capital-SCC reachability invariant that the Sentinel Corps backstops.