Particle file format
A typical particle effect file looks like:
<?xml version="1.0" encoding="utf-8"?> <particles> <texture>art/textures/particles/flame.png</texture> <blend mode="add"/> <!-- Parameters: --> <constant name="emissionrate" value="20.0"/> <uniform name="lifetime" min="1.0" max="1.5"/> <uniform name="position.x" min="-8.0" max="8.0"/> <uniform name="position.z" min="-8.0" max="8.0"/> <constant name="position.y" value="0.0"/> <uniform name="angle" min="-0.5" max="0.5"/> <uniform name="velocity.x" min="-0.3" max="0.3"/> <uniform name="velocity.y" min="2.0" max="2.5"/> <uniform name="velocity.z" min="-0.3" max="0.3"/> <uniform name="velocity.angle" min="-0.5" max="0.5"/> <uniform name="size" min="1.0" max="2.0"/> <uniform name="size.growthRate" min="1.0" max="2.0"/> <uniform name="color.r" min="0.8" max="1.0"/> <copy name="color.g" from="color.r"/> <copy name="color.b" from="color.r"/> <!-- Effectors: --> <force y="-2.5"/> </particles>
Particle files supporting hotloading: if you edit the XML while the game is running, it should automatically reload the file and start rendering the new effect when you switch back to the game. (Note the game is usually paused when its window is not focused, so the new animation won't play until you re-focus the window.)
All effect files must specify a texture and blend mode. The blend mode controls how each particle is drawn on top of the background, and is one of the following:
- The RGB colour of the texture is added to the background. Useful for bright effects e.g. flames.
- The RGB colour of the texture is subtracted from the background.
- The RGB colour of the texture is multiplied from the background. (Colours are interpreted as fractions in the range 0 to 1, so this will always make things darker).
- The RGB colour of the texture is drawn over the background, with transparency determined by the alpha channel. This is useful for more solid-looking particles, but may introduce visible glitches when particles are drawn over nearer particles, so it should be tested carefully from all angles.
The main part of the effect file is specifying initial particle parameters. Every time a new particle is created by the particle emitter, its state is determined by these parameters.
The available parameters are:
- emissionrate - number of particles per second that will be emitted.
- lifetime - number of seconds before the particle disappears.
- position.x - initial position of particle relative to the emitter point.
- position.y - initial position (Y axis is vertical).
- position.z - initial position.
- angle - initial rotation of sprite (they always face the camera but can rotate around one axis), in radians (6.28 radians = 360 degrees).
- velocity.x - initial speed in metres per second.
- velocity.angle - rotation speed in radians per second.
- size - size in metres.
- size.growthRate - number of metres by which the size increases (if positive) or decreases (if negative) per second.
- color.r - colour, which will be multiplied by the RGB of the texture.
Each parameter can be specified in a number of ways:
- <constant name="parameter" value="number"/> - the parameter will always have the given value.
- <uniform name="parameter" min="number" max="number"/> - the parameter will be given a random value between min and max. Every value in that range is equally likely (hence the "uniform"). Max must be greater than min.
- <copy name="parameter" from="parameter"/> - the parameter's value will be copied from the value of some other parameter. This lets you do randomised greyscale colours - use a uniform for color.r so that it's given a random value, then use some copy so that color.g and color.b are given the same random value as color.r. The 'from' parameter must have been computed first (i.e. be higher up in the parameter list from earlier in this section - color.g can copy from color.r, but can't copy from color.b since that's computed later).
- <expr name="parameter" ..."/> - a hopefully-temporary inflexible hack to make construction dust scale with the number of workers. You probably shouldn't use this.
Each parameter has a sensible default value, so you don't need to explicitly specify them all. E.g. you can omit all the position parameters if the particles should just be emitted directly from the emitter point instead of being spread randomly over a larger volume.
Once a particle has been emitted, it will move and spin according to its velocity, and it will automatically fade in and out. You can add more complex motion with particle effectors.
Currently they're very limited so the only thing you can do is:
- <force x="number" y="number" z="number"/> - each particle will be subjected to a constant acceleration force (in metres per second per second) in each direction. Each attribute will default to 0, so typically you can just write e.g. <force y="-2.5"/> to get downwards acceleration (simulating gravity).
To make use of particle effects in the game, you have to create an actor that links to them. An actor XML file like
<?xml version="1.0" encoding="utf-8"?> <actor version="1"> <group> <variant name="Base"> <particles file="flame.xml"/> </variant> </group> <material>basic_trans.xml</material> </actor>
will typically be sufficient. You can then use that actor directly in the game, or as a prop attached to a prop-point on another actor.