Skip to content

Particle systems

How a particle system's behavior decides which settings take effect, how systems end, and which systems an object can hold at once.

Features & systemsCombat & weaponsWeapons, warheads & projectiles

A particle system creates, ages, moves and removes the particles it holds. Particles take no turn of their own, so nothing happens to a particle except during its system’s turn. The system’s BehavesLike value selects which of those steps run and which settings in the system’s section are read.

Most settings apply to only some behaviors. A setting the behavior does not read is loaded and then ignored, so a section with fifteen assignments can produce an effect controlled by four of them. The two tables below list every setting each behavior reads.

Particle system types and particles in brief

Section titled “Particle system types and particles in brief”

Two kinds of type definition work together. Both have a BehavesLike key, and both accept the same seven names, so they are easy to confuse.

A ParticleSystemType describes an emitter: how often it creates particles, how many, in which direction, and when it stops. A ParticleType describes one puff, spark, flame or cloud: how it looks, how long it lives, how it moves, and what it does to objects it touches. The system’s HoldsWhat names the one particle type it creates. Rules registration lists covers how the [ParticleSystems] and [Particles] lists are read and what an unknown name does.

rules.ini
[ParticleSystems]
0=MYSMOKESYS
[Particles]
0=MYSMOKEPUFF
[MYSMOKESYS] ; the emitter
BehavesLike=Smoke
HoldsWhat=MYSMOKEPUFF
SpawnFrames=10
Slowdown=.0025
SpawnCutoff=15.0
[MYSMOKEPUFF] ; the thing emitted
Image=SGRYSMK1
BehavesLike=Smoke
MaxEC=80
Velocity=6
Deacc=.02
EndStateAI=20

The two BehavesLike values are independent. The system’s value decides how particles are emitted and aimed. The particle’s value decides what each particle does once it exists. They do not have to match. A smoke system can hold spark particles: the system decides when particles appear and whether they get successors, and each spark particle still ages and moves as a spark.

Each row lists the settings that a running system with that BehavesLike value reads on its turn. The system ignores every other setting in its section.

Four settings apply to every system, including those in the last two rows. Lifetime counts down for every system. OneFrameLight, LightSize and ParticleCap control the glow that a system of any behavior can cast. The table names these four only where a behavior also uses them in another way.

BehavesLikeUsed keys
SmokeHoldsWhat, SpawnFrames, Slowdown, SpawnCutoff, SpawnTranslucencyCutoff, SpawnRadius
FireHoldsWhat, SpawnFrames
SparkHoldsWhat, SparkSpawnFrames, SpawnSparkPercentage, SpawnDirection, plus ParticleCap for the size of each burst and LightSize for a flash on the first frame, which appears only when OneFrameLight is off
RailgunHoldsWhat, ParticlesPerCoord, SpiralRadius, SpiralDeltaPerCoord, PositionPerturbationCoefficient, MovementPerturbationCoefficient, VelocityPerturbationCoefficient, Laser, LaserColor
Gas, WeakGas, Webnothing, HoldsWhat included
A name outside the seven, or no name at allnothing, HoldsWhat included

No behavior reads Spawns.

Some places that build a system ask it for one particle at once, whatever its behavior. That particle comes from HoldsWhat. A warhead’s Particle, an exploding barrel’s BarrelParticle and each cell of a web blast work this way. For a gas, weak gas or web system, this first particle is the only one HoldsWhat ever supplies; every later particle is a successor. The Particle anim at… action asks for no particle, so a gas, weak gas or web system it places stays empty.

The system decides whether an expiring particle gets a successor, but the settings involved sit on the particle type:

  • A gas, weak gas or web system replaces each expiring particle with one NextParticle successor, displaced by NextParticleOffset.
  • A smoke system replaces it with two successors, thrown to either side by the expiring particle’s Radius. It ignores NextParticleOffset.
  • Fire, spark and railgun systems create no successors, so all three settings have no effect on the types they hold.

Only smoke and fire systems move:

  • A smoke system follows the object it is attached to, unless that object is a structure. It creates no particles while that object is traveling through a map tunnel.
  • A fire system moves to the muzzle of its firer’s first weapon slot and re-aims along the firer’s body facing. It does so only on frames when the firer has a target and is still turning.

Spark, railgun, gas, weak gas and web systems stay where they were created, however far the object they belong to travels.

Particle systems take their turns in each logic frame after animations, building lights, bullets, structures, aircraft, infantry and vehicles, and before terrain objects, voxel animations and waves.

On its turn, a system with one of the seven behaviors ages every particle it holds, then removes the particles that have finished. Smoke, fire, spark and railgun systems also create particles. Spark and railgun systems create them before aging; smoke and fire systems create them after.

