§ How to · with Picoo
How to make particle effects in Roblox
By Sametcan Tasgiran, Founder & Developer·Published ·Updated
Particles are the cheapest way to make a Roblox game look expensive, and the fastest way to make it run badly.
Three rules cover almost everything: how bursts are fired, what sequences will accept, and the one multiplication that tells you what you are actually spending.
Correct one-shot bursts
Emit-based impacts that finish their lifetime instead of being destroyed mid-flight.
Valid sequences
Size, transparency and colour curves built to the keypoint rules, so they do not error at runtime.
Budgeted emitters
Rate and Lifetime chosen against a target particle count rather than by eye.
Attachment-based effects
Beams and Trails wired to attachments correctly, including the part that only shows when things move.
Layered VFX
Impact, smoke and spark emitters combined into one reusable effect instance.
Client-side where it belongs
Cosmetic effects rendered locally instead of replicating hundreds of instances.
Files Picoo ships for this prompt
2 files · 175 lines · ~30s · 1 credit
VFXLibrary
Named effects, emitter templates, sequence builders, burst helper.
120 lines
VFXClient
Local playback, pooling, cleanup after lifetime.
55 lines
Sample output: ReplicatedStorage.VFXLibrary
-- ONE-SHOT BURSTS. The wrong version sets Enabled = true, waits, and destroys
-- the part -- which deletes particles that are still mid-flight, so the effect
-- visibly cuts off. Correct: keep Enabled false, Emit(n), and clean up only
-- after the longest possible lifetime has passed.
local function burst(emitter: ParticleEmitter, count: number)
emitter.Enabled = false
emitter:Emit(count)
local maxLife = emitter.Lifetime.Max
Debris:AddItem(emitter.Parent :: Instance, maxLife + 0.1)
end
-- SEQUENCES have rules the docs state and the editor hides: at least two
-- keypoints, the first at time 0 and the last at time 1. Build them and you
-- get a runtime error, not a warning.
local function fade(startSize: number, endSize: number): NumberSequence
return NumberSequence.new({
NumberSequenceKeypoint.new(0, startSize), -- MUST be time 0
NumberSequenceKeypoint.new(0.35, startSize * 0.8),
NumberSequenceKeypoint.new(1, endSize), -- MUST be time 1
})
end
-- THE BUDGET. Particles alive at once ~= Rate * Lifetime. An emitter at
-- Rate 200 with Lifetime 3 keeps ~600 particles on screen forever -- and ten
-- of those emitters is what kills frame rate on phones, not "too many parts".
local function aliveCount(e: ParticleEmitter): number
return e.Rate * e.Lifetime.Max
endBuilding particle effects in Roblox
Particles carry more of a Roblox game's perceived quality than almost anything else you can add, which is why they are worth understanding properly rather than dragging in from a free model.
The first thing to get right is how a burst is fired. The intuitive approach — enable the emitter, wait a moment, disable it, destroy the part — produces an effect that visibly cuts off, because destroying the instance deletes every particle it owns regardless of how much lifetime they had left. The correct shape is the opposite: leave the emitter disabled, call Emit with the count you want, and schedule cleanup for after the longest lifetime has expired. You also get an exact particle count that way, instead of one that varies with frame rate.
The second is the sequences. Size, transparency and colour are all curves, and Roblox enforces rules on them that the property editor quietly handles for you: at least two keypoints, the first at time zero, the last at time one. Build one in code that ends at 0.9 and you get a runtime error rather than a warning, which is a confusing failure the first time it happens.
The third is the budget, and it is a single multiplication. Rate times Lifetime is approximately how many particles are alive at any given moment. An emitter at Rate 200 with a three-second lifetime is sustaining around six hundred particles indefinitely — fine on its own, ruinous when eight of them are running near each other on a phone. Knowing that number turns "the game got laggy" into a thing you can budget for before shipping.
After that it is mostly placement. Beams and Trails are attachment-driven, and a Trail only draws while its attachments are moving and separated — two attachments at the same point produce a trail with no width, which looks exactly like a trail that is broken.
See more on the Luau generator, the game builder, or browse the full blog.
Frequently asked
Why does my explosion cut off halfway?+
The emitter or its parent was destroyed while particles were still alive. Destroying the instance removes its particles instantly, no matter how much lifetime they had left. Emit the burst, then delay cleanup by at least the emitter's maximum Lifetime.
Rate or Emit?+
Rate is for continuous effects — smoke, fire, a torch. Emit is for one-shot events — an impact, a level-up, a hit spark. Firing a one-shot by enabling Rate briefly gives you an inconsistent particle count, because how many you get depends on how many frames passed before you turned it off.
Why does my NumberSequence error?+
Sequences need at least two keypoints, the first at time 0 and the last at time 1. Anything else throws at runtime rather than warning, and it is easy to hit when generating curves in code — a loop that ends at 0.9 produces a sequence Roblox rejects.
How many particles is too many?+
Multiply Rate by Lifetime — that is roughly how many are alive at any moment. An emitter at Rate 200 and Lifetime 3 sustains around 600, and a handful of those together is what drops frame rate on phones. Compare that number against a budget instead of judging by eye on a desktop.
Should particles be created on the server?+
Only when every player must see the same thing at the same moment, and even then send an event rather than replicating dozens of instances. Purely cosmetic effects — muzzle flashes, footstep dust, UI sparkles — belong on the client, where they cost nothing in replication.
Why is my Trail invisible?+
Trails only draw when their attachments move, and they need both Attachment0 and Attachment1 set to two different attachments with a gap between them. A trail with both attachments in the same spot has no width and renders nothing.
Related Picoo prompts
Roblox magic spell system
7 files · 240 lines · 1m 06s · 1 credit. 5 spell archetypes, configurable.
How to set up lighting and atmosphere in Roblox
It is also full of settings that silently cancel each other out — an Atmosphere that makes your fog values do nothing, a Technology mode where your torches cast no shadow.
Roblox combat system
5 files · 140 lines · 42 seconds · 1 credit. Drop into your place and press Play.