Skip to content

Generic missions

A Generic mission is a TEMPLATE — gm_bringitems knows how to do “deliver wares to a station”, and is instantiated many times with different parameters (which wares, which station, which faction, reward amount). This is the bread-and-butter X4 mission system: the missions players find at BBS terminals, signal leaks, and faction representatives.

Vanilla has:

  • 37 gm_*.xml templates
  • 6 gmc_*.xml catalogues
  • 67 rml_*.xml reusable phase libraries

For the layered architecture overview see Architectural overview: Mission framework. This page focuses on how to use the layers as a modder.

Each gm_* file implements one mission kind. The 37 vanilla templates:

TemplateWhat it does
gm_achievecoverageAchieve satellite coverage in a region
gm_ambushAmbush a passing convoy
gm_assassinateKill a specific NPC
gm_barterwaresTrade wares between two stations
gm_board_shipCapture a ship via boarding
gm_bringitemsDeliver wares (most common BBS)
gm_buildstationBuild a station
gm_claimplotClaim a sector plot
gm_deployinplaceDeploy satellites/probes/mines
gm_destroy_matching_objectsDestroy objects matching criteria
gm_destroy_objectsDestroy specific objects
gm_destroy_rarelyonsightDestroy a rare-spawn
gm_escortEscort an NPC ship
gm_find_objectFind a specific object
gm_find_resourcesLocate an asteroid field
gm_getexactcrewRecruit specific crew
gm_getexactfleetAcquire ships matching criteria
gm_hackpanelHack a station data panel
gm_joinsubscriptionJoin a faction subscription
gm_killmasstrafficDestroy mass-traffic ships
gm_largesupplyLarge-scale supply runs
gm_patrolPatrol a region
gm_prisonbreakRescue a captured NPC
gm_repairobjectRepair a damaged object
gm_repairsignalleaksRepair signal leaks
gm_reputationGain reputation via task
gm_rescue_ship, gm_rescue_ship_2Rescue a stranded ship
gm_retrieveitemRetrieve an item from a crate
gm_sabotageSabotage station defences
gm_scanScan an object / region
gm_supplyfactorySupply wares to a factory
gm_support_invasionSupport military invasion
gm_trackshipTrack a ship’s movement
gm_transport_passengersTransport NPCs to a destination
gm_unlockshadyguyUnlock a black-market contact

Vanilla templates share a structure. gm_bringitems.xml (2056 lines) is canonical:

<library name="LIB_<Mission>_*"/> <!-- helper libraries (LookupGreedyCost, etc.) -->
<cue name="TextOffsets"> <!-- text-table offset constants -->
<cue name="FeedbackValueManager"> <!-- mission-impact tracker for AI factions -->
<cue name="Start" namespace="this">
<cue name="Do_Not_Start_Mission"/> <!-- early-bail conditions -->
<cue name="Do_Start_Mission">
<cue name="With_Offer"> <!-- offer flow (BBS / signal leak / NPC) -->
<cue name="CreateOffer"/> <!-- the actual create_mission call -->
<cue name="Offer_Management" ref="md.GenericMissions.OfferMission"/>
<cue name="Offer_End"/> <!-- offer expiry -->
</cue>
<cue name="Without_Offer"> <!-- auto-spawn variant (e.g. lockbox loot pickup) -->
<cue name="..."/> <!-- timer-based or trigger-based start -->
</cue>
</cue>
</cue>

Two main flavors:

FlavorWhen to use
With_OfferStandard BBS mission — player sees offer, can accept/decline
Without_OfferTriggered by world event (player picks up lockbox → mission auto-starts)

The 6 catalogues PICK which gm_* to instantiate when an offer source becomes available:

CataloguePicks fromOffer source
gmc_assisted_taskVarious gm_*NPC representative
gmc_dynamicVarious gm_*Signal leak (random encounter)
gmc_improve_station_defencesgm_destroy_*, gm_patrolStation faction representative
gmc_madscientistgm_find_, gm_destroy_Mad scientist NPC (story content)
gmc_retrieve_dead_dropgm_retrieveitemBlack market contact
gmc_supervised_mininggm_find_resourcesMining guild rep

