Skip to content

Firing geometry and beam weapons

Settles where an object's shots and firing effects appear, in what order one shot produces them, and which of them hold the weapon shut until they burn out.

Features & systemsCombat & weaponsWeapons, warheads & projectiles

One routine turns a decision to shoot into everything a shot consists of: the projectile, the beam or wave that goes with it, the muzzle flash, the report, the recoil, the round spent and the delay before the next one. It runs in a fixed order, and several of the things it produces are anchored at different points on the artwork and read from different weapon slots, which is why a beam and the shell it accompanies can leave from opposite sides of the same gun.

Projectile flight and impact owns what the shot does once it is in the air. This page owns the moment of firing.

An object type carries three weapon slots. Primary= and Secondary= fill the first two; Elite= fills a third that is never fired on its own. Each slot holds more than a weapon: it also holds the firing offset, barrel length and barrel thickness that weapon uses, read from the art entry rather than from the rules.

Two substitutions replace a whole slot, offsets included, and both are settled every time the slot is consulted rather than once.

  • An object that has reached elite rank reads the third slot in place of the first. Because the offsets travel with the slot and the third slot is filled from the first weapon’s PrimaryFireFLH, PBarrelLength and PBarrelThickness, an elite weapon fires from the same point on the artwork as the weapon it replaces.
  • A structure with anything plugged into an upgrade slot takes the requested slot from the first plugged-in type that supplies a weapon there — and takes that type’s firing offsets with it, not its own.

Throughout this page the firing slot means whichever slot the shot was ordered from after those substitutions, and the first slot means slot zero after them, which is the elite weapon on an elite object.

The order matters because a step that fails ends the shot, and everything below it is skipped. The numbered steps below all belong to one call.

  1. The firing slot’s weapon and projectile are fetched. A slot with no weapon does nothing at all.
  2. A warhead whose LimpetFactor is 1 or more diverts here whenever the target is an object rather than a cell: the mark is clamped on and the firer removes itself. A target this house has already marked ends the shot here too, leaving the firer standing. Either way no shot is created.
  3. The shot is refused outright where the effect this weapon would produce is still alive — see below.
  4. The barrel is given its desired elevation.
  5. The damage the shot will carry is worked out: nothing at all for an IsSonic=yes or UseFireParticles=yes weapon, and otherwise the weapon’s Damage scaled by the house’s and the object’s firepower bias and by the veteran firepower ability.
  6. The projectile is created and launched from the mounting. A shot that finds no ballistic solution, or that cannot be placed at the mounting, ends here and nothing below runs — no round is spent and no reload is started.
  7. A turreted object goes into recoil.
  8. A shot from a weapon whose slot has a barrel length above zero is given two flight turns immediately, so that it appears past the muzzle rather than inside it. An IsLaser=yes weapon and an Inviso=yes projectile are both excluded, and those two turns are ordinary ones — a shot that would detonate on them does.
  9. The fire, spark and railgun effects are spawned at the muzzle, each only where its own hold is empty. The railgun’s beam is walked and its damage dealt at this point, before anything below.
  10. The burst counter advances, the reload delay is set from it, and the counter wraps.
  11. The weapon’s Report sound plays from the mounting — or from the firer’s own center when the projectile is Dropping=yes.
  12. The firing animation from the weapon’s Anim list is created at the muzzle, attached to the firer unless the firer is a structure, in which case it is given a depth adjustment instead. A list of exactly eight entries is indexed by the gun heading rounded to one of eight, with the list rotated one place round: the first entry belongs to a gun facing north-west, the second to north, and so on. A list of any other length always uses its first entry.
  13. The sonic wave is created, from the muzzle to the target.
  14. The laser beam is drawn, from the muzzle to the target. On a structure this also stops the turret animation dead and, where the structure is down to its last round, discharges its turret; Charges covers what that costs a charging weapon.
  15. A round of ammunition is spent, and a firer standing hidden in shroud or fog reveals the ground around itself to the target’s owner where that owner is under player control.

Note where the reload delay sits. It is set at step 10, so the effects at step 9 are already alive when it is worked out — which is exactly what lets the effect weapons take a different delay from everything else.

Two distinct points are computed for every shot, and confusing them accounts for most of the surprises on this page.

The mounting is where the projectile is created and where the firing solution is measured from. It is built by taking a frame aligned with the gun heading, then displacing it by the firing slot’s own offset with TurretOffset added to the forward component. The barrel is deliberately not part of it, so the mounting holds still while the gun elevates.

The muzzle is where the fire animation, the laser beam, the sonic wave and the attached particle systems appear. It carries on from the same displacement by adding the slot’s barrel thickness upward, pitching by the barrel’s current elevation, and running out along the pitched barrel by its length.

The gun heading is not the same thing for every kind of object, and neither is the frame the two points are measured in.

