Skip to content

Faction

A Faction is an entity that owns objects in the universe, has bilateral relations with every other faction, accumulates money, and decides strategic actions. Every persistent thing in the universe (Station, Ship, Module, NPC) is owned by some faction.

Subtypes (by behavior): Player (faction.player) and NPC factions share the same datatype but differ in how engine-side AI drives them — NPC factions run factionlogic.xml heartbeat, the player does not. Some properties (willclaimspace, isaggressive, iseconomic) are tag-driven; see libraries/factions.xml for the definitive list.

Primary races: Argon, Paranid, Teladi, Split, Terran, Boron, Xenon, Khaak — see .primaryrace accessor. Note that “Riptide” is a scavenger sub-faction with primaryrace=argon, not Fallen Families — easy mistake.

The most-used accessors for modders. The full list (~60 properties) is in vanilla libraries/scriptproperties.xml:1820.

PropertyTypeDescription
.idstringInternal id (e.g. argon, khaak)
.namestringDisplay name (respects unknown-status — may show ”???”)
.knownnamestringDisplay name, ignoring unknown-status
.shortname / .prefixnamestringShort / prefix forms
.primaryraceraceThe race this faction is associated with
.isactiveboolCurrently active (some factions deactivate mid-game)
.knowntoplayerboolPlayer has met them
PropertyTypeDescription
.relationto.{faction}floatRelation to another faction. Raw float -1.0 .. +1.0
.relationto.{object}floatRelation to owner of an object
.defaultrelationto.{faction}floatWhat relation would be without runtime changes
.relation.{rangename}.min / .mid / .maxfloatEdges of a named relation range
.relation.{numeric}.uivalueintUI form (-30 .. +30) of a float relation value
.hasrelation.{rangename}.{X}boolIs relation to X in the given range
.mayattack.{component or faction}boolWill this faction shoot at X
.ishostileto.{component or faction}boolEither side may shoot
.isrelationlockedboolRelation cannot be changed

Relation ranges (named ranges in libraries/factions.xml):

RangeFloatUIMeaning
nemesis−30 only−30Maximally hostile, flavour
kill−25 .. −30−25 .. −30All assets attacked on sight
killmilitary−20 .. −30−20 .. −30Military assets attacked
enemy−10 .. −30−10 .. −30No docking; stations don’t report player attacks
neutral0 (excl.)0Tolerated
friend / ally / dockvarious positive10..30Docking and trading allowed
PropertyTypeDescription
.moneymoney (Cr × 100 internally)Current faction account balance
.hasownaccountboolIf false, uses dummy random-sum account
PropertyTypeDescription
.tagslistAll faction tags (tag.claimspace, tag.economic, tag.aggressive, …)
.hastag.{tag}boolHas tag
.isaggressive / .iseconomic / .ispolice / .isprotectiveboolBehavioural tags
.willclaimspaceboolWill claim sectors if it has a claim-granting station
.policefactionfactionWhich faction is its police force
PropertyTypeDescription
.headquartersstationThis faction’s HQ station
.representativeentityEmbassy representative NPC
.diplomatentityDiplomat NPC
.licenceslistAll licences this faction grants
.heldlicenceslistAll licences this faction holds (from other factions)
.haslicence.{type}.{faction}boolHas licence of <type> from {faction}
.doesresupplyboolWill resupply ships at owned docks

Change a faction’s relation to another faction (permanent)

Section titled “Change a faction’s relation to another faction (permanent)”
<set_faction_relation
faction="$Faction"
otherfaction="faction.player"
value="$Faction.relation.dock.min + 0.001"
reason="relationchangereason.missioncompleted"/>

reason= is the engine’s audit trail — pick a relationchangereason.X enum value. The comment in vanilla:

+ 0.001 to move into the ‘docking’ UI value range — range edges are exclusive on one side.

Change a single object’s relation (temporary, with decay)

Section titled “Change a single object’s relation (temporary, with decay)”
<set_relation_boost
object="$AttackedShip"
otherobject="$Attacker"
value="$AttackedShip.owner.relation.kill.min"
delay="10min"
decay="1"
reason="relationchangereason.attackedobject"
silent="true"/>

This affects only the object, decays over time. silent="true" suppresses the on-screen notification. Use this for “make this NPC hate the player for 10 min” rather than permanent shifts.

For attacks, kills, and boarding the engine has dedicated actions that read damage / weapon / context and apply the right curve:

<change_relation_on_attack
attacker="player.controlled"
attacked="event.param"
method="event.param2"
weapon="event.param3.{2}"
result="$relchange"/>
<change_relation_on_kill
killer="player.controlled"
killed="event.param"
method="event.param2"
result="$relchange"/>
<change_relation_on_boarding
boarder="player.controlled"
boarded="$object"
attempt="true"
result="$relchange"/>

See vanilla notifications.xml:1515, 1737, 1796 for the canonical wiring.

<get_factions_by_relation
result="$EnemyFactions"
faction="$Faction"
relation="enemy"
activeonly="true"/>

relation= takes a named range; activeonly=true skips inactive factions.

<transfer_money
from="$Faction"
to="faction.player"
amount="($Reward)Cr"/>

amount= must be a money type — wrap dynamic numbers as ($N)Cr, not bare integers.

