Emission
The runtime exposes six methods at the top of the call hierarchy. Each takes a transformed item (or native ParticleEmitter / Trail) and routes to the right per-type implementation under the hood. The per-type methods (:EmitPart, :EmitBeam, etc.) are documented in Per-type Methods — most code calls the dispatchers in this chapter.
All examples assume Part_Icles is the required module and :Activate has been called. See Lifecycle.
Start here:
:AbsoluteEmitis the primary tool. Hand it any instance — a transformed Part, a Folder of mixed transformed and native emitters, an entire Model rig, evenworkspace— and it fires everything emit-able inside the subtree, using each item’s own authored attributes (EmitCount,EmitDelay,EmitDuration). One call, regardless of how the rig is structured, regardless of which mix of transformed types and nativeParticleEmitter/Trailinstances live inside. If you only learn one method from this chapter, learn:AbsoluteEmit.The other dispatchers (
:Emit,:EmitAnimate,:Enable,:EnableEmit,:Disable) exist for the cases where you want precise control over a single emitter — when “fire everything” is too coarse, or when you need to gate, throttle, or interrupt mid-flight. Reach for them when you’ve outgrown the simplicity of:AbsoluteEmit. The plugin’s Emit Code tool in the Toolbench generates:AbsoluteEmitcalls by default for that reason.
At a glance
Section titled “At a glance”| Method | Signature | Purpose |
|---|---|---|
:AbsoluteEmit(item) | recursive, fire-everything | The primary tool. Walk item and its descendants; fire every transformed emitter and every native ParticleEmitter / Trail in the subtree using each one’s authored timing. One call, any input. |
:Emit(item, link?) | one-shot dispatch | Spawn one particle (or one clone, for screen / image / light types). For a single emitter, single burst. |
:EmitAnimate(item, link?) | one-shot Animate dispatch | Trigger Animate-mode emission (source plays graphs in place). |
:Enable(item, link?, duration?) | bare continuous loop | Start a Heartbeat-driven emission loop at the item’s Rate. Stops when duration elapses or :Disable called. |
:EnableEmit(item, link?) | scripted-timing wrapper | Read EmitCount / EmitDelay / EmitDuration on the item, run the full wait → burst → loop sequence. The single-emitter equivalent of :AbsoluteEmit. |
:Disable(item) | stop everything | Cancel any active loop and any in-flight Animate cycle on item. |
The optional link parameter is the same idea as the Linking chapter’s Link Dir. field — pass an instance whose CFrame the emitter should track. Pass nil (or omit) for unlinked emission. :AbsoluteEmit doesn’t take a link because it’s already operating across a subtree — each transformed item inside uses its own authored Link configuration.
Particle:Emit(item, link?)
Section titled “Particle:Emit(item, link?)”Spawn a single particle. Routes by type: BasePart → :EmitPart, Beam → :EmitBeam, etc. (full list in Per-type Methods).
Part_Icles:Emit(workspace.ExplosionFX)One call produces one particle. EmitCount is not read by :Emit — that attribute belongs to :EnableEmit, which loops over :Emit EmitCount times. To fire many particles at once, either call :Emit in a loop yourself or use :EnableEmit and let it read the attributes. For continuous emission at the item’s Rate, use :Enable.
If item is nil or has no parent, :Emit returns silently. If item is an unrecognised type, :Emit is a no-op.
For Animate-mode items, :Emit does NOT auto-redirect to Animate — call :EmitAnimate explicitly.
Trail is not dispatched by :Emit (or by :Enable / :EnableEmit). Trails use a different storage path with no Configuration child, so the per-type lookup returns nil and there’s no per-type Trail emit method to call. Use :AbsoluteEmit for a transformed Trail — its native-Trail branch parses EmitDuration and toggles Enabled. Or just toggle trail.Enabled yourself.
Particle:EmitAnimate(item, link?)
Section titled “Particle:EmitAnimate(item, link?)”Animate-mode dispatcher. For 3D types (Part / Beam / Attachment / Model) the source instance plays its graphs in place; no clones. For screen-space types (Blur / Bloom / ColorCorrection / Atmosphere / ImageLabel) the call produces a singleton clone — at most one Animate clone alive per source at a time. A second :EmitAnimate while the first is mid-cycle is silently dropped.
Part_Icles:EmitAnimate(workspace.PulsingOrb)If the item has AnimateLoop = true, the Heartbeat re-triggers the cycle when it ends — call :Disable to stop it. With AnimateLoop = false, the cycle plays once and the source resets to its starting state.
Atmosphere is force-pinned to Animate mode at Transform time. :EmitAnimate(myAtmosphere) is the right call for it.
Particle:Enable(item, link?, duration?)
Section titled “Particle:Enable(item, link?, duration?)”Continuous emission loop. Spawns a task.spawn thread that calls :Emit(item, link) repeatedly at the item’s Rate (particles per second) until one of:
durationseconds elapse (defaultmath.huge— runs forever)- The item’s parent becomes
nil(despawned) :Disable(item)is called- The Configuration child’s
Enabledattribute flips tofalse
Part_Icles:Enable(workspace.WaterFountain) -- runs until you stop itPart_Icles:Enable(workspace.SmokeStack, nil, 30) -- runs for 30sPart_Icles:Enable(workspace.SwordSpark, sword.Tip, 2) -- linked, 2sThe loop uses an accumulator — sub-frame Rate values still spawn correctly. A Rate of 200 on a 60Hz tick produces ~3.33 particles per frame, alternating 3 and 4 across frames so the long-run average matches.
Animate-mode short-circuit: if the item has EmissionMode = "Animate", :Enable flips AnimateLoop = true and calls :EmitAnimate instead. The Heartbeat handles the re-triggering — no separate loop thread.
Particle:EnableEmit(item, link?)
Section titled “Particle:EnableEmit(item, link?)”The full scripted-timing dispatcher. Reads three attributes on item:
EmitCount(script-side fallback1if the attribute is missing) — how many instant bursts at start.EmitDelay(default0) — seconds to wait before the first burst.EmitDuration(default0) — seconds of continuous loop after the initial bursts.0= no loop.
Auto-bump: if both EmitCount and EmitDuration read as 0 (the default for a freshly transformed Part / Attachment / Model / PointLight whose timing the user hasn’t configured), :EnableEmit treats the call as “fire once” and runs one burst. Without this, a default-zero item would produce no emission at all.
Then it runs:
- Wait
EmitDelay. - Trigger
EmitCountinstant bursts via:Emit. - If
EmitDuration > 0, start:Enablefor that many seconds.
spell:SetAttribute("EmitCount", 3)spell:SetAttribute("EmitDelay", 0.2)spell:SetAttribute("EmitDuration", 1.5)Part_Icles:EnableEmit(spell)→ wait 0.2s, fire 3 bursts, then loop continuously for 1.5s.
This is the right call for effects whose timing was authored on the item itself — the script just says “play it” and the attributes carry the rest.
Animate-mode behaviour: if EmissionMode = "Animate", the call respects EmitDelay and uses EmitDuration to bound how long AnimateLoop stays true. EmitCount is unused (Animate-mode doesn’t burst-fire).
Particle:Disable(item)
Section titled “Particle:Disable(item)”Stop everything running on item:
- Any continuous
:Enableloop is cancelled. - Any in-flight Animate cycle is cancelled, source CFrame restored.
- The Configuration child’s
Enabledattribute flips tofalseso the auto-listener doesn’t restart.
Part_Icles:EnableEmit(stream)task.wait(0.5)Part_Icles:Disable(stream) -- cut shortIn-flight clone particles (already emitted) are NOT killed — they finish their lifetimes naturally. Only the spawning of new particles stops.
Particle:AbsoluteEmit(item)
Section titled “Particle:AbsoluteEmit(item)”The fire-everything dispatcher. Hand it any instance and it triggers every emitter the subtree contains, regardless of how that subtree is organised — folders, models, attachments holding transformed children, transformed parents holding native ParticleEmitter and Trail children, all of it.
Why this is the primary tool. Real VFX rigs aren’t single emitters. An explosion is a flash plus a shockwave plus debris plus smoke plus a light plus a screen-tint plus a blur — six or seven emitters, each with its own authored timing. A spell-cast is a glow plus orbiting sparks plus a beam plus a UI flare. Authoring those rigs as a Folder (or Model) of transformed children, then triggering the whole rig with one :AbsoluteEmit call, is the canonical pattern. You don’t have to enumerate the children in your trigger script; you don’t have to remember which of them are transformed and which are native; you don’t have to call a different dispatcher per type. One call.
It also means the script and the authoring stay decoupled. If you add a new emitter to the rig in Studio (drop in another Beam, another PointLight), the existing :AbsoluteEmit call in your spell script picks it up the next time you trigger — no script edit required. The rig’s structure and timing live in Studio; the trigger is a single line.
Dispatch logic. When you call :AbsoluteEmit(item), the runtime checks item against four cases, in order:
itemhasTransformed = true(it’s a plugin-transformed emitter — Part / Beam / Attachment / Model / PointLight / ImageLabel / Blur / Bloom / ColorCorrection / Atmosphere) → call:EnableEmit(item, nil). The full scripted-timing flow runs:EmitDelaywait →EmitCountinstant bursts →EmitDuration-bounded continuous loop. Each transformed item uses its own authored attributes. Stop here; don’t recurse into the transformed item’s subtree.itemis a nativeParticleEmitter(Roblox’s stock PE, never transformed) → fire its native:Emit(EmitCount)for an instant burst, then ifEmitDuration > 0toggle.Enabled = truefor that many seconds and back tofalse.EmitCountdefaults to1andEmitDurationto0if the attributes are absent. Stop here.itemis aTrail(native or transformed — Trail’sdirectAccessdesign means the runtime treats both the same way; neither carries theTransformedattribute) → parseEmitDuration(a string, single number or"min,max"range) and pulseEnabled = true → falsefor the parsed duration. IfEmitDurationparses to0or fails, the pulse is skipped. Stop here.itemis anything else (aBasePart, anAttachment, aModel, aFolder, theworkspace, a UIFrame, …) → recurse intoitem:GetChildren()and run the same dispatch on each child. NativeParticleEmitter/Trailinstances insideBasePart/Attachment/Modelcontainers also fire via a separate sweep that walks:GetDescendants(), so you don’t have to worry about depth.
The recursion stops at every transformed item or native emitter it finds — those don’t get descended into, because their own :EnableEmit (or native fire) handles the cloning. If you nest a transformed Part inside a Folder inside another Folder, :AbsoluteEmit still finds it. If you nest one transformed Part inside another transformed Part’s RenderTemplate, that’s the nested-emitter pattern — the outer Part handles emitting it on its own.
Examples.
A simple folder of mixed emitters:
local rig = workspace.ExplosionVFX-- ExplosionVFX/-- CoreFlash (transformed Part)-- Shockwave (transformed Beam)-- Smoke (transformed Part)-- Light (transformed PointLight)-- ScreenColor (transformed ColorCorrection)-- ScreenBlur (transformed Blur)-- AmbientSparks (native ParticleEmitter — set its EmitCount attribute manually)-- FlashTrail (native Trail — set its EmitDuration attribute as "0.3")
Part_Icles:AbsoluteEmit(rig)→ all eight emitters fire together, each with its own authored timing.
A cloned VFX template (the typical “spawn an effect at a position” pattern):
local function castSpell(originPosition) local effect = ReplicatedStorage.SpellVFX:Clone() effect:PivotTo(CFrame.new(originPosition)) effect.Parent = workspace.Effects Part_Icles:AbsoluteEmit(effect) task.delay(5, function() effect:Destroy() end)endA whole Model (e.g. a fireball where the entire fireball is the rig):
local fireball = ReplicatedStorage.FireballVFX:Clone()fireball:PivotTo(CFrame.new(spawnPos))fireball.Parent = workspace.EffectsPart_Icles:AbsoluteEmit(fireball)A character’s full attached effects (every emitter the player carries — auras, weapons, UI):
Part_Icles:AbsoluteEmit(player.Character)→ every emitter inside the character’s hierarchy fires once. If you’ve authored an aura on the torso, sparks on a sword tip Attachment, and a UI flare on the player’s HUD, all three trigger together.
:AbsoluteEmit does not emit continuously — it triggers the authored emit timing once. For continuous ambient effects (fountains, torches), use :Enable per emitter or set Enabled = true on each transformed item’s Configuration once at game start.
The Toolbench’s Emit Code tool generates :AbsoluteEmit calls by default for any multi-component selection, for the same reason: it’s the simplest correct trigger for any rig shape.
Picking the right method
Section titled “Picking the right method”A decision tree:
- One instant burst →
:Emit - Continuous emission with no end →
:Enable(item)(no duration) - Continuous emission for N seconds →
:Enable(item, link, N) - Effect with attribute-baked timing (count + delay + duration) →
:EnableEmit - Animate-mode item →
:EmitAnimate(or:Enable, which short-circuits to Animate whenEmissionMode = "Animate";:Emitdoes not auto-redirect — use:EmitAnimatedirectly) - Folder/model containing many emitters →
:AbsoluteEmit - Cancel any of the above →
:Disable
Most game code uses :EnableEmit for triggered effects, :Emit for impacts and flashes, :AbsoluteEmit for assembled rigs. :Enable and :EmitAnimate are situational.
What’s next
Section titled “What’s next”The dispatchers route to per-type implementations. If you need to skip the dispatch (slightly faster, slightly more explicit), the Per-type Methods chapter covers the 10 emit-mode + 9 animate-mode methods directly. Otherwise Texture Pinning is next — :Preload and :Deload for keeping asset bytes resident.