Skip to content

Boarding operation

A Boarding operation is the lifecycle of a boarding attempt: one boardee (the target ship/station), one or more attackers (ships contributing marines), and a state machine over four phases. Vanilla source: md/boarding.xml.

Inheritance: operation β†’ boardingoperation. The base operation type adds starttime, duration, owner.

Why this matters for modders: boarding is one of the few engine-driven long-running operations with its own datatype, properties, and event family. Touching it well β€” adding modded boarding actions, custom marine selection, alternate phase triggers β€” requires understanding the phase machine.

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
created β”‚ pre marines being β”‚
↓ β”‚ selected, β”‚
started β”‚ approach not yet β”‚
↓ β”‚ started β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ approach pods en route to β”‚
β”‚ boardee β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ infiltration marines insertingβ”‚
β”‚ through hull β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ internalfight marines fightingβ”‚
β”‚ inside boardee β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
removed β”‚ (complete / cancelled β€” β”‚
β”‚ removed from engine) β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Vanilla phases (boardingphase.X enum):

PhaseEngine behaviourVanilla driver
prePlayer / faction is composing the operation. Marines being selected. No pods launched yetboarding.xml:103, 338, 571
approachPods launched and en route to boardee. Aiscripts on each pod handle approach + defence-evasionboarding.xml:386
infiltrationMarines inserting through hull. Marine skill + boardingresistance shape successboarding.xml:568, 852
internalfightMarines fighting interior crew. Marine combinedskill vs .boardingresistance of boardeeboarding.xml:893, 1095
(removed)Operation concluded β€” fires event_boarding_operation_removedboarding.xml:1548

Thresholds (.boardingapproachthreshold, .boardinginsertionthreshold) decide when one phase triggers the next.

From the boardingoperation datatype (scriptproperties.xml:1597) + inherited from operation.

PropertyTypeDescription
.existsboolOperation exists in engine
.starttimetimeWhen started (inherited)
.durationtimeExpected duration; -1s if unspecified (inherited)
.ownerfactionThe boarding faction (inherited)
.boardingphaseboardingphaseCurrent phase enum
PropertyTypeDescription
.boardeedefensibleThe target (ship or station)
.attackerslistAll ships contributing marines
.approachingpodslistPods currently en route
.allmarinesdispatchedboolAll assigned marines have launched (true if none were assigned)
PropertyTypeDescription
.marines.infiltrating.listlistMarines currently inserting (NPC templates)
.marines.infiltrating.countintCount
.marines.infiltrating.combinedskillint 0..100Avg skill
.marines.infiltrating.randomnpctemplateentryRandom member
.marines.fighting.list / .count / .combinedskill / .randomvariousSame fields, currently in internal fight
.marines.killed.list / .count / .combinedskill / .randomvariousMarines killed in this operation
PropertyTypeDescription
.boardingapproachthresholdintThreshold to transition pre β†’ approach
.boardinginsertionthresholdintThreshold to transition approach β†’ infiltration

Target-side accessors (on the boardee, not the operation)

Section titled β€œTarget-side accessors (on the boardee, not the operation)”

On the boardee (defensible datatype):

PropertyNotes
.boardingoperationThe currently-attacking op, or null
.boardingoperationsList of all inbound ops (rare; one is usual)
.boardingresistanceHostile NPCs’ aggregate strength
.baseboardingresistanceFloor (defined per macro)
.boardingstrengthAttacker marines’ aggregate score

Boarding operations are typically created through the player-side context menu, but scripts can start them directly:

<start_boarding_operation operation="$operation"/>

Vanilla showcases.xml:350 uses this for the tutorial. Most mod use cases let vanilla boarding.xml create the op, then react via events.

<set_boarding_phase
operation="$Operation"
phase="event.param"/>

The vanilla phase machine uses event_boarding_phase_changed + set_boarding_phase to advance phases on threshold hits. See boarding.xml:103.

<set_value name="$avgSkill"
exact="$op.marines.fighting.combinedskill"/>
<set_value name="$totalKilled"
exact="$op.marines.killed.count"/>
<do_if value="@$Ship.boardingoperation">
<set_value name="$op" exact="$Ship.boardingoperation"/>
<write_to_logbook
text="$Ship.knownname + ' under boarding, phase: '
+ $op.boardingphase"/>
</do_if>

Boarding has a dedicated MD framework rather than LIB_Generic helpers:

LibraryFilePurpose
md.Boarding.X cuesmd/boarding.xmlThe full ~3000-line state machine driving the four phases
md.LIB_Generic.TransferShipOwnershipmd/lib_generic.xml:1551Called at conclusion to transfer the captured boardee to the new owner

For ad-hoc work the md.Boarding cues are the source of truth β€” read them rather than re-implementing.

