Particle Effects
Particle effects can be used to add pizzazz to your game. There are two parts to adding particles: invoking the particles from your main Lua code and actually defining them. We'll cover invoking particle effects first, since it's considerably simpler, and you'll want to be able to invoke your new effects to test them out and tune their parameters.
Contents
Invoking Particles
Assuming your particle effect is named "my_particle.lua" (see below, there are a few main options for invoking it. (Other alternatives also exist for more specialized circumstances.)
On the map
The Map.particleEmitter function can add a particle effect to the map. For example, if a talent should display an effect centered on the user, add the following code to your talent's action
function:
game.level.map:particleEmitter(self.x, self.y, 1, "my_particle")
Make sure that your particle effect limits how many particles it generates; otherwise, it can run forever.
On an entity
A long-lasting particle effect can be added to an entity with Entity.addParticles and removed with Entity.removeParticles. For example, to associate a particle effect with a status condition, add the following to the appropriate newEffect
block in your timed_effects.lua
:
activate = function(self, eff) eff.particle = self:addParticles(Particles.new("my_particle", 1)) end, deactivate = function(self, eff) self:removeParticles(eff.particle) end,
As a projectile
See ActorProject.
Testing your particle effects
Note that particle effects files are loaded every time they're invoked. This makes it very easy to test your particles: make up a talent that invokes the particles, give it no resource cost and no cooldown, and invoke it as much as you want as you tweak the particle parameters.
Defining Particles
To define a new particle effect, create a Lua file under your module's data/gfx/particles
directory.
The ToME source code has a huge set of existing particle effects under game/modules/tome/data/gfx/particles, so you can look there to see how particular effects are implemented.
Basic concepts
Particle effects are processed at 30 frames per second (regardless of the T-Engine's actual frame rate).
A particle effect is a fragment of Lua code that returns the following:
- A table of parameters for each particle. This table can define parameters directly, or it can contain a
generator
function that returns a table of parameters each time it's invoked. - An emitter function. This function is called every frame (i.e., 30 times a second). Its main job is to call
self:ps:emit(N)
(where N is the number of particles to generate for that frame) as appropriate. - (Optional) A number giving the maximum number of particles that the system will handle for this particle effect. Setting this too high will slightly hurt performance.
- (Optional) A string giving an image filename (minus extension) to load and use in place of the standard dot or spherical image.
- (Optional) A boolean that can be set to cause the particle system to not be automatically deleted when no more particles exist. Use with care.
Under normal conditions, a particle system will be automatically deleted when no more particles exist. The emitter function often limits itself to only running a certain number of times to ensure that particle systems don't go on forever.
Some basic trigonometry may be helpful to convert between x, y coordinates and angles on a circle.
Parameters
Particle effect code can return a table of parameters directly for use with the T-Engine's simple generator, or it can return a generator function.
Simple generator
A table for use with the simple generator might look like this:
return { base = 1000, angle = { 0, 360 }, anglev = { 2000, 4000 }, anglea = { 200, 600 }, life = { 5, 10 }, size = { 3, 6 }, sizev = {0, 0}, sizea = {0, 0}, r = {0, 0}, rv = {0, 0}, ra = {0, 0}, g = {80, 200}, gv = {0, 10}, ga = {0, 0}, b = {0, 0}, bv = {0, 0}, ba = {0, 0}, a = {255, 255}, av = {0, 0}, aa = {0, 0}, }
Note that each value is given as a pair of numbers; these give the minimum and maximum values for the RNG to randomly generate each particle. Also note that colors (r, g, b, and a) range from 0 to 255. Only integers are permitted.
The simple generator is fairly restrictive; it's only really suitable for particles moving outwards from a central point.
Generator function
The same particle effect expressed as a generator function would look like this: (UNTESTED)
return { generator = function() return { trail = 0, life = rng.range(5, 10), size = rng.range(3, 6), sizev = 0, sizea = 0, x = 0, xv = 0, xa = 0, y = 0, yv = 0, ya = 0, dir = math.rad(rng.range(0, 360)), dirv = 0, dira = 0, vel = rng.range(2, 4), velv = rng.range(0.2, 0.6), vela = 0, r = 0, rv = 0, ra = 0, g = rng.range(80, 200)/255, gv = rng.range(0, 10)/255, ga = 0, b = 0, bv = 0, ba = 0, a = 1, av = 0, aa = 0 } end }
The generator function invokes the RNG itself and returns floating point numbers.
Parameter values
Several parameters have ...v and ...a values. These give velocity and acceleration for that value. Each frame, velocity is added to the base value, then acceleration is added to velocity (causing velocity to change for future frames). For example:
r = 1, rv = -0.1, ra = 0 g = 0, gv = 0, ga = 0, b = 0, bv = 0, ba = 0
starts out solid red and fades to black over 10 frames.
As another example:
y = 0, yv = 0, ya = -0.4
creates a particle that is initially motionless but starts moving up faster and faster.
Details on values:
General settings | |
life | Number of frames for which the particle will exist |
size, sizev, sizea | Size of the particle |
Simple generator only | |
base | All velocity and acceleration values are divided by this before being processed (since the default generator can't take fractional values directly). |
angle, anglev, anglea | Angle along which the particle should move, in degrees, and velocity and acceleration at which it should move along that angle. Generator functions can use dir and vel for a similar effect. |
Generator function only | |
trail | Used to draw trails from one particle to another |
x, xv, xa | x coordinate, relative to the center of the particle system |
y, yv, ry | y coordinate, relative to the center of the particle system |
dir, dirv, dira | Angle along which the particle should move, in radians. dirv and dira give the rate at which that angle should change. |
vel, velv, vela | Velocity to move along the angle given by dir, and the "velocity of velocity" (i.e., acceleration) and the "acceleration of velocity." Movement can be done via xv, xa, yv, ya or dir, vel (or both at the same time). |
Color | |
r, rv, ra | Red component |
g, gv, ga | Green component |
b, bv, ba | Blue component |
a, av, aa | Alpha component. 255 (for the simple generator) or 1 (for a generator function) means fully opaque, 0 means fully transparent. |