Skip to content

Utilities

The bulk-edit tools (Resize, Retime, Hue, Clipboard, Shifter) all share the pattern of “select something, modify its properties.” The four utility tools here do something different — they help you find emitters, package the plugin runtime, generate code for game scripts, and watch performance load. Properties don’t change; the tools instead surface information or produce artefacts.

This chapter covers all four together since each is small.

Scan walks every place in the workspace and finds Part-Icles emitters. It’s a diagnostic, not a modifier — useful for cataloguing the emitters in a complex scene and for surfacing any with format issues.

Click the Scan All button in the QMenu, and the plugin:

  1. Walks workspace, ServerStorage, and ReplicatedStorage recursively.
  2. For each instance, checks for evidence of being a Part-Icles emitter — either the Transformed attribute (current format), or a child named Factors / BakedFactors (older formats).
  3. Categorises matches into two buckets — Fix (current format with cosmetic issues that can be patched) and Migrate (older format that needs structural conversion).
  4. Displays a banner at the top of the panel summarising the counts.

Older versions of the plugin stored emitter properties using slightly different conventions (different attribute names, different child structures). When you load a place authored in an old plugin version into a newer one, those emitters still work, but they’re flagged for Migrate — the plugin can convert them to the current format.

The current-format emitters that have small issues — outdated attribute defaults, missing child folders that newer code expects — are flagged for Fix. The plugin can patch them in place.

The Scan banner shows two counts and three buttons:

  • Fix N — applies the cosmetic patches to the N flagged items.
  • Migrate N — runs the structural conversion on the N flagged items.
  • Dismiss — clears the banner without acting.

Run Scan after:

  • Loading a place authored under an older plugin version, to surface anything that needs migration.
  • Doing significant restructuring of your scene’s emitters, to confirm the plugin still recognises everything.
  • Before publishing a place, as a sanity check.

For most active development, the Scan banner doesn’t show anything to fix. It’s most useful as a “before publishing” or “after upgrade” pass.

Insert is the tool that gives your game scripts something to require. The Part-Icles plugin maintains a runtime module internally; Insert copies that module into your workspace as a Part_Icles instance, ready to be used by game code.

Click Insert Module in the QMenu:

  1. The plugin destroys any existing workspace.Part_Icles (so you can re-insert to refresh).
  2. It clones its internal runtime module.
  3. It names the clone Part_Icles and parents it under workspace.
  4. It selects the new module so you can see it in Studio’s Explorer.
  5. It creates a Studio change-history waypoint named “Part-Icles: InsertScript” (so the action is undoable).

The result is a ModuleScript (or a Folder containing one, depending on version) at workspace.Part_Icles. Your scripts can require it:

local Part_Icles = require(workspace:WaitForChild("Part_Icles"))
Part_Icles:Activate()

The other path that produces a runtime module is the Emit Code tool (further down this chapter). Opening the Emit Code panel for the first time clones a fresh Part_Icles into ReplicatedStorage — that’s the convention the snippets it generates require from. Insert is a separate flow, dropping the module into workspace specifically, intended for cases where:

  • You want the module shipped with a specific level/scene’s hierarchy.
  • You’re packaging a stand-alone VFX kit and want everything in one folder for clarity.
  • You need to override the ReplicatedStorage copy with a specific older or modified version.

For most game scripting, the ReplicatedStorage.Part_Icles you get from opening Emit Code is what you want. Insert is for explicit packaging cases.

Each plugin update may include changes to the runtime module. Existing Part_Icles copies in either ReplicatedStorage or workspace get refreshed automatically when you reopen Studio with a newer plugin version — so you usually don’t need to re-Insert just for plugin updates. But if you’ve intentionally kept a stale workspace copy and want to bring it up to date, clicking Insert Module again destroys the old copy and clones the current runtime in its place.

Emit Code generates a Lua snippet that triggers the selected emitters when pasted into a game script. Click the button on a selection of emitters and the plugin produces the snippet — a require statement, an :Activate() call, and a :AbsoluteEmit() call for each selected item.

Open the Emit Code panel with one or more emitters selected. The panel shows:

  • A multiline read-only TextBox containing the generated Lua snippet.
  • A Copy button — copies the snippet to your clipboard for pasting into Studio’s Script editor.
  • A Run button — executes the snippet immediately, triggering the emission for testing without leaving the panel.

For a single selected emitter at workspace.Sword.SparkBeam:

local Part_Icles = require(game.ReplicatedStorage:WaitForChild("Part_Icles"))
Part_Icles:Activate()
local VFX = workspace.Sword.SparkBeam
Part_Icles:AbsoluteEmit(VFX)

