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

Particles and ParticleSystems

From ModEnc
Revision as of 09:25, 27 November 2009 by EvilRenegade (talk | contribs) (Replacing Template:TTL with Template:F.)
Jump to: navigation, search
Wip tools.png 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. 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.


BehavesLike

Tiberian Dawn The Covert Operations Red Alert Counterstrike Aftermath Tiberian Sun Firestorm HyperPatch Red Alert 2 Yuri's Revenge Ares Generals Zero Hour Tiberium Wars Kane's Wrath
Flag: BehavesLike
File(s): rules(md).ini
Values: Smoke, Gas, Fire, Spark, Railgun
Applicable to: Particles, ParticleSystems


The pivotal flag for Particles and ParticleSystems is BehavesLike. As the flag name implies, BehavesLike defines how the Particle or ParticleSystem in question behaves like. There are five possible values for this flag, but unfortunately, Westwood decided to use the exact same flag with the exact same values for both Particles as well as ParticleSystems, making their effects on one of them independent from the other one, but having Particle be influenced by what behavior its ParticleSystem is set to.
This means: Whenever you set this flag, look closely on what kind of object you are setting it - Particle or ParticleSystem. It makes a difference.

BehavesLike=Smoke

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.

On Particles

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 / WindEffect) 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.

On ParticleSystems

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 NextParticle 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.
Warning small.png Attention: Each successor is spawned twice, so five particles pointing to the same NextParticle will spawn ten particles when they expire.


BehavesLike=Gas

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.

On Particles

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 WindEffect before being added to the coordinates. This is applied independently from any movement the particle system is performing.

On ParticleSystems

Doesn't do much except make the particles move around somewhat randomly.


BehavesLike=Fire

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.

On Particles

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.

On ParticleSystems

Makes the particle more translucent as it "matures", and, much like Smoke, can damage each object in the same cell except its owner object.


BehavesLike=Spark

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.

On Particles

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.

On ParticleSystems

Makes the particles affected by [AudioVisual]Gravity= as they move.


BehavesLike=Railgun

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.

On Particles

This particle cannot have any Image set and is always drawn as a single pixel. Gets a smaller ExistenceCounter bonus than other types.

On ParticleSystems

Doesn't do much except move the particles in a predefined direction.

Spawning

Particles

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 ParticleSystem:

  • SpawnsParticle Once the animation SpawnsParticle is on expires, the specified particle is spawned NumParticles times.
  • GasCloudM1 In TS, the Veinhole Monster spouted a cloud of poisonous gas every once in a while.
  • InfDeath=8 In YR, when a Virus kills a soldier, the animation set under [CombatDamage]InfantryVirus= is triggered, spawning a particle set through SpawnsParticle once.
Warning small.png Warning: This happens without checking if SpawnsParticle is actually set to a valid particle.

ParticleSystems

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

  • AttachedSystem Voxel animations can have ParticleSystems attached.
  • [CombatDamage]DefaultSparkSystem= In YR, if Robot Tanks go offline, this ParticleSystem will be spawned every once in a while.
  • DamageParticleSystems When a tank, ship or aircraft (or anything else with Organic=no) is damaged into yellow condition, a smoke system (BehavesLike=Smoke) is chosen at random from the DamageParticleSystems list is spawned on it. Once the unit has been healed (or killed), the system is destroyed. Should the unit be healed, and then immediately damaged again, a new smoke system will not be spawned while the old one still exists.
  • Cyborgs with DamageSparks=yes In TS, when Cyborgs (Cyborg=yes) had yellow ([AudioVisual]ConditionYellow=) or less health, sparks would spawn from their bodies (DamageSparks). Similar to Organic units, a system is chosen at random from DamageParticleSystems, only this time, it will be one of the spark systems (BehavesLike=Spark). Again, there can only ever be one system per unit in existence. The odds of this system being created (assuming the previous condition allows it) are set in [General]ConditionRedSparkingProbability= or [General]ConditionYellowSparkingProbability=, depending on whether the cyborg's health is below [AudioVisual]ConditionRed= or not.
  • AttachedParticleSystem A unit fires a weapon with an AttachedParticleSystem. The weapon should have IsRailgun, UseSparkParticles or UseFireParticles set (depending on the type of ParticleSystem attached), and will not be able to fire any more weapons with that flag until the ParticleSystem expired. (e.g. a unit which fires an IsRailgun=yes weapon has to wait until the railgun system it spawned has vanished before it will be able to fire any other weapon with IsRailgun=yes.)
  • Map Actions can call for the creation of a ParticleSystem.
  • Scenario start All subjectively "unmanaged" Particles (i.e. those not spawned by a ParticleSystem) are actually part of a hidden global ParticleSystem named "GasCloudSys".
  • 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 IsElectricBolt=yes is fired - the [CombatDamage]DefaultSparkSystem= will be created. Like the parasite one, this system is ownerless.
  • A warhead with Particle 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 Explodes=yes 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 NaturalParticleSystem , if any, is created. This system is recreated whenever the building decloaks, Warning small.png however, this part is done if the BuildingType has the NaturalParticleLocation 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 DestroyParticleSystems (only systems with BehavesLike=Smoke are eligible) will be created.
  • A Harvester or a Slave unloads ore at a Refinery - up to four instances of the System specified as RefinerySmokeParticleSystem will be created, depending on how many of RefinerySmokeOffsetOne, RefinerySmokeOffsetTwo, RefinerySmokeOffsetThree, RefinerySmokeOffsetFour are set to non-zero. These systems will auto expire after RefinerySmokeFrames frames.

