ModEnc is currently in Maintenance Mode: Changes could occur at any given moment, without advance warning.

Particles and ParticleSystems

From ModEnc
Revision as of 14:46, 15 February 2009 by DCoder (talk | contribs) (Continuing, wheeee)
Jump to navigation Jump to search
Work in Progress
This page is the result of a currently running discussion. The information on it is subject to change. If you wish to follow the discussion or want to know more about the history of this page, please follow this chat link.

"Particles" are ingame objects designed to represent things like smoke, gas, sparks, fire and Railgun effects. They're usually contained within a "ParticleSystem" that's attached to a weapon or an object, such as the IFV Repair spark or Ghost Stalker's Railgun. Like a lot of other Westwood concepts, they sound nice in theory but end up limited in practice.

ParticleSystems

ParticleSystems are basically commanders of single Particles - they spawn their own Particles when needed, tell them where to go, how to act and when to die. There are no unmanaged Particles in the game, even the seemingly independent Poison Gas Particles spawned by the Virus are in fact controlled by the global particle system the game creates especially for "uncontrolled" particles.

ParticleSystem Behaviours

ParticleSystems have five preprogrammed behaviours corresponding to the five use cases that were needed in Tiberian Sun where they first appeared. These behaviours are assigned to a Particle System by setting its Template:TTL flag.

Note that Template:TTL is a flag applicable to both ParticleSystems and Particles. It means two different things in those two contexts.


Template:TTL

This behaviour is normally used to depict smoke caused by damage the object has sustained, or smoke produced by normal functionality of the object (Slave Miner's smoke stacks). The system follows its owner object around.

Template:TTL

This behaviour is naturally used to depict gases floating around, such as Tiberium Gas emitted by the Veinhole Monster in Tiberian Sun or Poison Gas created by the Virus-induced deaths in Yuri's Revenge. The system usually has no owner object and floats around in accordance to the wind.

Template:TTL

This behaviour is used by flamethrower-type weapons like the Devil's Tongue subterranean flame tank in Tiberian Sun. The system obeys the source object's turret facing and will not fire until the turret is correctly facing the target. This behaviour generates lots of particles in a sine wave formation.

Template:TTL

This behaviour is used (predictably) to depict sparks caused by damaged electrical systems or welding sparks (IFV Repair weapon). In addition to spawning particles, this behaviour also creates flashes of light programmatically, although other behaviours can also create these flashes in a different way.

Template:TTL

This behaviour is used for the Railgun particles. It is the most complex one, calculating the particles' trajectories along the path as a spiral. There are multiple INI controls to adjust this spiral's behaviour. It also can draw a narrow laser beam along the center of the spiral, this laser is visually quite different from ordinary ones generated by laser-type weapons.

Creating Particle Systems

Particle Systems are spawned by the game under the following circumstances:

  • A VoxelAnim has been created - the Particle System specified in Template:TTL (if any) will be created.
  • A VehicleType is inactive (like an offline Robot Tank) - the [CombatDamage]DefaultSparkSystem= will be created every once in a while.
  • A TechnoType with Template:TTL is damaged into yellow health - a random System from those listed in Template:TTL (only systems with Template:TTL are eligible) will be created. As long as this spawned system exists, repeating these conditions will not create more systems. This system will be terminated automatically if the object heals back into green health.
  • An InfantryType with Template:TTL and Template:TTL has less than [AudioVisual]ConditionYellow= health - a random System from those listed in Template:TTL (only systems with Template:TTL are eligible) will be created. As long as this spawned system exists, repeating these conditions will not create more systems. The odds of this system being created (assuming the previous condition allows it) are [General]ConditionRedSparkingProbability= or [General]ConditionYellowSparkingProbability=, depending on whether the cyborg's health is below [AudioVisual]ConditionRed= or not.
  • A TechnoType is firing a weapon that has Template:TTL set. Once this TechnoType fires this weapon, it will not be able to fire any more Template:TTL weapons until that particle system expires.
  • A TechnoType is firing a weapon with either Template:TTL or Template:TTL set. Once it fires, it will not be able to fire any more weapons with any one of those two flags until that particle system expires.
  • A Map Action calls for a creation of a Particle System.
  • A Scenario starts - a global system named GasCloudSys is created to control the "unmanaged" particles mentioned above.
  • A Parasite is "firing its weapon" inside its host - the [CombatDamage]DefaultSparkSystem= will be created. This system is ownerless, will be recreated with each "shot" and will expire on its own.
  • A weapon with Template:TTL is fired - the [CombatDamage]DefaultSparkSystem= will be created. Like the parasite one, this system is ownerless.
  • A warhead with Template:TTL set is detonated - an ownerless system declared in this flag will be created. Note that despite the flag being named Particle, you're supposed to specify a ParticleSystem as its value.
  • A warhead is detonated in a cell that contains an OverlayType with Template:TTL set - the [CombatDamage]BarrelParticle= system will be created. Note the Particle/ParticleSystem naming again.
  • A Mind Controlling object that's subject to MasterMindOverload logic is overloaded - 5 instances of the [CombatDamage]DefaultSparkSystem= will be created.
  • A BuildingType is placed - the System specified as Template:TTL , if any, is created. This system is recreated whenever the building decloaks, however, this part is done if the BuildingType has the Template:TTL set to non-zero coordinates, without checking that it actually has a NaturalParticleSystem set.
  • A BuildingType is destroyed - a random System from those listed in Template:TTL (only systems with Template:TTL are eligible) will be created.
  • A Harvester or a Slave unloads ore at a Refinery - up to four instances of the System specified as Template:TTL will be created, depending on how many of Template:TTL, Template:TTL, Template:TTL, Template:TTL are set to non-zero. These systems will auto expire after Template:TTL frames.

Particles

Like ParticleSystems, Particles themselves have certain predefined behaviours controlled by Template:TTL.

Note that Template:TTL is a flag applicable to both ParticleSystems and Particles. It means two different things in those two contexts.


Behaviour controls

The particles' behaviour over their lifetime is influenced by both contexts of BehavesLike.

ParticleSystemTemplate:TTL

Template:TTL
These particles, like Gas, float around, but they are also influenced by [AudioVisual]Gravity= to an extent. In addition to that, they emit Damage, however that Damage doesn't follow the natural damage delivery system and instead just is applied to each object standing in the same cell as the particle itself (except the particle's owner object), ignoring the assigned Warhead's CellSpread entirely. When a particle in this system expires, if it has Template:TTL set, this particle will be spawned, and it has a 5/6 chance of being more translucent than its predecessor, which means you should not chain up more than five particles this way. Each successor is spawned twice , so five particles pointing to the same NextParticle will spawn ten particles when they expire.
Template:TTL
Doesn't do much except make the particles move around somewhat randomly.
Template:TTL
Makes the particle more translucent as it "matures", and, much like Smoke, can damage each object in the same cell except its owner object.
Template:TTL
Makes the particles affected by [AudioVisual]Gravity= as they move.
Template:TTL
Doesn't do much except move the particles in a predefined direction.