EventWhenNotes
event_boarding_operation_createdOperation exists in engine, before player/faction finalisesVanilla boarding.xml:7
event_boarding_operation_startedPlayer/faction committed; marines being preparedboarding.xml:265
event_boarding_phase_changedAny phase transitionevent.object = operation, event.param = new phase
event_boarding_operation_removedOperation concluded (capture / cancel / loss)Fired in boarding.xml:1548

There is no event_boarding_operation_succeeded / event_boarding_operation_failed. The outcome is observed by:

  • Watching event_object_changed_owner on the boardee (success = ownership swap to attackers’ faction)
  • Watching event_object_destroyed on the boardee (failure mode = boardee destroyed)
  • On event_boarding_operation_removed, comparing boardee’s .trueowner to the operation’s .owner
  • ⚠ event_boarding_operation_removed fires for both success AND failure. It’s the engine’s β€œthis op is done” signal. To distinguish, check event.object.boardee.trueowner == event.object.owner (success) or event.object.boardee.exists == false (boardee destroyed).
  • ⚠ .boardingphase is an enum, NOT a string. Use boardingphase.pre / .approach / .infiltration / .internalfight, not "pre" etc.
  • ⚠ Pre-phase operations can be cancelled cheaply. Once boardingphase.approach is reached pods are in flight and cancellation leaves them adrift β€” make sure your mod accepts cleanup.
  • ⚠ Marines killed in earlier phases don’t return to the attacking ship. The .marines.killed list grows monotonically; check it before assuming β€œno marines available”.
  • ⚠ Special ships reject boarding. Khaak Queen’s Guard, Hive Guard, certain story ships β€” they have .iscapturable=false and engine refuses the op. Filter via $ship.iscapturable before offering boarding.
  • ⚠ Boardingresistance includes pilot/crew skill, not just marines. A boardee with low marine count but a high-skill pilot still resists. Read .boardingresistance to estimate, not .people.marine.count.
  • ⚠ set_boarding_phase skips phase logic. Forcing infiltration directly bypasses approach thresholds β€” pods still need to physically arrive. Use sparingly.
  • ⚠ approachingpods is a list of ships, not pod-specific instances. Each pod is a class.ship_xs controllable. Cancel via standard ship destruction / commandeer if needed.

Example 1: Notify when a player boarding op enters infiltration

Section titled β€œExample 1: Notify when a player boarding op enters infiltration”
<cue name="WatchPlayerBoarding" instantiate="true">
<conditions>
<event_boarding_phase_changed/>
<check_value value="event.object.owner == faction.player
and event.param == boardingphase.infiltration"/>
</conditions>
<actions>
<write_to_logbook
text="event.object.boardee.knownname
+ ': marines inserting'"/>
</actions>
</cue>
<cue name="OnBoardingDone" instantiate="true">
<conditions>
<event_boarding_operation_removed/>
</conditions>
<actions>
<set_value name="$op" exact="event.object"/>
<do_if value="$op.boardee.exists
and $op.boardee.trueowner == $op.owner">
<write_to_logbook
text="'Boarding succeeded: '
+ $op.boardee.knownname"/>
</do_if>
<do_else>
<write_to_logbook
text="'Boarding failed: '
+ ($op.boardee.exists ?
$op.boardee.knownname :
'boardee destroyed')"/>
</do_else>
</actions>
</cue>

Example 3: Find all boarding ops the player is currently running

Section titled β€œExample 3: Find all boarding ops the player is currently running”
<find_ship_by_true_owner name="$PlayerShips"
space="player.galaxy"
faction="faction.player"
multiple="true"/>
<create_list name="$ActiveOps"/>
<do_for_each name="$ship" in="$PlayerShips">
<do_if value="@$ship.boardingoperation
and $ActiveOps.indexof.{$ship.boardingoperation} == 0">
<append_to_list name="$ActiveOps"
exact="$ship.boardingoperation"/>
</do_if>
</do_for_each>
<write_to_logbook
text="'Player has ' + $ActiveOps.count
+ ' boarding ops in progress'"/>

Note: a single boarding op can have multiple attackers, so dedup by op ref.

  • End-to-end boarding pipeline: Architectural overview Boarding β€” md/boarding.xml ~3000 lines, four-phase machine, pod lifecycle, marine skill ↔ resistance arithmetic, ownership swap on success.
  • How marines are recruited and tracked: Architectural overview Marine recruitment β€” entityrole.marine, ship .people.marine.count, training at equipment docks.
  • Combat side of boarding: Architectural overview Defence response to boarding β€” engine fires event_object_attacked on the boardee as a side effect; defending faction’s static-defence cues respond.
  • Ship β€” both the attackers and (often) the boardee.
  • Station β€” boardee subset (L/XL boardable).
  • NPC β€” marines, pilots; skill drives outcome.
  • Faction β€” .owner of operation, .trueowner of boardee.
  • Order β€” attacking ships execute 'AssistBoarding'-style orders during the operation.