Automated Lag Countermeasures

To reduce lag, particles that do not have a non-zero Damage 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 BehavesLike=Fire or BehavesLike=Smoke do).

  • Particles with BehavesLike=Spark or BehavesLike=Gas are not drawn at low Visual Detail Level.
  • Particles with BehavesLike=Spark or BehavesLike=Railgun cannot have an SHP image and are always drawn as a single pixel.
  • Particles with BehavesLike=Smoke, BehavesLike=Gas or BehavesLike=Fire need to have an 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 Translucent25State and Translucent50State controls (see the section on DC/EC for more details). Chained particles in a system that has BehavesLike=Smoke can become more translucent than their predecessors with random luck.

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 unreasonable - 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 BehavesLike=Smoke or BehavesLike=Gas. 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 BehavesLike=Railgun 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 BehavesLike=Smoke or BehavesLike=Gas use the "AIState" as the frame index.
Particles with BehavesLike=Fire use the "AIState" + ((direction of the trajectory % 4) * EndStateAI) as the frame index. Basically, the frames [0..EndStateAI - 1] are used for directions 0 and 4 (straight north/south), frames [EndStateAI..2 * EndStateAI - 1] are used for directions 1 and 5 (NE/SW), and so on. Check the TS flameall.shp for details.


To be continued...

"SHP Railgun hack"

The original, pixel-based railgun has one significant drawback: Universally, whenever a railgun is fired, there will be a noticeable slowdown of the game. This made the usage of railguns by modders a double-edged sword - on one hand, especially in Red Alert 2 and Yuri's Revenge, it was a cool, unused effect for weapons; on the other hand, using it, especially on "common" units, would make the game crawl to a halt.

In 2004, gamemate discovered and published a hack that allowed putting SHP images in place of the generated pixels of a railgun. This technique made railguns both more customizable, allowing their usage for a wide array of weapons, as well as, magically, lag free. gamemate's advice was subsequently copied to PPM's tutorial section and has since been the go-to solution for lag-free railguns.

On the technical side, gamemate's statement "both must be present for this to work" is incorrect; the later BehavesLike=Smoke simply overrides BehavesLike=Railgun anyway. What does the magic is a simple fact: The code does not check whether BehavesLike on a Particle is set to the same behavior as BehavesLike on the ParticleSystem controlling it. Knowing this, one can craft constructs in which the two flags mismatch and create new, interesting combinations. The key to this particular hack is having a ParticleSystem that BehavesLike=Railgun and controls Particles which BehavesLike=Smoke, and thus accept (require) SHPs for their imagery.

Example Code

As originally posted by gamemate, cleaned up.

; Particle system
[XXXXSys]
BehavesLike=Railgun
HoldsWhat=XXXXPart
Spawns=yes
SpawnFrames=1
SpawnRadius=1
Slowdown= ; Can be any number, .002 is a good value
ParticleCap=7
SpawnCutoff=10
SpawnTranslucencyCutoff=11
; Particle
[XXXXPart]
BehavesLike=Smoke
MaxEC=30
Image=XXXX ; Short small anims are the best ones
Translucency=25
Velocity=5.0
Deacc=.05
WindEffect=0
DeleteOnStateLimit=yes
EndStateAI=20
StateAIAdvance=3 

See also


Needs particle flag box here