Skip to content

Mission framework

Every β€œFind this object” / β€œDeliver these wares” / β€œDefend this station” mission the player encounters in X4 is generated by a layered mission framework. The framework separates mission TEMPLATES (what to do) from mission COMPOSITION (which template to pick) from BEHAVIOR REUSE (shared phases). This overview maps the layers.

Vanilla scope:

  • 37 gm_*.xml files β€” base mission templates
  • 6 gmc_*.xml files β€” mission catalogues / compositions
  • 67 rml_*.xml files β€” reusable mission library
  • 7 story_*.xml files β€” narrative content
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Layer 3: Story missions (story_*) β”‚
β”‚ - Hand-authored narrative content β”‚
β”‚ - Tied to specific characters, sectors β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
↓ uses
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Layer 2: Generic Mission Catalogues (gmc_*) β”‚
β”‚ - Compose templates into themed flows β”‚
β”‚ - Examples: assisted_task, dynamic, mad_ β”‚
β”‚ scientist β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
↓ instantiates
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Layer 1: Generic Missions (gm_*) β”‚
β”‚ - Mission TEMPLATES β”‚
β”‚ - Examples: gm_bringitems, gm_board_ship, β”‚
β”‚ gm_buildstation, gm_patrol β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
↓ uses
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Layer 0: Reusable Mission Library (rml_*) β”‚
β”‚ - Shared phases / sub-objectives β”‚
β”‚ - Examples: rml_find_object, rml_buildstationβ”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

The 37 gm_* files are mission templates. Each defines one β€œkind” of mission:

FileMission type
gm_bringitems.xmlDeliver wares to a station
gm_board_ship.xmlCapture a ship via boarding
gm_buildstation.xmlBuild a station
gm_destroy_objects.xmlDestroy components / objects
gm_find_object.xmlFind a specific object
gm_patrol.xmlPatrol a region
gm_assassinate.xmlKill a specific NPC
gm_barterwares.xmlTrade wares between two stations
gm_ambush.xmlAmbush a passing convoy
(and 28 more)Various mission types

Each gm_* script implements the full lifecycle: offer creation β†’ player accept β†’ objective setup β†’ progress tracking β†’ completion / failure β†’ reward distribution.

A typical gm_* script is 1000-3000 lines. Larger ones (gm_buildstation ~5000+) handle complex multi-phase missions.

The 6 gmc_* files are mission composers β€” they pick which gm_* to instantiate based on context.

FileComposition theme
gmc_assisted_task.xmlPlayer-assisted task missions
gmc_dynamic.xmlDynamic encounter missions (deploy in space)
gmc_improve_station_defences.xmlFaction-requested defence upgrades
gmc_madscientist.xmlMad scientist story content (interior dynamic interior)
gmc_retrieve_dead_drop.xmlBlack-market dead drops
gmc_supervised_mining.xmlMining supervision tasks

Catalogues are the β€œWhere do missions come from?” layer. When the player approaches a station, the engine asks a catalogue β€œwhat mission do you have for me right now?”, and the catalogue picks a gm_* template and instantiates it with appropriate parameters.

The 67 rml_* files are shared phases / sub-objectives. Multiple gm_* missions reference the same rml_* for common functionality:

FileReusable functionality
rml_find_object.xmlFind-an-object sub-objective (used by 5+ missions)
rml_buildstation.xmlBuild-a-station sub-objective
rml_collect_crates.xmlCollect floating crates
rml_deploy_in_sectors.xmlDeploy satellites/probes
rml_trade_wares.xmlTrade ware exchanges
rml_destroy_components.xmlDestroy sub-components
rml_largesupply.xmlLarge-scale supply runs
rml_rescue_ship.xmlRescue stranded ships
(and 59 more)…

The naming is parallel: gm_bringitems (top-level mission) uses rml_bringitems (the actual delivery phase). The split lets one mission compose multiple rml_* phases β€” e.g. find-then-deliver-then-defend uses 3 different rml_*.

The 7 story_* files are hand-authored narrative content β€” main plot missions, DLC arcs. They use the same framework primitives but are not templated. Each story script is bespoke.

FileStory arc
story_buccaneers.xmlPirate DLC arc
story_diplomacy_intro.xmlDiplomacy system introduction
story_paranid.xmlParanid story
story_research_welfare_1.xmlResearch welfare story
story_ventures.xmlVentures DLC arc
(and 2 more)DLC-specific

Every gm_* mission follows a similar lifecycle:

Offer creation
- Catalogue picks gm_*, sets parameters
- Creates a mission offer at the offering object
↓
Player accept (event_mission_accepted)
- Mission becomes "active"
- .hasmission = true on the cue
↓
Objective setup
- Spawn target objects / NPCs
- Create map markers / guidance
↓
Progress tracking
- Listen for completion events
- Update objective state
- Voice line / UI feedback
↓
Completion / failure
- Reward distribution (LIB_Reward_Balancing)
- Cleanup spawned content
- Faction relation hit (if applicable)

Each catalogue picks an OFFER LOCATION β€” typically:

  • A specific NPC (faction representative, ship trader)
  • A control panel (signal leak with mission type)
  • A signal leak (random encounter)

The location’s .offerlocations list tracks active offers. See Cue β†’ Properties for .offerlocations accessor.

If your mod needs a new mission KIND not in vanilla:

  1. Write a new gm_X.xml (consider patterns from existing gm_* files)
  2. Reuse rml_* for common sub-objectives
  3. Either: (a) hand-add offers via your own cue, or (b) register with an existing gmc_* catalogue
  4. Implement reward via LIB_Reward_Balancing for vanilla-style economy

Most β€œprimitive” mission objectives (find, deliver, destroy, collect) are already in rml_*. Your custom mission should call into them via <run_actions ref=> rather than reimplementing.

Mission group lets you bucket missions by theme. Custom missions should register a mission group for analytics + UI.

Many vanilla missions (gm_bringitems uses 5+ sites) check whether the offer object is a Signal leak vs a station, and apply different content per case. Custom missions should follow the same pattern.

  • Cue (lang) β€” .hasmission / .missiontype / .objective accessors
  • Mission group β€” categorisation
  • Signal leak β€” common offer source
  • Crate β€” find_crate_slot used in rml_collect_crates
  • Reward calculation β€” LIB_Reward_Balancing math
  • NPC orders β€” missions create orders for cooperating ships
  • Mission framework reward β€” separate concern