ParticleTemplate:TTL

Template:TTL
This particle can only be rendered as a SHP image. Initial Velocity might get a minor random boost. See the section on DC/EC for details on animating the image. Applies WindEffect to the particles as follows:
Every frame, the coordinates of the particle are modified by a constant amount depending on [General]WindDirection=: counting from straight up (North) clockwise, the constant offsets are: {0,-2}, {2,-2}, {2, 0}, {2, 2}, {0, 2}, {-2,2}, {-2,0}, {-2,-2} , and these are multiplied by Template:TTL before being added to the coordinates. This is applied independently from any movement the particle system is performing.
Template:TTL
Makes the particles hover at least 5 leptons above ground. This particle can only be rendered as a SHP image. See the section on DC/EC for details on animating the image. Applies WindEffect to the particles as follows:
Every (10 / Template:TTL) frames, the coordinates of the particle are modified by a constant amount depending on [General]WindDirection=: counting from straight up (North) clockwise, the offsets are: {0,-2}, {2,-2}, {2, 0}, {1, 2}, {0, 2}, {-2,2}, {-2,0}, {-2,-2}. Note that only the fourth offset differs from the offsets used for Gas particles.
Template:TTL
Kills the particle as it lands to the ground. This particle can only be rendered as a SHP image, with 4 directional variations. the section on DC/EC for more details.
Template:TTL
This particle cannot have any Image set and is always drawn as a single pixel. It is not drawn if the player has selected low Detail Level in Game Options.
Template:TTL
This particle cannot have any Image set and is always drawn as a single pixel. Gets a smaller ExistenceCounter bonus than other types.

Particle Drawing

To reduce lag, particles that do not have a non-zero Template:TTL set are not drawn if the frame rate drops below a certain threshold. This is independent from whether or not the particle actually deals damage (only Particles belonging to ParticleSystems with Template:TTL do).