FirerGun headingMountingMuzzle
Vehicle with a turretThe turret facingMeasured inside the transform the body is drawn with, so ground slope and body tilt move itMeasured upright, so slope and tilt do not move it
Vehicle without a turretThe body facingAs aboveAs above
AircraftThe turret facing, whether or not it carries a turretAs aboveAs above
InfantryThe body facingThe same point as the muzzle, so barrel length and thickness move the projectile tooMeasured upright
Structure with a turretThe turret facingMeasured uprightMeasured upright
Structure without a turretThe direction from its center to what it is shooting atMeasured uprightMeasured upright

A structure has two further layers on top of that, tested in this order for both points alike:

  1. A PrimaryFirePixelOffset other than 65535,65535 replaces both outright with that screen offset projected back onto the ground, whichever slot is firing. Nothing below is consulted.
  2. A BarrelAnimIsVoxel=yes structure takes both from VoxelBarrelOffsetToBarrelEnd run through the barrel’s own placement, so the two points coincide at the end of the barrel and both rise as it elevates.
  3. Otherwise the ordinary transform applies, with the turret animation’s own screen offset added when the turret is drawn as a voxel.

The barrel elevation itself is decided per firer as well. A structure whose first weapon is IsLaser=yes points its barrel straight at the aim point rather than solving anything; an EM pulse cannon solves a ballistic arc and retries a quarter faster when the first solve fails; every other object solves the arc for its first weapon, which is why Lobber in the second slot does not raise the barrel.

A burst counter runs from zero to one less than the weapon’s Burst and is used by the geometry as well as by the reload: the lateral component of the firing offset is negated whenever the counter is odd, which is what gives a burst weapon a pair of muzzles either side of the centerline. A structure with a voxel barrel does the same thing through its barrel offset instead, centering the third shot and any after it. Those are facts of the two settings; what belongs here is when the counter is read.

Several parts of a shot are read from the first slot rather than from the slot that fired, which matters as soon as a beam or wave weapon is put in the second slot. The table gathers where each part is anchored and which slot supplies its settings.

Part of the shotAnchored atRead from
The projectile, its damage, warhead and projectile rangeThe mountingThe firing slot
The report sound and the firing animationThe mounting and the muzzle respectivelyThe firing slot
The fire and spark particle systemsThe muzzleThe firing slot
The railgun beam, its ambient damage, warhead and particle systemThe muzzleThe firing slot
The sonic wave’s ambient damage and warheadThe muzzle at creation, then re-anchored each frame to the first slot’s muzzleThe first slot
The laser beam’s colors, spread, duration and glow widthThe muzzleThe first slot
The barrel elevation and whether it is lobbedThe first slot
The reload delayThe firing slot

The two re-anchoring rows are worth reading twice. A sonic wave is created from the muzzle that fired it and then follows the first slot’s muzzle for the rest of its life, so a second-slot sonic weapon on an object whose slots have different offsets sees its wave jump on the frame after it is fired. A UseFireParticles=yes stream behaves the same way; particle systems owns the re-anchoring itself.

Four effects lock an object out of firing while they are alive: a fire particle stream, a spark particle spray, a railgun particle trace, and a sonic wave. The first three each occupy one of the object’s particle holds; the wave occupies a single slot of its own, so an object can have only one wave in flight.

The lock is applied at three separate places, and the three do not answer alike.

  • Before the shot is considered at all, the slot that is not firing is examined: a live effect belonging to that slot’s weapon reports the object as unable to fire at this target at all.
  • The firing slot’s own weapon is examined next, and a live effect there reports the object as still rearming.
  • The firing routine tests the same four conditions again and returns without creating anything.

The tests ask whether the hold is occupied, not whether this weapon’s own effect is the thing occupying it. That matters for one hold only: sparks from a damaged object and a spark weapon’s spray share theirs, and particle systems records what that costs.

A vehicle carries one further gate that is not about effects at all: FiringSyncFrame1 ties the first round of a burst to the firing animation and FiringSyncFrame2 the second, holding the weapon as rearming until the animation reaches the named frame and then releasing the round without the reload timer being consulted. Only the first slot is tied this way; a shot from the second slot is never held.

The delay before the next shot is chosen by the first of these that applies, so a row further down is reached only when every row above it has been passed over.

The firer and its weaponFrames until the next shot
A structure with more than one round left1
The firing slot holds no weapon1
The weapon is IsSonic=yes — whether or not a wave is actually alive — or is a fire, spark or railgun weapon whose matching particle hold is occupiedExactly ROF
The burst is not finishedThe matching BurstDelay0 to BurstDelay3, or a random 3 to 5 where that entry is -1 or the shot is past the fourth
Anything elseROF scaled by the house’s rate-of-fire bias, plus a random 0 to 2, and shortened by the veteran rate-of-fire ability

The third row is the whole reason an effect weapon fires at the pace it does. It skips the bias, the burst gaps and the random padding alike, so the firing rate is decided by ROF and the effect’s own lifetime and by nothing else — and on a structure with a stock of rounds even ROF drops out, because the first row has already answered with a single frame and only the effect’s lifetime is left to pace it.

