Skip to content

Weapon

A Weapon is a destructible component installed on a Ship or Station that fires projectiles. Lasers (primary weapons), turrets (auto-targeting defensive guns), and missile launchers (secondary weapons / heavy ordnance) all share the weapon datatype.

Inheritance: component → destructible → weapon. Note: weapon extends destructible directly, not object. Weapons are components of larger objects — they don’t have their own .sector (read .parent.sector).

Subtypes:

SubtypeDatatypeNotes
class.weaponweaponGeneric — covers primary laser-type weapons
class.turretturret (extends weapon, no extra props)Auto-targeting defensive gun
class.missileturretmissileturret (extends turret)Missile-firing turret
class.missilelauncher(class only, no datatype)Primary missile launcher (secondary weapon slot)

The four classes form a hierarchy where missileturret IS-A turret IS-A weapon — isclass.weapon is true for all of them. isclass.missilelauncher is checked separately (vanilla scenario_combat.xml:1211 uses not .isclass.missilelauncher to distinguish primary lasers from primary missiles).

The weapon datatype is rich — these are common modder use cases.

PropertyTypeDescription
.modeweaponmodeCurrent operating mode (see weaponmode enum below)
.isreadytofireboolWeapon active and (if a turret) deployed
.isinactiveweapongroupboolInstalled on a defensible AND in an active weapon group
.iscombatboolNOT for repairing or mining
.isminingboolMining weapon (drills / extractors)
.isrepairingboolRepair weapon (welders)
.isbeamboolFires a continuous beam (not discrete bullets)
.isguidedboolFires guided missiles
.istorpedoboolFires torpedoes
PropertyTypeDescription
.maxfirerangelengthMaximum effective range
.reloadratefloatShots per second
.reloadtimetimeTime between shots
.barrelpositionpositionBarrel position (may be 0,0,0 for collision-free weapons)
PropertyTypeDescription
.ammo.macromacroAmmo macro (the missile/torpedo)
.ammo.warewareWare that provides the ammo
.ammo.capacityintAmmo storage capacity this weapon adds
.ammo.iscompatible.{macro}boolCan this weapon fire that missile macro

Modes verified from vanilla MD usage:

ModeBehaviour
weaponmode.holdfireDisabled — never fires
weaponmode.defendFires only when ship is attacked
weaponmode.attackenemiesFires at any hostile in range
weaponmode.missiledefenceFires only at incoming missiles
weaponmode.prefercapitalTargets capitals first
weaponmode.miningMining drills active

Set via <set_weapon_mode>:

<set_weapon_mode
weapon="$turret"
weaponmode="weaponmode.attackenemies"/>

Vanilla: lib_generic.xml:2034, 2049 (HoldFire / Defend), setup_gamestarts.xml:1595 (AttackEnemies), tutorial_mining.xml:584 (mining), scenario_tutorials.xml:6384, 6402 (prefercapital / missiledefence).

<set_weapon_mode
weapon="$turret"
weaponmode="weaponmode.attackenemies"/>

Use the vanilla library:

<run_actions
ref="md.LIB_Generic.Setup_Ship_Turrets_Defend">
<param name="Ship" value="$ship"/>
</run_actions>

For hold-fire:

<run_actions
ref="md.LIB_Generic.Setup_Ship_Turrets_HoldFire">
<param name="Ship" value="$ship"/>
</run_actions>

Pattern from lib_generic.xml:2026-2055.

<set_turrets_armed object="$Ship" armed="true"/>
<set_turrets_armed object="$Ship" armed="false"/>

Pattern from scenario_tutorials.xml:5699.

There is no direct .weapons list. Iterate via .weapongroups or compatible patterns:

<do_for_each name="$weapon" in="$Ship.weapons">
<do_if value="$weapon.iscombat">
<write_to_logbook
text="$weapon.knownname + ' range: '
+ $weapon.maxfirerange"/>
</do_if>
</do_for_each>

Filter primary lasers vs missile launchers

Section titled “Filter primary lasers vs missile launchers”
<set_value name="$isprimary"
exact="not $weapon.isclass.missilelauncher"/>

Pattern from scenario_combat.xml:1211. Used to bias damage calcs differently for laser vs missile primaries.

For “how much DPS does this ship have”, use the Defensible properties on the ship rather than iterating weapons:

