Skip to content

Particles

Fire, smoke, sparks, dust — attached to an object with self:particles.

luau
self:particles({ preset = "fire" })      -- a whole campfire
self:particles()                         -- remove it

The 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

KeyTypeMeaning
ratenumberparticles born per second
lifenumber or pairhow long one lives, in seconds

Where they come from

KeyTypeMeaning
shapestring"cone" (default), "sphere", "beam"
anglenumbercone half-angle, in degrees
directionpointwhich way the cone points, in the object's own frame
offsetpointwhere they are born, relative to the object
radiusnumbersize 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

KeyTypeMeaning
speednumber or pairstarting speed, m/s
gravitynumbervertical acceleration, m/s². Negative falls, positive rises
dragnumberair resistance, per second
spinnumbersprite 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

KeyTypeMeaning
sizenumber or pairradius in metres, at birth then at death
texturestringthe sprite: "soft", "spark", "smoke", "ring", "star", "ember"
colorcolour, or up to 4across the particle's life
alphanumber, or up to 4opacity across the life
glownumberhow bright it is where it sits
blendstring"add" (default) or "alpha"
stretch0 – 10 is round, 1 is stretched along the direction of travel
softnessnumbermetres 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)

See also

Hungrit scripting documentation.