For multiple selected emitters:

local Part_Icles = require(game.ReplicatedStorage:WaitForChild("Part_Icles"))
Part_Icles:Activate()
local VFX = {
workspace.Effect1,
workspace.Effect2,
workspace.Effect3,
}
for _, item in VFX do
Part_Icles:AbsoluteEmit(item)
end

The path strings are computed from each instance’s hierarchy — the plugin walks parent chains and emits the dotted path. Items in ReplicatedStorage come out as game.ReplicatedStorage.MyEffect, items in workspace come out as workspace.MyEffect (Workspace is rewritten to lowercase workspace for the global shorthand), and other services follow game.<Service>.<Path>. Names that aren’t valid Lua identifiers use bracket notation (workspace["Effect with spaces"]).

If your selection includes both a parent and its descendants (a Folder plus emitters inside it), the snippet only includes the parent — :AbsoluteEmit recursively walks descendants, so emitting the parent already triggers the children. The plugin filters out any selected item whose ancestor is also selected, to keep the generated snippet clean.

The Run button executes the snippet right now, without you having to copy-paste. Useful for quick testing — adjust the emitter properties in the panel, click Run, see the result.

The Run button uses the same :AbsoluteEmit flow as the generated snippet, so what you see during Run is exactly what your published-game scripts will see.

  • You’ve authored a complex effect and want to write the code that triggers it. Emit Code gets you the boilerplate.
  • You’re testing whether an effect plays correctly when triggered — Run lets you trigger it without writing a script first.
  • You’re documenting an effect for another scripter — paste the snippet into your project’s notes.

A small badge anchored at the bottom-left of the plugin HUD. Reads Optimization: -- by default; once you select a transformed item (or items), it switches to a percentage from 0 to 100 with a colour for the band.

The indicator is a predictive score for the current selection — not a live frame-load reading. The plugin walks the selected items, reads each one’s Rate, Lifetime, EmitCount, EmitDuration, Enabled, TotalKeyFrames, plus shadow / transparency / flipbook flags, and computes the worst-case simultaneous-particle cost if those emitters all ran together. The result is normalized against an internal budget and shown as a percentage.

The colour bands:

  • Green (0 – 30%) — comfortably under budget. Most authoring lands here.
  • Yellow (31 – 60%) — getting expensive. A handful of these in one rig will compound.
  • Red (61 – 100%) — heavy. Expect frame-rate impact on lower-end hardware once this is actually emitting.

-- (muted gold) shows when nothing computable is selected — no transformed items and no native ParticleEmitters.

Idle items — emitters with EmitCount = 0, Enabled = false, and no EmitDuration set — register as 0 cost. Earlier plugin versions counted them as if they were active, which gave a false red warning on a scene full of stand-by emitters waiting for a script to fire them. As of v33, only emitters that can actually fire on their own contribute to the score.

Glance at it while authoring. If you tune a single emitter and the score climbs into yellow or red, that emitter alone won’t scale into a populated scene. Drop Rate, shorten Lifetime, lower EmitCount, simplify nested children, or move the effect to client-side emission to share the cost across clients rather than the server.

The score is selection-driven — it only updates when your selection changes. So you tune a property, re-select to refresh, watch the number move. The cheapest authoring loop is: tune → re-select → read → repeat.

The score is a worst-case predictive estimate based on authored properties, not a live measurement. It doesn’t profile actual rendering cost, texture-upload time, or shader complexity — just the simulation cost the plugin would incur if every selected emitter ran continuously at its authored Rate.

It also doesn’t know your players’ hardware. The cost model is calibrated against an internal reference budget tuned so a typical medium effect lands in the green band. A score of 30% on a workstation Studio session is still 30% on a budget device — reach for Roblox’s MicroProfiler when you want a real frame-cost reading on representative hardware.

The toggle in the QMenu’s Opt. Indicator button flips the indicator on and off, in case you want it hidden while focusing on visual authoring.

The first three (Scan, Insert, Emit Code) are in the QMenu — the plugin’s secondary tool menu, accessed via a button in the main panel. The QMenu houses plugin-wide actions (theme settings, motion preview, the inventory) — wherever an action doesn’t fit a per-emitter property or a bulk-edit tool, it lives here.

The Optimization Indicator is always-on in the HUD itself, bottom-left, no menu access needed.

You’ve now seen the entire Toolbench — nine tools (five bulk-edit + four utilities) that operate on a Studio selection. The next section, API Reference, covers the runtime API: how to require the plugin module from a game script and trigger emissions programmatically (:Emit, :EnableEmit, :Disable, :AbsoluteEmit, :EmitAnimate).