Ship propertyDescription
.dps.allCombined DPS
.dps.primary / .dps.secondaryPer-slot type
.dps.turrets.allJust turrets
.dps.missiles.allJust missile weapons
.maxcombatrange.allFurthest effective range across all weapons
.shortestmaxcombatrange.allShortest among all weapons (kiting decisions)

These aggregates are much cheaper than iterating weapons and are vanilla’s preferred path.

There is no event_weapon_X family. Weapon-related observations go through:

EventWhenNotes
event_object_destroyedWeapon destroyedFilter event.object.isclass.{class.weapon}
event_object_attackedShip attacked — event.param2 is often the weaponevent.param3.{2} is the weapon in some events (see notifications.xml:1515)

For “weapon fired” / “weapon hit”, vanilla observes at the Bullet or Missile level, not the weapon.

  • weapon extends destructible, NOT object. No .sector, .zone, .position directly — use .parent.sector or .macro.barrelposition for the local offset.
  • .barrelposition may be [0,0,0] for collision-free weapons. Don’t treat it as a guaranteed muzzle location.
  • .isclass.weapon is TRUE for turret, missileturret, missilelauncher too (inheritance). To target only “basic weapons”, check not .isclass.turret and not .isclass.missilelauncher.
  • .isclass.missilelauncher is a CLASS check with no dedicated datatype. Same pattern as Bomb / Countermeasure — class exists but no missilelauncher datatype in scriptproperties.
  • set_weapon_mode is per-weapon. For “all turrets on this ship”, use the Setup_Ship_Turrets_* libraries or iterate weapons.
  • .ammo.macro is null for non-ammo weapons. A laser has no ammo macro. Don’t dereference without @$weapon.ammo.macro check.
  • .isreadytofire requires BOTH active state AND deployed turret. A turret-stowed weapon shows ready=false even if armed. To distinguish “off” from “stowed”, check parent ship’s alertlevel.
  • Player ammo for missiles is add_ammo, not add_inventory. Same as all ammostorage-based content. The weapon’s .ammo.ware tells you what ware to add.

Example 1: All player ship turrets to defend mode

Section titled “Example 1: All player ship turrets to defend mode”
<run_actions
ref="md.LIB_Generic.Setup_Ship_Turrets_Defend">
<param name="Ship" value="player.ship"/>
</run_actions>
<write_to_logbook
text="'Turrets set to defend on '
+ player.ship.knownname"/>

Example 2: Compute weapon-value sum for a ship

Section titled “Example 2: Compute weapon-value sum for a ship”
<set_value name="$Total" exact="0"/>
<do_for_each name="$weapon" in="$Ship.weapons">
<do_if value="@$weapon.macro.ware">
<set_value name="$Total"
operation="add"
exact="$weapon.macro.ware.averageprice"/>
</do_if>
</do_for_each>
<write_to_logbook
text="'Weapon value: ' + $Total + 'Cr'"/>

Example 3: Find ships with mining drills equipped

Section titled “Example 3: Find ships with mining drills equipped”
<find_ship_by_true_owner name="$Ships"
space="player.galaxy"
faction="faction.player"
multiple="true"/>
<create_list name="$Miners"/>
<do_for_each name="$ship" in="$Ships">
<do_for_each name="$weapon" in="$ship.weapons">
<do_if value="$weapon.ismining">
<append_to_list name="$Miners" exact="$ship"/>
<break/>
</do_if>
</do_for_each>
</do_for_each>
<write_to_logbook
text="$Miners.count + ' player miners armed'"/>
  • Weapon-mode dispatching: Architectural overview Turret AI — how weaponmode.X drives per-turret target selection.
  • DPS aggregation: Architectural overview Defensible damage model — how Ship.dps.X is computed from individual weapons.
  • Ammo vs no-ammo weapons: Architectural overview Weapon ammo system — when .ammo.macro is null vs populated.
  • Ship — what weapons are installed on; aggregate DPS lives on the ship.
  • Station — also hosts weapons (turrets on defence stations).
  • Defensible — the type that aggregates .dps.X.
  • Missile — what missile launchers fire.
  • Bullet — what laser weapons fire (component-level, brief lifecycle).
  • Ware.macro.ware is the inventory item.