A system with no recognized behavior does nothing on its turn. A particle put into it never ages, moves or expires, and the system stays on the map for as long as it holds that particle.

A particle moves only when its system runs the movement step for it:

  • A fire system moves every particle it holds, including those expiring that frame.
  • Gas, weak gas, smoke and web systems move every particle except those expiring that frame.
  • Spark and railgun systems never run the movement step. In those systems, only Spark and Railgun particles move, because they move themselves as they age. Particles of other behaviors stay where they were created.

Asking a system to end only marks it. A marked smoke, fire or railgun system stops creating particles. A marked spark system keeps throwing bursts until its SparkSpawnFrames run out, unless all its particles expire between two bursts first. Either way, the system stays on the map until its last particle has expired, and only then is it removed.

This delay has visible effects. A repaired vehicle can keep smoking for a while, because its damage smoke stops producing puffs but the existing puffs and their successors live out their time. A system also keeps its object’s hold filled until it is removed.

A system is marked when any of these happens:

  • Its behavior’s end condition is met. A smoke system ends when its spawn interval passes SpawnCutoff. A spark system with a positive SparkSpawnFrames ends when that count runs out. A railgun system ends after it lays its trace, which it does in a single turn. A fire system ends when it has no live firer to follow.
  • A positive Lifetime counts down to zero.
  • The object the system is attached to is taken off the map, changes owner, or starts to cloak.
  • Damage smoke ends when its object is repaired above yellow health or goes underground.
  • A fire stream ends when its firer is given a destination (a move order, or its own approach to a target) or a new target out of range.
  • The Remove particle anim at… action ends every system standing in the waypoint’s cell at that moment.

Gas, WeakGas and Web have no end condition of their own, and neither does a spark system whose SparkSpawnFrames is 0. A system of that kind, or with no behavior, ends only through one of the other routes above.

Each vehicle, aircraft, infantry and structure has five holds, and each hold keeps one running system. While a hold is filled, no second system of that kind starts for the object.

HoldWhat claims it
Firethe stream a UseFireParticles=yes weapon throws
Sparkthe spray a UseSparkParticles=yes weapon throws, and the sparks a damaged object gives off (infantry only with Cyborg=yes)
Naturala structure’s NaturalParticleSystem
Damagethe smoke a damaged object gives off
Railgunthe trace an IsRailgun=yes weapon lays

A hold stays filled until its system is removed. An object therefore cannot fire a spark, fire or railgun weapon again until the previous effect has burned out. Firing geometry covers how a filled hold blocks each weapon slot.

The fire hold is the exception. A new destination (a move order, or the object’s own approach to a target) or a new target out of range frees it at once. The old stream burns out on its own, and the object can start a new stream before it has finished.

The types come from other settings. A weapon names its system with AttachedParticleSystem. A damaged object picks from its DamageParticleSystems list: entries with the Spark behavior fill the spark hold, and entries with the Smoke behavior fill the damage hold.

A particle’s BehavesLike likewise decides which settings in its section are read. MaxEC applies to every behavior and is left out of the table. Some particle settings are read by the holding system instead, so they depend on the system’s behavior, not the particle’s:

BehavesLikeUsed keys
GasMaxDC, Damage, Warhead, WindEffect, Translucency, StartStateAI, EndStateAI, StateAIAdvance, DeleteOnStateLimit
WeakGaseverything Gas reads except MaxDC, Damage and Warhead
SmokeVelocity, Deacc, WindEffect, Translucency, StartStateAI, EndStateAI, StateAIAdvance, DeleteOnStateLimit
FireVelocity, Deacc, MaxDC, Damage, Warhead, FinalDamageState, Normalized, Translucency, Translucent25State, Translucent50State, StartStateAI, EndStateAI, StateAIAdvance, DeleteOnStateLimit
SparkColorList, ColorSpeed, StartColor1, StartColor2
RailgunVelocity, ColorList, ColorSpeed, StartColor1, StartColor2
WebWarhead, Translucency, StartStateAI, EndStateAI, StateAIAdvance, DeleteOnStateLimit
A name outside the seven, or no name at allTranslucency

No behavior reads StartFrame or NumLoopFrames.

Normalized recalculates the interval between animation states when a particle is created, but only Fire particles use the recalculated interval. Particles of every other behavior use StateAIAdvance as written.

A Web particle applies its warhead at zero damage, so its Damage has no effect.

Two global settings reach only some behaviors. WindDirection sets one wind direction for the whole map. Only Gas, WeakGas and Smoke particles drift with it. For Gas and WeakGas particles, WindEffect sets how often they take a wind step. For Smoke particles, it sets how far they move each frame. Gravity affects only Gas, WeakGas and Spark particles.

