Skip to content

Station

A Station is a persistent structure in space owned by a faction. Stations contain modules (production, docks, defence, habitation), employ NPCs, trade wares, and serve as hubs for ship operations.

Subtypes: Shipyard, Wharf, Equipment Dock, Trade Station, Defence Station, Production Factory, Pirate Base, Player Headquarters.

Contains: Modules, Dockareas, Build plot.

Most common accessors used by vanilla MD scripts and mods.

PropertyTypeDescription
.faction / .ownerfactionCurrent owning faction
.trueownerfactionTrue owner — differs from .faction during boarding/capture
.knownnamestringDisplay name
.sectorsectorContaining Sector
.zonezoneContaining Zone
.moduleslistAll Modules of this station
.containercontainerAggregate inventory and value
.container.valueint (Cr)Total value of modules + drones
.cargocontainerCargo inventory
.cargo.listlistList of wares in cargo
.buildplotbuildplotBuild plot info
.buildplot.priceint (Cr)Build plot price
.dockingbayslistDocking bays
.crewlistNPC crew
.workforceintCurrent workforce
.maxworkforceintMaximum workforce
.controlpost.managernpcStation manager NPC
.istradestationboolIs a trade station
.isfactionheadquartersboolIs a faction HQ
.isplannedshipyardboolIs a planned shipyard
.isplannedwharfboolIs a planned wharf
.isplanneddefencestationboolIs a planned defence
.hasfixedconstructionboolHas fixed construction (cannot extend)
.hasstagedconstructionboolHas staged construction (X4 9.0+)
<create_station name="$myStation"
macro="..."
faction="..."
object="$sector"
position="[x, y, z]"/>
<set_owner object="$station" faction="faction.player"/>

For ships, use md.LIB_Generic.TransferShipOwnership (handles fleet detachment). For stations, <set_owner> is typically sufficient — but verify subordinate ship behaviors with your specific scenario.

<destroy_object object="$station"/>
<find_station_by_true_owner name="$stations"
faction="faction.argon"
space="player.galaxy"/>
<do_if value="not $station.isplanneddefencestation
and not $station.isplannedshipyard
and not $station.isplannedwharf
and not $station.istradestation
and not $station.isfactionheadquarters">
<!-- this is a normal production/storage station -->
</do_if>

This is the filter used by the Buy and Sell Stations mod to identify stations the player can buy or sell.

Vanilla helpers for working with stations. Source: md/lib_generic.xml.

LibraryPurposeSource line
md.LIB_Generic.FindNearestStationForFactionClosest station of given faction1240
md.LIB_Generic.FindStationsForFactionByDistanceAll stations sorted by distance1270
md.LIB_Generic.TransferStationOwnershipTransfer with cleanup1559
md.LIB_Generic.SetStationMinHullSet hull floor2971
md.LIB_Generic.RequestObjectInvincibilityMark indestructible3522
md.FinaliseStations.NewStation_GenerateFactory_SignalPublic API for finalizing a created stationfinalisestations.xml:192

Events that fire about stations.

EventWhenNotes
event_object_destroyedStation destroyedFilter by event.object.isclass.{class.station}
event_object_changed_ownerOwnership changed
event_object_attackedUnder attackFires from aiscript, not MD-side
event_god_created_factoryEngine-side new station spawnisgamestartgodentry=true/false distinguishes initial seed from runtime

For galaxy-wide combat notifications, see Behavior → Order — aiscripts emit 'station_under_attack' signal to player.galaxy.

  • <find_station> (without _by_true_owner) excludes player stations. Use find_station_by_true_owner or merge results from both.
  • ⚠ Module recipes accessible via $Mod.macro.ware.resourcesnot $Mod.products.list.{1}.resources (returns null silently).
  • ⚠ In X4 9.0, <create_construction_sequence> errors on stations with hasstagedconstruction=true — guard with <do_if value="not $Station.hasstagedconstruction">.
  • bare <set_player_target> for cross-cluster stations errors (not in player cluster). For galaxy-wide tracking use Guidance API.

Example 1: Find the player’s nearest Argon trade station

Section titled “Example 1: Find the player’s nearest Argon trade station”
<run_actions ref="md.LIB_Generic.FindNearestStationForFaction"
result="$nearest">
<param name="Faction" value="faction.argon"/>
<param name="Position" value="player.ship.position"/>
<param name="Sector" value="player.ship.sector"/>
</run_actions>
<do_if value="@$nearest">
<set_value name="$is_trade" exact="$nearest.istradestation"/>
</do_if>

Example 2: Listen for any station destruction in the galaxy

Section titled “Example 2: Listen for any station destruction in the galaxy”
<cue name="WatchStationDestruction" instantiate="true">
<conditions>
<event_object_destroyed/>
<check_value value="event.object.isclass.{class.station}"/>
</conditions>
<actions>
<write_to_logbook
text="'Station destroyed: ' + event.object.knownname"/>
</actions>
</cue>

Example 3: Transfer ownership of a station with cleanup

Section titled “Example 3: Transfer ownership of a station with cleanup”
<run_actions ref="md.LIB_Generic.TransferStationOwnership">
<param name="Station" value="$capturedStation"/>
<param name="NewOwner" value="faction.player"/>
</run_actions>

For deeper understanding of station-related subsystems:

  • How stations come into existence: Architectural overview Galaxy seeding (Tier 1) — covers god.xml, FinaliseStations pipeline, factionlogic_stations runtime spawner.
  • How factions decide when to build new stations: Architectural overview Faction economyEvaluateSectorShortage formula and Request_Factory action.
  • Station construction rendering: Architectural overview Construction sequence<create_construction_sequence> and <apply_construction_sequence>.
  • Module — building block of a station.
  • Shipyard — subtype, builds capital ships.
  • Sector — container.
  • Faction — owner.
  • Ware — what stations trade and produce.