38 of 38

KeyDescriptionValueWhen omitted
AmbientDamageWeaponTypeThe damage a sonic wave or a railgun beam deals to everything along its path, as opposed to the damage the shot delivers at the target.integer0
AnimWeaponTypeThe animations played at the firing coordinate when the weapon goes off, either one fixed entry or one per facing.list of AnimTypes(empty)
AttachedParticleSystemWeaponTypeThe particle system a flame, spark or railgun weapon spawns as it fires.stringnone
BarrelAnimIsVoxelBuildingTypeDraws a building's gun barrel from a voxel model over its turret animation.booleanno
BurstWeaponTypeHow many shots the weapon fires in quick succession before it waits out its full reload.integer1
BurstDelay0WeaponTypeThe gap in frames between the first and second shot of a burst.integer-1
BurstDelay1WeaponTypeThe gap in frames between the second and third shot of a burst.integer-1
BurstDelay2WeaponTypeThe gap in frames between the third and fourth shot of a burst.integer-1
BurstDelay3WeaponTypeThe gap in frames between the fourth and fifth shot of a burst.integer-1
ChargesWeaponTypeMakes a structure wind its turret animation up to full charge before the weapon will fire.booleanno
EliteAircraftType, BuildingType, InfantryType, UnitTypeThe WeaponType an elite object fires in place of its primary.classnone
FiringSyncFrame1UnitTypeThe countdown value at which the first round of a burst leaves a shape-drawn vehicle.integer-1
IsBigLaserWeaponTypeWidens the screen glow drawn along a laser beam.booleanno
IsLaserWeaponTypeDraws a beam from the muzzle to the target as the weapon fires.booleanno
IsRailgunWeaponTypePunches a damaging line through the world from the muzzle to the target as the weapon fires.booleanno
IsSonicWeaponTypeSends a visible wave rolling from the muzzle to the target, damaging everything it crosses on the way.booleanno
LaserDurationWeaponTypeHow many frames a laser beam stays drawn for.integer10
LaserInnerColorWeaponTypeThe color of the thin core line of a laser beam.colour (R,G,B)0,0,0
LaserOuterColorWeaponTypeThe color of the pair of glow lines drawn alongside a laser beam's core.colour (R,G,B)0,0,0
LaserOuterSpreadWeaponTypeHow far each channel of a laser beam's glow may wander from its color, redrawn every frame.colour (R,G,B)0,0,0
LobberWeaponTypeMakes the weapon always throw its shot on the high arc rather than the flat one.booleanno
PBarrelLengthAircraftType, BuildingType, InfantryType, UnitTypeHow far out along the first weapon's barrel its muzzle sits.integer0
PBarrelThicknessAircraftType, BuildingType, InfantryType, UnitTypeRaises the point the first weapon's barrel pivots about.integer0
PrimaryAircraftType, BuildingType, InfantryType, UnitTypeThe WeaponType in the object type's first weapon slot.classnone
PrimaryFireFLHAircraftType, BuildingType, InfantryType, UnitTypeThe offset from an object's center that its first weapon fires from.point (x,y,z)0,0,0
PrimaryFirePixelOffsetBuildingTypeThe screen offset a building's shots leave from, in place of its firing offsets.point (x,y)65535,65535
RailgunDamageRadiusglobal rulesHow far an object's center may stand from a railgun beam and still be caught by it.integer128
ReportAnimType, WeaponTypeThe sound effect played when the weapon fires, or when the animation starts.soundVaries by type
ROFHouseType, WeaponType, difficulty settingsA weapon's frames between shots, or the multiplier a country or a difficulty setting applies to that delay.floating pointVaries by type
SBarrelLengthAircraftType, BuildingType, InfantryType, UnitTypeHow far out along the second weapon's barrel its muzzle sits.integer0
SBarrelThicknessAircraftType, BuildingType, InfantryType, UnitTypeRaises the point the second weapon's barrel pivots about.integer0
SecondaryAircraftType, BuildingType, InfantryType, UnitTypeThe WeaponType in the object type's second weapon slot.classnone
SecondaryFireFLHAircraftType, BuildingType, InfantryType, UnitTypeThe offset from an object's center that its second weapon fires from.point (x,y,z)0,0,0
SecondaryFirePixelOffsetNo effectBuildingTypeParsed screen offset that the engine never uses.point (x,y)65535,65535
TurretOffsetAircraftType, BuildingType, InfantryType, UnitTypeMoves an object's turret forward from its center along the centerline.integer0
UseFireParticlesWeaponTypeAttacks with a stream of fire particles instead of the projectile's damage.booleanno
UseSparkParticlesWeaponTypeSprays a particle system at the target alongside the shot.booleanno
VoxelBarrelOffsetToBarrelEndBuildingTypeWhere a building with a voxel barrel creates its shots.point (x,y,z)Context-dependent