Particles#
Fire, smoke, sparks and dust, attached to an object with self:particles.
Use it to
- add fire, smoke, sparks or dust to an object
- start from a preset, then change only what you need
- look up what every field of an emitter does
self:particles({ preset = "fire" }) -- a whole campfireself:particles() -- remove itThe emitter belongs to the object: it follows it and dies with it. Nothing is sent per particle, so every viewer draws the same field from this description, so it costs the same for one watcher or forty.
Start from a preset#
Naming one is almost always the right first move. Each is hand-tuned and already looks like the thing it is named after.
fire · smoke · sparks · torch · magic · dust · steam · fireflies
Then override only what you care about:
self:particles({ preset = "smoke", rate = 40, speed = { 0.4, 1.1 } })An unknown preset name is refused, and the refusal lists the real ones.
One number, or two#
Many fields take a number or a {min, max} pair. The pair is what makes an effect look alive: everything moving at exactly one speed reads as a texture scrolling, while the same particles spread over {3, 6} read as a fire.
How many, and how long#
| Key | Type | Meaning |
|---|---|---|
rate | number | particles born per second |
life | number or pair | how long one lives, in seconds |
Where they come from#
| Key | Type | Meaning |
|---|---|---|
shape | string | "cone" (default), "sphere", "beam" |
angle | number | cone half-angle, in degrees |
direction | point | which way the cone points, in the object's own frame |
offset | point | where they are born, relative to the object |
radius | number | size of the birth region, in metres. 0 is a single point |
direction being in the object's own frame is what lets a torch keep pointing up its own handle when you lay it on its side.
How they move#
| Key | Type | Meaning |
|---|---|---|
speed | number or pair | starting speed, m/s |
gravity | number | vertical acceleration, m/s². Negative falls, positive rises |
drag | number | air resistance, per second |
spin | number | sprite rotation, radians per second |
gravity positive is what makes hot smoke climb.
drag is what makes a smoke column slow down and spread instead of rising forever in a straight line. It is the difference between smoke and a jet.
How they look#
| Key | Type | Meaning |
|---|---|---|
size | number or pair | radius in metres, at birth then at death |
texture | string | the sprite: "soft", "spark", "smoke", "ring", "star", "ember" |
color | colour, or up to 4 | across the particle's life |
alpha | number, or up to 4 | opacity across the life |
glow | number | how bright it is where it sits |
blend | string | "add" (default) or "alpha" |
stretch | 0 to 1 | 0 is round, 1 is stretched along the direction of travel |
softness | number | metres of fade where particles meet a wall or the floor |
Careful
size is birth-then-death, not min-and-max. { 0.12, 0.02 } shrinks and { 0.18, 0.85 } grows. It is the one pair on this page that does not mean a random range.
The sprites are drawn by the engine, so no upload and no image file.
glow#
A multiple of how bright white is where the particle sits. At 1 it is simply lit by the world, which is what smoke wants. Above 1 it gives off light instead, at that multiple, and blooms.
Tip
Fire that does not look like fire is almost always fire with glow = 1.
blend#
"add" piles light up, which suits fire, sparks and magic. "alpha" covers what is behind it, which suits smoke and dust. Using "add" on smoke gives you glowing fog; using "alpha" on fire gives you orange paper.
stretch#
What separates a spark from an orange dot. Ignored when spin is set, since a stretched sprite is already oriented by its travel.
softness#
Without it, smoke cuts the ground in a straight line and the illusion dies.
Colour across a life#
color = { "#fff3b0", "#ff9a3c", "#8c2f10", "#20000000" },Up to four stops. The eight-digit form puts the opacity in front, so "#20000000" reads as black, nearly transparent, which is a clean way to fade out.
Two worked examples#
A campfire that is warmer and lazier than the preset:
self:particles({ preset = "fire", rate = 60, life = { 0.7, 1.4 }, speed = { 0.7, 1.6 }, size = { 0.16, 0.02 }, glow = 3.5, softness = 0.3,})A dust puff where something landed, with no preset and everything stated:
self:particles({ rate = 0, -- see below shape = "sphere", life = { 0.4, 0.9 }, speed = { 0.5, 1.8 }, size = { 0.05, 0.35 }, gravity = -1.2, drag = 3, color = { "#b8a891", "#40000000" }, blend = "alpha", glow = 1, softness = 0.2,})Tip
There is no "burst" verb. For a one-off puff, turn the emitter on, and turn it off again a moment later:
self:particles({ preset = "dust", rate = 200 })self:after(0.15, function() self:particles()end)See also#
Updated 17 October 2026