Skip to content

Faction goals

Above Faction economy (which manages day-to-day stations and freighters) sits a higher layer: faction goals. This is where vanilla decides β€œshould Argon invade Boron space?” or β€œshould Teladi run plunder operations?” β€” strategic, multi-stage actions that take time to play out.

Vanilla implements goals across 4 factiongoal_*.xml files (Hold / Invade / Plunder / Patrol) plus 4 factionsubgoal_*.xml files (BuildStation / DefendArea / PrepareStagingArea / Recon). The whole system is tied together by a two-tier evaluation pattern.

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Per-faction tick β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Tier 1: PriorityGoals β”‚
β”‚ - Must-run goals β”‚
β”‚ - Examples: Hold_Space β”‚
β”‚ - Run regardless of competing options β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Tier 2: EvaluatedGoals β”‚
β”‚ - Compete for execution β”‚
β”‚ - Examples: Invade / Plunder / Patrol β”‚
β”‚ - Faction picks best based on weight β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Selected goal runs β”‚
β”‚ - Drives subgoals (Recon, BuildStation, β”‚
β”‚ DefendArea, PrepareStagingArea) β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

The distinction:

  • PriorityGoals ALWAYS execute their evaluation/action loop if their conditions are met. They don’t compete.
  • EvaluatedGoals evaluate their weight per tick; the faction picks the highest-weight option to actually run.

This lets vanilla express both β€œArgon must defend its space at all times” (Hold = PriorityGoal) and β€œArgon picks ONE strategic operation per tick” (Invade vs Plunder vs Patrol = EvaluatedGoals).

Every goal β€” priority or evaluated β€” exposes the same contract:

Cue / phasePurpose
StartInitial setup when goal first becomes active
InitPer-cycle initialization
EvaluateReturns a EvaluationResult indicating fitness
CleanupCleanup when goal ends
Update_Sub_GoalPropagate state to active subgoals

EvaluationResult enum values (used by Evaluate):

  • success β€” goal achieved
  • failure β€” goal can no longer proceed
  • cancel β€” caller-initiated stop
  • inprogress β€” still working
  • partial β€” partial success, continue
  • priority β€” promote to high-priority status

Each goal’s Evaluate returns one of these, and the parent (PriorityGoals or EvaluatedGoals dispatcher) decides next action based on the result.

factiongoal_hold_space.xml β€” defends faction territory. Runs always for any active faction. Triggers subgoals (DefendArea, PrepareStagingArea) to respond to threats.

factiongoal_invade_space.xml β€” picks an enemy sector to invade, sets up staging, executes the invasion. Highly involved: 4-phase state machine (prepare β†’ beachhead β†’ retreat β†’ handoff), uses Recon subgoal to scout.

factiongoal_plunder.xml β€” sends raiders to disrupt enemy trade. Has its own broker pattern: NPC factions outsource plunder targets to specific ship missions. 375 lines.

factiongoal_patrolcoordinationservice.xml β€” galaxy-wide combat coordination. Maintains a master list of distress calls, evaluates response weights, dispatches patrol ships.

Subgoals are reusable building blocks that any goal can invoke:

SubgoalPurpose
BuildStation (factionsubgoal_buildstation.xml)Build a station as part of a larger plan
Recon (factionsubgoal_recon.xml)Scout a sector for intel
DefendArea (factionsubgoal_defendarea.xml)Defend a specific area
PrepareStagingArea (factionsubgoal_preparestagingarea.xml)Pre-position assets for upcoming operations

Subgoals follow the same contract as goals (Start / Init / Evaluate / Cleanup / Update_Sub_Goal). The composability is the point β€” Invade_Space uses Recon + PrepareStagingArea; Hold_Space uses DefendArea. Same subgoal, different parents.

Each faction has a FactionGoals registry containing all active goals + subgoals:

FactionGoals (per-faction global table)
β”œβ”€β”€ [active goal] Hold_Space (PriorityGoal)
β”‚ └── DefendArea subgoal for Argon Prime
β”œβ”€β”€ [active goal] Invade_Space (EvaluatedGoal)
β”‚ β”œβ”€β”€ Recon subgoal scouting Boron territory
β”‚ └── PrepareStagingArea subgoal in adjacent cluster
└── ...

The registry is the source of truth for β€œwhat’s this faction doing right now”. Modders extending faction behaviour add to this registry.

A custom goal (priority OR evaluated) needs:

  1. New factiongoal_X.xml file mirroring vanilla structure
  2. Registration in the FactionGoals registry on faction init
  3. Implementation of the 5-cue contract (Start / Init / Evaluate / Cleanup / Update_Sub_Goal)
  4. Tested EvaluationResult values

The 4 vanilla subgoals are well-tested. A custom goal that needs β€œbuild a station” should call BuildStation rather than inlining the logic. Subgoals were designed for reuse.

x4_md_subgoal_recon_stable β€” Vanilla subgoals are battle-tested. DA mods (and other major mods) deliberately don’t modify subgoals because they’re a β€œstable foundation for custom faction AI”. Build on them, don’t fork them.

Each goal’s Evaluate runs per faction per tick. With ~12 active factions Γ— 4 evaluated goals = 48 evaluations per tick. Heavy evaluation logic (galaxy-wide scans) adds up. Vanilla goals cache aggressively.

Invade_Space and Hold_Space frequently use $LocalClusters + $AdjacentClusters patterns to operate across cluster boundaries. Custom goals targeting cross-cluster strategy should mirror this β€” see factiongoal_hold_space.xml:136-152.

  • Faction economy β€” child system
  • Patrol coordination β€” overlapping with Patrol goal
  • Mission framework β€” goals can spawn missions via the framework