Skip to content

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: :AbsoluteEmit is the primary tool. Hand it any instance — a transformed Part, a Folder of mixed transformed and native emitters, an entire Model rig, even workspace — 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 native ParticleEmitter / Trail instances 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 :AbsoluteEmit calls by default for that reason.

MethodSignaturePurpose
:AbsoluteEmit(item)recursive, fire-everythingThe 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 dispatchSpawn one particle (or one clone, for screen / image / light types). For a single emitter, single burst.
:EmitAnimate(item, link?)one-shot Animate dispatchTrigger Animate-mode emission (source plays graphs in place).
:Enable(item, link?, duration?)bare continuous loopStart a Heartbeat-driven emission loop at the item’s Rate. Stops when duration elapses or :Disable called.
:EnableEmit(item, link?)scripted-timing wrapperRead EmitCount / EmitDelay / EmitDuration on the item, run the full wait → burst → loop sequence. The single-emitter equivalent of :AbsoluteEmit.
:Disable(item)stop everythingCancel 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.

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.

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.

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:

  • duration seconds elapse (default math.huge — runs forever)
  • The item’s parent becomes nil (despawned)
  • :Disable(item) is called
  • The Configuration child’s Enabled attribute flips to false
Part_Icles:Enable(workspace.WaterFountain) -- runs until you stop it
Part_Icles:Enable(workspace.SmokeStack, nil, 30) -- runs for 30s
Part_Icles:Enable(workspace.SwordSpark, sword.Tip, 2) -- linked, 2s

The 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.

The full scripted-timing dispatcher. Reads three attributes on item:

  • EmitCount (script-side fallback 1 if the attribute is missing) — how many instant bursts at start.
  • EmitDelay (default 0) — seconds to wait before the first burst.
  • EmitDuration (default 0) — 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:

  1. Wait EmitDelay.
  2. Trigger EmitCount instant bursts via :Emit.
  3. If EmitDuration > 0, start :Enable for 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).

Stop everything running on item:

  • Any continuous :Enable loop is cancelled.
  • Any in-flight Animate cycle is cancelled, source CFrame restored.
  • The Configuration child’s Enabled attribute flips to false so the auto-listener doesn’t restart.
Part_Icles:EnableEmit(stream)
task.wait(0.5)
Part_Icles:Disable(stream) -- cut short

In-flight clone particles (already emitted) are NOT killed — they finish their lifetimes naturally. Only the spawning of new particles stops.

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:

  1. item has Transformed = 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: EmitDelay wait → EmitCount instant bursts → EmitDuration-bounded continuous loop. Each transformed item uses its own authored attributes. Stop here; don’t recurse into the transformed item’s subtree.
  2. item is a native ParticleEmitter (Roblox’s stock PE, never transformed) → fire its native :Emit(EmitCount) for an instant burst, then if EmitDuration > 0 toggle .Enabled = true for that many seconds and back to false. EmitCount defaults to 1 and EmitDuration to 0 if the attributes are absent. Stop here.
  3. item is a Trail (native or transformed — Trail’s directAccess design means the runtime treats both the same way; neither carries the Transformed attribute) → parse EmitDuration (a string, single number or "min,max" range) and pulse Enabled = true → false for the parsed duration. If EmitDuration parses to 0 or fails, the pulse is skipped. Stop here.
  4. item is anything else (a BasePart, an Attachment, a Model, a Folder, the workspace, a UI Frame, …) → recurse into item:GetChildren() and run the same dispatch on each child. Native ParticleEmitter / Trail instances inside BasePart / Attachment / Model containers 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)
end

A 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.Effects
Part_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.

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 when EmissionMode = "Animate"; :Emit does not auto-redirect — use :EmitAnimate directly)
  • 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.

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.