Most of the following text has been mentioned above, and is just repeated here for completeness
Particles with ParticleTemplate:TTL set to Spark or Gas are not drawn at low Visual Detail Level.
Particles with ParticleTemplate:TTL set to Spark or Railgun cannot have a SHP Image and are always drawn as a single pixel.
Particles with ParticleTemplate:TTL set to Smoke, Gas or Fire need to have a SHP Image (not a voxel!). If Visual Detail Level is set to high, they can be translucent: Setting [Particle]Translucency= to 25, 50, or any number larger than 74 will respectively make this particle 25%, 50% or 75% translucent. Fire particles become more translucent as they "mature", according to the Template:TTL and Template:TTL controls (see the section on DC/EC for more details). Chained particles in a system that has Template:TTL can become more translucent than their predecessors with random luck.

"SHP Railgun hack"

A hack to make railguns lag less and use SHP images was discovered and published back in 2004 by gamemate. For a long time it was blindly copy-pasted as the ultimate solution to railgun lag, but recent analysis has proven it to not be entirely correct. The documentation on this page should be sufficient to get SHP images working on Railguns.

= ExistenceCounter, DamageCounter and other advanced controls

The rules(md).ini precedes the [Particles] section with these comments:

; MaxDC = How many frames go by before this particle damages the things near it? (def = 0)
; MaxEC = How many frames does this object last (def = 0)
; Damage = How much damage does it do (def = 0)
; Warhead = What warhead to use for damage purposes (def = WARHEAD_NONE)
; StartFrame = what frame of image to start on? (def = 0)
; NumLoopFrames = how many frames form a single loop? (def = 1)
; WindEffect = to what degree does the wind affect his particle, 0 = not at all, 5 = a lot (def = 0)
; Velocity = speed at which particle travels (def = 0.0)
; Radius = how big is this particle? (used for attract/repel)
;
; BehavesLike, DeleteOnStateLimit, EndStateAI, StateAIAdvance are things that
; shouldn't be messed with

For once, it's not completely offtopic - those things shouldn't be messed with unless you do know what you're doing.

Most of these flags only apply to particles in ParticleSystems with certain behaviours. Namely, "AIState" advances are only done for ParticleSystems with Template:TTL. Other behaviours only increment the ExpirationCounter and expire particles if it reaches the limit.

MaxDC (most likely Damage Counter)
This flag controls the delay, in frames, before this particle will be able to inflict damage, limited to 65535 frames (wraparound, not saturation).
MaxEC (most likely Existence Counter)
This flag controls the delay, in frames, before this particle will expire. In reality, particles get a random lifetime bonus when they're created - particles with Template:TTL get a random bonus of [1..10] frames, other particles get a random bonus of [1..MaxEC] frames. Total lifetime is limited to 65535 frames (wraparound, not saturation).
StateAIAdvance
Each time this many frames pass in this particle's lifetime, its internal "AIState" is incremented.
Translucent25State
Translucent50State
If a particle's internal "AIState" is equal to these values, the particle becomes 25% or 50% translucent, respectively.
EndStateAI
This is the maximum "AIState" for this particle.
DeleteOnStateLimit
If set, this particle will be forcibly removed from the game once its AIState matches EndStateAI.
FinalDamageStage
The particle will stop emitting damage after this many frames have elapsed since MaxDC expired and it started dealing damage.
StartFrame
NumLoopFrames
Have no effect in Yuri's Revenge. The animation sequences are hardcoded:
Particles with Template:TTL use the "AIState" as the frame index.
Particles with Template:TTL use the "AIState" + ((direction of the trajectory % 4) * Template:TTL) as the frame index. Basically, the frames [0..EndStateAI - 1] are used for directions 0 and 5 (straight north/south), frames [EndStateAI..2 * EndStateAI - 1] are used for directions 1 and 6 (NE/SW), and so on. Check the TS flameall.shp for details.

Particle creation

Aside from particles created when their controlling Particle System behaviour decides to do so, there are some special case particles spawned as part of the global Particle System:

  • An Animation expired - the Particle specified as Template:TTL is spawned Template:TTL times.
  • A Veinhole Monster's gas emission is triggered - the Particle named GasCloudM1 is spawned once.
  • An InfantryType is killed by a warhead with Template:TTL (Virus death) - the animation specified as [CombatDamage]InfantryVirus= is triggered, and the particle specified as that animation's Template:TTL is created once ( this happens without checking if SpawnsParticle is actually set to a valid particle).
To be continued...