A catalogue’s job: select a template, compute parameters (which faction, what wares, which sector), pass to the template’s offer cue.

The 67 rml_* libraries provide sub-objectives. A mission gm_X references rml_X (and others) via library calls:

<run_actions ref="md.RML_Deliver_Wares.Setup">
<param name="Mission" value="$MissionCue"/>
<param name="Wares" value="$RequestedWares"/>
<param name="Destination" value="$Station"/>
</run_actions>
Common rml_*Used by
rml_find_objectgm_assassinate, gm_board_ship, gm_destroy_objects, gm_find_object, gm_retrieveitem
rml_buildstationgm_buildstation, gm_supplyfactory
rml_collect_cratesgm_retrieveitem, gm_rescueship_2
rml_deploy_in_sectorsgm_deployinplace, gm_achievecoverage
rml_destroy_componentsgm_destroy_*, gm_sabotage
rml_escortgm_escort, gm_largesupply
rml_trade_waresgm_barterwares, gm_largesupply

For your custom mission template: identify which rml_* covers each sub-objective and reference it via <run_actions ref=>. Don’t reimplement.

md/genericmissions.xml (1930 lines, 81 cues) is the dispatch hub. Key public cues:

CuePurpose
md.GenericMissions.OfferMissionReference cue used by all gm_* for offer management
md.GenericMissions.SetupMissionAfterAcceptStandard post-accept setup
md.GenericMissions.CleanupMissionStandard cleanup (markers, anchored objects)
md.GenericMissions.AbortMissionPlayer-initiated abort path

Custom missions should reference these for vanilla-style lifecycle integration.

Offer sources are objects that have .offerlocations:

Source typeUsed by
BBS terminal (control panel)NPC representative offer
Signal leakDynamic encounters (gmc_dynamic)
NPC actorAssisted task (gmc_assisted_task)
Station (direct)Faction-direct offers

Each catalogue picks an offer-source pattern matching its theme.

All generic missions route rewards through:

<run_actions ref="md.LIB_Reward_Balancing.GetReward">
<param name="Mission" value="$MissionCue"/>
<param name="ResultStorage" value="$RewardSnapshot"/>
</run_actions>

See Architectural overview: Reward calculation for the full reward math.

  • Without_Offer missions auto-spawn but still need cleanup<event_mission_aborted> cleanup is mandatory
  • rml_* libraries write into the mission cue’s $X namespace — clashes with your local variables if both pick the same name
  • gmc_* catalogues choose templates probabilistically — your custom mission won’t appear unless added to a catalogue or offered directly
  • Adding a new mission group requires missiongroups.xml diff — without it, mission group filter on HUD won’t show your mission
  • Multi-language text — text constants in t/0001-L044.xml (English); missing translations show readtext{page,id} literals
  • DLC-only templatesgm_joinsubscription is Pirate DLC; guards needed (see DLC handling)
  1. Pick template-or-catalogue:
    • Want a new mission KIND? → Write gm_my_mission.xml (model on closest vanilla)
    • Want existing kind in new context? → Diff a gmc_* catalogue
  2. Reuse rml_* for sub-objectives
  3. Reference md.GenericMissions.OfferMission for offer lifecycle
  4. Reference md.LIB_Reward_Balancing.GetReward for reward
  5. Register a mission group (or reuse existing)
  6. Add text constants to your mod’s t/<lang>.xml
ConcernFile
Canonical With_Offer/Without_Offer splitgm_bringitems.xml
Catalogue picker logicgmc_dynamic.xml (random) / gmc_assisted_task.xml (themed)
Reusable phaserml_find_object.xml, rml_collect_crates.xml
Orchestrator hubgenericmissions.xml:1-200 (setup) + OfferMission cue
Reward mathlib_reward_balancing.xml

The three-tier layering pays off when you write a custom mission: an hour of reading vanilla rml_* saves a week of reimplementing find-object / collect-crates / deliver-wares logic.