Examples
The previous chapters covered the API surface — Lifecycle for :Activate / :Deactivate, Emission for the six dispatchers, Per-type Methods for direct calls, Texture Pinning for asset warming. This chapter walks through four canonical use cases end-to-end — the kind of problems most games encounter, with complete script examples you can adapt.
Pattern 1: Sword slash — sparks on swing
Section titled “Pattern 1: Sword slash — sparks on swing”You have a sword in your game, and you want sparks to fly off the tip when the player swings. The sword has an Attachment at its tip, and you’ve transformed that Attachment as a Beam emitter (via the plugin’s panel).
The trigger runs on a swing event from your sword script. The emission is brief — a few sparks, no follow-up.
local Part_Icles = require(game.ReplicatedStorage:WaitForChild("Part_Icles"))Part_Icles:Activate()
local swordSpark = workspace.Sword.SparkAttachment.SparkBeam -- transformed Beam
-- Set timing onceswordSpark:SetAttribute("EmitCount", 1)swordSpark:SetAttribute("EmitDuration", 0.15)
-- Connect to swing eventsword.OnSwing:Connect(function() Part_Icles:EnableEmit(swordSpark)end):EnableEmit reads the attributes and produces one initial burst, then continuous emission for 0.15 seconds. The Beam’s animated graphs play over each emit’s lifetime, the sword’s swing animation plays, and the sparks naturally trail along because the Beam’s attachments are inside the sword model.
If you wanted a single spark per swing instead of a stream, switch to :Emit — it ignores EmitCount / EmitDuration entirely and fires one burst:
sword.OnSwing:Connect(function() Part_Icles:Emit(swordSpark)end):Emit produces one burst and stops there.
Pattern 2: Fireball — clone from ReplicatedStorage with timed burst
Section titled “Pattern 2: Fireball — clone from ReplicatedStorage with timed burst”You have a fireball effect authored in ReplicatedStorage. It’s a Model containing a textured sphere, a Beam tail, and a PointLight — all transformed children, ready to emit together as a nested composite particle.
When the player casts a fireball spell, you clone the model, position it at the spell’s origin, trigger emission, and clean up after.
If the fireball uses textures the player hasn’t seen before in this session, also call :Preload on the template once at game start so the first cast doesn’t stutter waiting for asset bytes.
local Part_Icles = require(game.ReplicatedStorage:WaitForChild("Part_Icles"))Part_Icles:Activate()
local fireballTemplate = game.ReplicatedStorage.FireballVFX -- Model with transformed children
local function castFireball(originPosition) local fireball = fireballTemplate:Clone() fireball:PivotTo(CFrame.new(originPosition)) fireball.Parent = workspace.Effects -- a Folder for transient effects
Part_Icles:AbsoluteEmit(fireball)
-- Clean up after the longest-lived emission finishes task.delay(3, function() fireball:Destroy() end)end
-- Trigger from your spell logicspellCast.OnFireball:Connect(castFireball):AbsoluteEmit walks the cloned fireball Model, finds every transformed child (sphere, beam, light), and triggers their emission together. Each child uses its own authored EmitCount / EmitDuration attributes — the ones set on it in Studio when you tuned the effect. The parent Model has no role beyond grouping; :AbsoluteEmit does not propagate attributes from the container down. So tune timings per-child at authoring time, then trigger the whole rig with one call.
The cleanup task.delay(3) is a safety net. Pick the duration based on the longest-lived child’s EmitDuration plus its particles’ Lifetime — three seconds is comfortably past most authored effects.
If you’d rather the fireball stay alive until your spell logic decides it’s done — say, a guided fireball that follows the cursor for a variable duration — keep a reference and disable it explicitly:
local fireball = fireballTemplate:Clone()fireball.Parent = workspace.EffectsPart_Icles:AbsoluteEmit(fireball)
-- Later, when the spell ends:for _, item in fireball:GetDescendants() do if item:GetAttribute("Transformed") then Part_Icles:Disable(item) endendtask.wait(2) -- let in-flight particles finishfireball:Destroy()Pattern 3: On-screen-only emission for performance
Section titled “Pattern 3: On-screen-only emission for performance”Some effects are expensive enough that you only want them to run when the player can see them. A passive “magic aura” that emits constantly on every NPC in the world adds up fast — twenty NPCs × 30 particles per second × across all clients quickly approaches the engine’s particle budget.
Solution: gate emission on a distance check or screen-visibility check, polled per NPC at a low frequency.
local Part_Icles = require(game.ReplicatedStorage:WaitForChild("Part_Icles"))Part_Icles:Activate()
local camera = workspace.CurrentCameralocal emissionDistance = 80 -- studslocal pollInterval = 0.25
local function trackNPC(npc) local emitter = npc:FindFirstChild("AuraEmitter") -- transformed Part-Icle if not emitter then return end
local emitting = false while npc.Parent do local distance = (camera.CFrame.Position - npc.HumanoidRootPart.Position).Magnitude local shouldEmit = distance < emissionDistance
if shouldEmit and not emitting then Part_Icles:EnableEmit(emitter) emitting = true elseif not shouldEmit and emitting then Part_Icles:Disable(emitter) emitting = false end
task.wait(pollInterval) end
-- NPC despawned; ensure emitter is off if emitting then Part_Icles:Disable(emitter) endend
-- Spawn-trackingfor _, npc in workspace.NPCs:GetChildren() do task.spawn(trackNPC, npc)endworkspace.NPCs.ChildAdded:Connect(function(npc) task.spawn(trackNPC, npc)end)The poll interval of 0.25 seconds is a balance — too frequent and the gating itself becomes the cost; too infrequent and emission lags noticeably behind the camera moving. For most cases, 0.25 seconds is invisible to the player and cheap enough.
For more sophisticated culling (frustum check rather than distance), use Camera:WorldToViewportPoint:
local viewportPoint, onScreen = camera:WorldToViewportPoint(npc.HumanoidRootPart.Position)local shouldEmit = onScreen and viewportPoint.Z > 0 -- Z > 0 means in front of cameraThis catches the case where an NPC is near the camera but behind it (a 360° aura visible from afar wouldn’t normally be culled by simple distance).
Pattern 4: Recursive :AbsoluteEmit on a complex VFX rig
Section titled “Pattern 4: Recursive :AbsoluteEmit on a complex VFX rig”For elaborate effects — say, an environment-shaking explosion with multiple emitter components — a single :AbsoluteEmit on the rig’s root saves you from threading individual triggers.
local Part_Icles = require(game.ReplicatedStorage:WaitForChild("Part_Icles"))Part_Icles:Activate()
local explosionRig = game.ReplicatedStorage.ExplosionVFX -- Folder
-- Folder contents:-- ExplosionVFX/-- CoreFlash (transformed Part — bright flash)-- Shockwave (transformed Beam — outward ring)-- Debris (transformed Part — scattered chunks)-- Smoke (transformed Part — lingering cloud)-- Light (transformed PointLight — illumination)-- ScreenColor (transformed ColorCorrection — brief tint)-- ScreenBlur (transformed Blur — concussion blur)
local function triggerExplosion(position) local effect = explosionRig:Clone() effect:PivotTo(CFrame.new(position)) effect.Parent = workspace.Effects
Part_Icles:AbsoluteEmit(effect)
task.delay(5, function() effect:Destroy() end)end
-- Hook into your explosion eventexplosionEvent.Triggered:Connect(triggerExplosion)One call. Every emitter in the rig triggers according to its own attributes. The flash is short, the shockwave expands, the debris scatters, the smoke lingers, the light pulses, the screen-tint flares, the blur peaks and fades — all coordinated by their authored timings, all triggered by one script call.
This is the same pattern the plugin’s Emit Code button generates by default. Selecting a multi-component VFX rig in Studio and clicking Emit Code produces a script that’s structurally identical to the above (with paths filled in for your specific selection).
Common pitfalls
Section titled “Common pitfalls”A few things to watch for.
Calling emit methods before :Activate(). The methods don’t error — they just don’t animate. If your particles spawn but sit motionless, check that :Activate() was called once at game start. Detail: Lifecycle.
Setting attributes after :EnableEmit is already running. Attributes are read at the moment of the :EnableEmit call. Changing them mid-cycle won’t affect the in-flight emission. Set them, then call.
Forgetting cleanup on cloned effects. A cloned effect parented to workspace lives forever unless you destroy it. Use task.delay (after the longest emission lifetime) or a cleanup hook on a parent destruction signal.
Emitting from the server when clients should handle it. Particles emitted on the server replicate to all clients, multiplying the rendering cost. For most VFX, emit on the client — each client renders only its own particles, the network cost is just the trigger event. Server-side emission is right when the effect needs to be authoritative (a damage-flash that only the player taking damage should see, for instance).
Native ParticleEmitter inside a transformed parent. When :AbsoluteEmit walks the hierarchy, it triggers transformed items via :EnableEmit, native ParticleEmitter instances via :Emit(EmitCount) plus optional Enabled toggle for EmitDuration, and Trail instances via parsed-duration Enabled toggling (transformed Trails included, since the runtime treats them the same as native Trails). Defaults: EmitCount falls back to 1 if absent, EmitDuration to 0 (no continuous loop). Set EmitDuration on the PE if you want a continuous run after the burst.
What’s next
Section titled “What’s next”That’s the end of the Walkthrough. The runtime API and four worked patterns close out the script side of the plugin. From here, the remaining sections are reference material: the Property Reference for a flat A-to-Z lookup of every property, Setup for installation and authentication, FAQ & Troubleshooting for common issues, and the Changelog for version history.