Appearance
Particles
Fire, smoke, sparks, dust — attached to an object with self:particles.
luau
self:particles({ preset = "fire" }) -- a whole campfire
self:particles() -- remove itThe emitter belongs to the object: it follows it and dies with it. Nothing is sent per particle — 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:
luau
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 – 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 |
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 — no upload, 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.
Fire that does not look like fire is almost always fire with glow = 1.
blend
"add" piles light up — fire, sparks, magic. "alpha" covers what is behind — smoke, 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
luau
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 — a clean way to fade out.
Two worked examples
A campfire that is warmer and lazier than the preset:
luau
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 — no preset, everything stated:
luau
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,
})There is no "burst" verb. For a one-off puff, turn the emitter on, and turn it off again a moment later:
luau
self:particles({ preset = "dust", rate = 200 })
self:after(0.15, function()
self:particles()
end)