These systems belong to no object:

  • a warhead’s Particle, built at each impact, except that a Gas system joins the shared gas cloud described below;
  • a Webby=yes warhead’s Particle, built in every cell the web covers;
  • an exploding barrel’s BarrelParticle, built on one blast in four;
  • the system the Particle anim at… action places on the ground at a waypoint.

None of these has a source object, so no object’s destruction ends them, and none moves after it is placed, whatever its behavior.

Two more are tied to an object but fill no hold. A piece of debris builds its AttachedSystem. An aircraft, or a vehicle without DeathFrames, killed by the firestorm warhead throws seven to nine copies of DefaultFirestormExplosionSystem; each of these picks a random direction for every burst and ignores SpawnDirection. Both kinds are marked when the object that made them is removed.

Two systems are named by the engine, not by any key. A mod configures them only through sections with these exact names:

  • GasCloudSys is the scenario’s shared gas cloud. The game builds it once as the scenario starts, at cell 10,10, and it never moves. Every warhead whose Particle system has BehavesLike=Gas releases its particle into this cloud instead of building a system of its own. That particle comes from the cloud’s HoldsWhat, not from the system the warhead names, and the cloud’s turn ages and moves every such particle in the match. Veinhole monsters release their gas into it as well.
  • GasPuffSys is the puff a levitating vehicle leaves behind as it accelerates. Each puff builds a new system.

Of the ten Default…System settings, only DefaultFirestormExplosionSystem names a system the game ever builds. The DefaultSparkSystem page covers the other nine.

HalfDamageSmokeLocation1, HalfDamageSmokeLocation2 and a vehicle’s HalfDamageSmokeLocation are loaded but never used. Damage smoke and sparks start at DamageSmokeOffset.

69 of 69