<set_owner object="$Station" faction="$NewOwner"/>

For ships, prefer md.LIB_Generic.TransferShipOwnership — it severs the old commander’s fleet link, which bare set_owner does not. See Station → Actions.

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

LibraryPurposeSource line
md.LIB_Generic.DetermineEnemyFactionFind a random enemy of $Faction (or return all)1482
md.LIB_Generic.CalculateReputationCompute reputation gain from a contribution376
md.LIB_Generic.CalculateReputationDropCompute reputation drop from a hostile act411
md.LIB_Generic.FixFactionRepresentativeRestore missing representative NPC after save load1651
md.LIB_Generic.WaitForFactionsToHaveStationsWait until ALL given factions have at least one station4254
md.LIB_Generic.FindNearestStationForFactionClosest station of given faction to position1240
md.LIB_Generic.FindStationsForFactionByDistanceAll stations sorted by distance1270
md.LIB_Generic.FindNearestEnemySectorForFactionNearest sector controlled by an enemy of $Faction1326
md.LIB_Generic.GetSectorSafetyFriend/enemy station ratio in a sector, evaluated for a faction4703
EventWhenNotes
event_faction_relation_changedBilateral relation between two factions changedevent.param = [fA, fB]. Use faction= and optionally otherfaction= attributes to filter
event_faction_activatedFaction transitioned to activeVanilla uses for diplomacy intros
event_faction_deactivatedFaction transitioned to inactiveTriggers cleanup of pending operations
event_faction_police_changedpolicefaction changedUsed by faction_relations.xml
event_object_changed_ownerAn object changed faction (boarding, transfer, capture)Object-side; not faction-side
  • .relationto returns a raw float (-1.0..+1.0), not the UI value. Doing .relationto.{Y}.uivalue silently returns null. To get UI: $F.relation.{$F.relationto.{Y}}.uivalue. For float thresholds (most common), compare floats directly (0.10, 0.20, 0.50).
  • .money is stored as 1/100-credit integer. A reading of 1000000 means 10 000 Cr. The same scale applies to sellprice/buyprice in logs. Divide by 100 only for display.
  • transfer_money amount= needs money type. A dynamic ($val)Cr works; a bare integer logs “not of type money” and silently no-ops. See memory: transfer_money requires money type.
  • set_faction_relation vs set_relation_boost. set_faction_relation is the permanent baseline between two factions. set_relation_boost is time-decaying per-object. For “this NPC ship is mad at the player for 10 min” use boost; for “Argon now likes the player +5 from a mission” use set_faction_relation (or let the engine do it via change_relation_on_*).
  • Relation range edges are exclusive on one side. Vanilla often adds +0.001 to relation.dock.min to actually land inside the docking range. Read the property description: “in ‘neutral’ and ‘dock’ the .min value is NOT included”.
  • faction.X lookups for missing factions return null silently. A DLC-gated faction.terran is null on a Base-only install. Wrap DLC-faction references with <do_if value="@faction.terran">.

Example 1: Find a random enemy faction for AI raiders

Section titled “Example 1: Find a random enemy faction for AI raiders”
<run_actions ref="md.LIB_Generic.DetermineEnemyFaction"
result="$Enemy">
<param name="Faction" value="faction.argon"/>
<param name="ClaimSpaceFactionsOnly" value="true"/>
</run_actions>
<do_if value="@$Enemy">
<write_to_logbook
text="'Picked enemy: ' + $Enemy.knownname"/>
</do_if>

Example 2: Reward the player when a side mission completes

Section titled “Example 2: Reward the player when a side mission completes”
<set_value name="$RewardCr" exact="50000"/>
<transfer_money
from="$QuestGiver"
to="faction.player"
amount="($RewardCr)Cr"/>
<set_faction_relation
faction="$QuestGiver"
otherfaction="faction.player"
value="$QuestGiver.relationto.{faction.player} + 0.05"
reason="relationchangereason.missioncompleted"/>

Example 3: Listen for player relation reaching docking with Argon

Section titled “Example 3: Listen for player relation reaching docking with Argon”
<cue name="WatchArgonRelation" instantiate="true">
<conditions>
<event_faction_relation_changed
faction="faction.player"
otherfaction="faction.argon"/>
<check_value
value="faction.player.hasrelation.dock.{faction.argon}"/>
</conditions>
<actions>
<write_to_logbook
text="'Argon now allows player docking.'"/>
</actions>
</cue>
  • How factions decide what to produce, build, or buy: Architectural overview Faction economy — per-faction Econ_Manager reads shortages, picks one of 7 corrective actions.
  • How factions pick strategic actions (invade, hold, plunder, patrol): Architectural overview Faction goals — Registry + two-tier evaluation (PriorityGoals must-run + EvaluatedGoals competition).
  • How factions evaluate distress calls: Architectural overview Patrol coordination — galaxy combat bus + per-faction priority queue.
  • Faction relations seeding: libraries/factions.xml declares default relations; runtime changes go through set_faction_relation with relationchangereason.X audit.
  • Raceprimaryrace of a faction (argon, paranid, …).
  • NPC — the people that belong to a faction.
  • Station — owned by a faction.
  • Ship — owned by a faction.
  • Ware — produced and traded by a faction’s stations.
  • Licence — diplomatic privileges a faction grants.