KeyDescriptionValueWhen omitted
AttachedParticleSystemWeaponTypeThe particle system a flame, spark or railgun weapon spawns as it fires.stringnone
AttachedSystemVoxelAnimTypeThe particle system created with a voxel animation and destroyed with it.classnone
BarrelParticleglobal rulesThe particle system released by an exploding overlay, on one blast in four.classnone
BehavesLikeParticleType, ParticleSystemTypeThe behavior a particle or a particle system follows, such as smoke, gas or sparks.stringnone
ColorListParticleTypeThe colors a spark or railgun particle blends through as it ages.rgbclass list(empty)
ColorSpeedParticleTypeHow fast a spark or railgun particle slides from one of its colors to the next.floating point0
DamageAnimType, ParticleType, VoxelAnimType, WeaponTypeA weapon's damage per shot, or the damage an animation, particle or voxel animation deals.floating pointVaries by type
DamageParticleSystemsAircraftType, BuildingType, InfantryType, UnitTypeThe particle systems a damaged object gives off, sorted into sparks and smoke by their own behavior.list of ParticleSystemTypes(empty)
DamageSmokeOffsetAircraftType, BuildingType, InfantryType, UnitTypeWhere a damaged object's spark and smoke systems are anchored, relative to the object.offset (x,y,z)0,0,0
DeaccParticleTypeThe speed a particle loses each frame.floating point0
DefaultFirestormExplosionSystemglobal rulesThe ParticleSystemType spawned in place of the usual explosion when the firestorm warhead destroys a vehicle or aircraft.classnone
DefaultSparkSystemNo effectglobal rulesParsed particle system name that the engine never uses.classnone
DeleteOnStateLimitParticleTypeKills a particle the moment its animation reaches the last state.booleanno
EndStateAIParticleTypeThe animation state that ends a particle's sequence.integer0
FinalDamageStateParticleTypeThe last animation state at which a flame particle still burns what it drifts over.integerInherited
Gravityglobal rulesThe downward pull applied each frame to ballistic shots, hovering and levitating objects, and some particles.integer3
HalfDamageSmokeLocation1No effectBuildingTypeParsed offset that nothing in the engine reads.point (x,y,z)0,0,0
HoldsWhatParticleSystemTypeThe ParticleType every particle a system creates is made from.string(empty)
IsRailgunWeaponTypeFires a beam that damages objects along the line from the muzzle to the target as the weapon fires.booleanno
LaserParticleSystemTypeWhether a railgun system draws a beam alongside its spiral of particles.booleanno
LaserColorParticleSystemTypeThe color of the beam a railgun system draws.color (R,G,B)0,0,0
LifetimeParticleSystemTypeHow many frames a particle system runs before it winds down.integer-1
LightSizeParticleSystemTypeHow strong a light a particle system casts.integer0
MaxDCParticleTypeThe frames between one particle's damage applications.integer0
MaxECParticleTypeThe base lifetime of a particle, in frames.integer1
MinZVelocityParticleTypeThe smallest upward part of the speed picked for each spark.integer0
MovementPerturbationCoefficientParticleSystemTypeHow far each railgun particle's course is deflected from the spiral it was laid on.floating point0.0
NaturalParticleLocationAircraftType, BuildingType, InfantryType, UnitTypeWhere a structure's continuous particle plume sits, relative to the structure.offset (x,y,z)0,0,0
NaturalParticleSystemAircraftType, BuildingType, InfantryType, UnitTypeA particle system a structure runs continuously from the moment it appears.classnone
NextParticleParticleTypeThe particle type created in place of this one when it expires.stringnone
NextParticleOffsetParticleTypeHow far a successor particle is placed from the one it replaces.offset (x,y,z)0,0,0
NormalizedNo effect in some scopes7 applicable typesRescales an animation's frame delay against the game speed setting, or paces a particle's damage states over its flight.booleanno
NumLoopFramesNo effectParticleTypeParsed frame count that the engine never uses.integer1
OneFrameLightParticleSystemTypeWhether a system's light is redrawn every frame at a brightness that follows how full of particles it is.booleanno
ParticleWarheadTypeThe particle system released where the warhead detonates.classnone
ParticleCapParticleSystemTypeThe size of a spark system's burst, and the fullness a one-frame light's brightness is measured against.integer50
ParticlesPerCoordParticleSystemTypeHow many particles a railgun trace lays per lepton of beam length.floating point.1
PositionPerturbationCoefficientParticleSystemTypeHow far each railgun particle is displaced from its place on the spiral, in leptons.floating point0.0
RadiusParticleTypeHow far a smoke system throws the two successors of an expiring particle.integer0
SlowdownParticleSystemTypeHow much a smoke system's spawn interval lengthens every frame.floating point0.0
SparkSpawnFramesParticleSystemTypeHow many frames a spark system goes on throwing bursts for.integer0
SpawnCutoffParticleSystemTypeThe spawn interval a smoke system stops emitting at.floating point0.0
SpawnDirectionParticleSystemTypeThe direction a spark burst is thrown in.vector0,0,0
SpawnFramesParticleSystemTypeThe starting interval, in game frames, between a smoke or fire system's particle spawns.integer1
SpawnRadiusParticleSystemTypeHow far a smoke system scatters its new particles from its own position, in leptons.integer0
SpawnSparkPercentageParticleSystemTypeThe chance that a spark system throws a burst on any one frame.floating point0.0
SpawnTranslucencyCutoffParticleSystemTypeThe spawn interval past which a smoke system raises its new particles' fade level by one step.floating point0.0
SpawnsNo effect in some scopesAnimType, ParticleSystemType, VoxelAnimTypeThe type spawned where thrown debris lands, and on a particle system a flag with no effect.classVaries by type
SpiralDeltaPerCoordParticleSystemTypeHow far a railgun trace's corkscrew turns per lepton of beam length, in radians.floating point.025
SpiralRadiusParticleSystemTypeThe radius of the corkscrew a railgun trace winds around its beam, in leptons.floating point25.0
StartColor1ParticleTypeOne end of the color range a spark or railgun particle is created at.color (R,G,B)0,0,0
StartColor2ParticleTypeThe other end of the color range a spark or railgun particle is created at.color (R,G,B)0,0,0
StartFrameNo effectParticleTypeParsed frame index that the engine never uses.integer0
StartStateAIParticleTypeThe animation state a particle is created at.integer0
StateAIAdvanceParticleTypeThe frames a particle spends in each animation state.integer4
TranslucencyAnimType, ParticleTypeHow faded an animation or a particle is drawn, as a percentage, at the detail settings that honor it.integer0
Translucent25StateParticleTypeThe animation state at which a flame particle thins to a quarter faded.integer-1
Translucent50StateParticleTypeThe animation state at which a flame particle thins to half faded.integer-1
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
VelocityParticleTypeThe speed a particle is created with, in leptons per frame.floating point0
VelocityPerturbationCoefficientParticleSystemTypeHow much a railgun trace randomly varies its particles' speed.floating point0.0
WarheadAnimType, ParticleType, VoxelAnimType, WeaponTypeThe WarheadType a weapon's shot uses, or the one an animation, particle or voxel animation delivers its own damage through.classnone
WebbyWarheadTypeThe warhead entangles the infantry it catches instead of damaging them.booleanno
WindDirectionglobal rulesThe facing that smoke and gas particles drift toward.integer-1
WindEffectParticleTypeHow strongly the prevailing wind carries a particle sideways.integer0
XVelocityParticleTypeOne horizontal axis of the spread of speeds a spark is thrown at.integer1
YVelocityParticleTypeThe other horizontal axis of the spread of speeds a spark is thrown at.integer1
ZVelocityRangeParticleTypeThe spread of upward speeds a spark is thrown at.integer1