Beam
A Beam doesn’t fly through space. It connects Attachment0 to Attachment1 with a textured line and stays there. Two endpoints, one line — fixed geometry between them.
So what does “emit” mean for a Beam?
It means animating the look. Each emission produces a duplicate of the source Beam pinned to the same two attachments. The engine runs a set of property graphs over the duplicate’s lifetime — width swelling, texture scrolling, colour shifting — and destroys it when the time runs out. The geometry never moves. The texture, the width, the colour, the curve, the lighting all do.
This is different enough from Part that the property surface is also different. No Speed. No Acceleration. No Drag. No three-axis Size. Beams aren’t going anywhere; nothing about velocity or trajectory applies. Instead you get graphs for the visual qualities of the beam itself — and one feature unique to this type, the GraphBlender, which lets you author multiple Color and Transparency states across a single beam’s life.
What it transforms
Section titled “What it transforms”Any Roblox Beam instance — provided it has valid Attachment0 and Attachment1 set as endpoints. That’s a Roblox engine requirement: a Beam without two attachments doesn’t render. The plugin doesn’t add or override the attachments; it uses whatever you’ve already wired up before clicking Transform.
If the attachments are missing or detached after Transform, emitted duplicates will render invisibly. Check the source Beam’s Attachment0/Attachment1 first whenever a beam effect doesn’t appear.
Properties at a glance
Section titled “Properties at a glance”The full surface area, grouped by panel section. Beam shares far less with the workspace types than Part or Attachment did.
Spawning (Beam-specific subset)
Section titled “Spawning (Beam-specific subset)”| Panel label | Data attribute | Type | Default | What it does |
|---|---|---|---|---|
| Mode | EmissionMode | enum | Emit | Emit (duplicates) or Animate (in-place loop on the source) |
| Loop | AnimateLoop | boolean | false | Whether Animate mode loops the cycle |
| Enabled | Enabled | boolean | false | Master on/off |
| Rate | Rate | number | 10 | Beam-duplicates per second |
| Lifetime | BeamLifetime | NumberRange | 1 | Seconds each duplicate animates before the engine destroys it |
That’s it for Spawning. No SpreadAngle, no Direction, no Position ranges, no Pos. Mode, no Orientation — beams don’t have a spawn cone or a position to roll because the duplicates always pin to the same two attachments as the source.
Appearance (Beam-specific)
Section titled “Appearance (Beam-specific)”| Panel label | Data attribute | Type | Default | What it does |
|---|---|---|---|---|
| Texture | Texture | string (asset id) | from source | The texture image painted along the beam |
| Brightness | BeamBrightness | NumberSequence | 1 | Glow multiplier graph |
| Width0, Width1 | Width0, Width1 | two NumberSequence | 1 | Beam thickness at each endpoint, over life |
| LightEmission | LightEmission | NumberSequence | 0 | Self-illumination (additive blending) over life |
| LightInfluence | BeamLightInfluence | NumberSequence | 0 | How much scene lighting affects the beam, over life (Transform forces 0; see prose) |
Geometry (Beam-specific)
Section titled “Geometry (Beam-specific)”| Panel label | Data attribute | Type | Default | What it does |
|---|---|---|---|---|
| CurveSize0, CurveSize1 | CurveSize0, CurveSize1 | two NumberSequence | 0 | Bezier handle lengths for the curved beam path |
| Segments | Segments | NumberSequence | 10 | Tessellation count over life — more segments, smoother curve |
| TextureLength | TextureLength | NumberSequence | 1 | How far one texture tile covers along the beam |
| TextureSpeed | TextureSpeed | NumberSequence | 1 | Scroll rate for the texture along the beam |
| TextureMode | BeamTextureMode | enum | Stretch | How the texture fits the beam — Stretch, Wrap, Static |
| Z-Offset | ZOffset | number | 0 | Render-depth bias for layering |
| FaceCamera | FaceCamera | boolean | false | When on, the beam re-orients each frame to face the camera, like a billboard |
Flipbook (shared with Part — separate folder)
Section titled “Flipbook (shared with Part — separate folder)”| Panel label | Data attribute | Type | Default | What it does |
|---|---|---|---|---|
| Mode | BeamFlipbookMode | enum | OneShot | How frames play |
| Framerate | BeamFlipbookFramerate | NumberRange | 1, 1 | Frames per second |
| StartRandom | BeamFlipbookStartRandom | boolean | false | Random start frame per duplicate |
| Reverse | BeamFlipbookReverse | boolean | false | Plays backwards |
Advanced (Beam-specific subset)
Section titled “Advanced (Beam-specific subset)”| Panel label | Data attribute | Type | Default | What it does |
|---|---|---|---|---|
| Anim. Steps | TotalKeyFrames | number | 100 | Pre-sample resolution for the graphs |
| Emit Into | EmitParent | Instance | nil | Where the duplicates parent — overrides the default |
| PreloadTexture | PreloadTexture | boolean | false | Force-loads the texture before emission begins |
Blender (Beam-only)
Section titled “Blender (Beam-only)”An expandable UI section, not a property table. Each entry is a state — a Time plus a Color graph plus a Transparency graph. The + Add State button creates a new state; the state list shows all current states. Covered in detail in GraphBlender below.
Visual properties in detail
Section titled “Visual properties in detail”Texture
Section titled “Texture”The image painted along the beam’s length. A Roblox asset id (rbxassetid://...) or a Decal/Texture-style URL. Each duplicate inherits the source Beam’s Texture at the moment of emission — it’s a single value, not a graph.
To animate the texture’s appearance over life, reach for TextureSpeed (scroll), TextureLength (tile size), or the Flipbook system (cycle through multiple textures).
Brightness
Section titled “Brightness”A NumberSequence graph that multiplies the beam’s rendered brightness over its life. Same role as Part’s Brightness — values above 1 make the beam glow more brightly, values below 1 dim it.
The data attribute is named BeamBrightness rather than Brightness to avoid colliding with native Roblox Beam.Brightness. The plugin reads the panel value into BeamBrightness and applies it via the graph each frame.
Width — Width0, Width1
Section titled “Width — Width0, Width1”The beam’s thickness at each endpoint. Both are NumberSequence graphs, evaluated each frame at the duplicate’s current age.
A beam that swells mid-life uses a graph from 0 rising to 2 and falling back to 0. A beam that’s wide at one end and tapered at the other uses a constant Width0 = 2 and a constant Width1 = 0.2. A pulsing beam uses an oscillating graph.
The two ends are independent. The plugin doesn’t enforce equal widths — that’s a stylistic choice. For a uniform-width beam, set both graphs to the same value.
LightEmission
Section titled “LightEmission”A NumberSequence for self-illumination — how much of the beam renders with additive blending, ignoring scene lighting. 0 is normal blending; 1 is fully additive (the beam appears as if internally lit). Useful for laser, lightning, and energy effects where the beam should appear to be the light source.
LightInfluence
Section titled “LightInfluence”A NumberSequence for how much scene lighting affects the beam. 1 means full lighting integration (the beam dims in shadows); 0 means the beam ignores lighting entirely (always rendered at its base brightness, regardless of where it is).
The plugin’s Transform forces LightInfluence = 0 on every Beam by default, and the Fix tool re-applies that override. Reason: most beam effects (lasers, magic, energy) want the beam to look the same regardless of where in the scene it sits. Manual lighting integration produces shadowed beams that read as physical objects, which is rarely what a VFX artist wants. Set the graph back to 1 if you genuinely want lighting integration.
Geometry properties in detail
Section titled “Geometry properties in detail”CurveSize — CurveSize0, CurveSize1
Section titled “CurveSize — CurveSize0, CurveSize1”Two NumberSequence graphs that control the bezier curvature of the beam between its two endpoints. 0 is a straight line. Positive values make the beam bow outward in the direction of each attachment’s Up vector. The two values control curvature near each endpoint independently.
A wavy beam uses oscillating CurveSize graphs. An arc-shaped beam (rainbow, plasma arc) uses a constant CurveSize0 = CurveSize1 = 5. A straight laser uses 0 for both throughout life.
Segments
Section titled “Segments”A NumberSequence for how finely the beam is tessellated. More segments mean smoother curves at the cost of vertex count. The engine clamps the runtime value to a minimum of 20 segments — going below produces visible kinks.
For straight beams, lower values (10–20) work fine. For curved beams, push up to 40–80 depending on how tight the curve gets.
TextureLength
Section titled “TextureLength”How long, in studs, one tile of the texture covers along the beam. Smaller values pack more tiles; larger values stretch each tile. Combined with TextureSpeed it controls the apparent speed of the scroll.
A Texture of a single repeating pattern (a stripe, a chevron) with TextureLength = 1 produces tight tiling. The same texture with TextureLength = 5 looks five times as wide per tile.
TextureSpeed
Section titled “TextureSpeed”A NumberSequence for how fast the texture scrolls along the beam, in studs per second.
The plugin gives you frame-rate-independent scrolling: the beam scrolls at the right visual rate regardless of FPS, because the math is integrated over time, not stepped per frame. A 30-FPS player and a 144-FPS one see the same scroll speed.
A beam with TextureSpeed = 0 doesn’t scroll. With a constant 5 it scrolls at five studs per second along the beam’s length. With a graph that ramps from 0 up to 20, the beam starts still and accelerates into a fast scroll over its life — useful for charging or rev-up effects.
TextureMode
Section titled “TextureMode”How the texture fits the beam. An enum drawn from Roblox’s Enum.TextureMode: Stretch, Wrap, Static. The choice changes both how the texture lays across the beam and how TextureSpeed reads visually as the beam scrolls.
Stretch (default)
Section titled “Stretch (default)”The texture is scaled to fit the beam’s full length exactly once. TextureLength is ignored — there’s only one tile, and it’s always the whole beam.
Use cases:
- A textured beam where the design is meant to read as a single image — a magic sigil whose runes span the entire beam, a banner with a pattern that runs end-to-end.
- Beams whose length varies dramatically per emit. Stretch keeps the design recognisable regardless of length; Wrap would change how many tiles fit and could read inconsistently.
- Lightning bolts with a pre-authored shape. A texture painted as a single jagged silhouette stretches to fit each beam.
The texture repeats along the beam, with TextureLength controlling the tile size. Combined with TextureSpeed, this is the mode for moving visuals along the beam.
Use cases:
- Lasers and energy streams. A short repeating pattern (chevrons, bands of light, a shifting waveform) tiled along the beam reads as continuous flow when scrolled with
TextureSpeed. - Magical text or rune bands. Repeating glyphs that scroll along the beam — useful for incantation visuals, conduit lines, runic tethers.
- Pulsing cables. A darker-and-lighter repeating pattern with non-zero
TextureSpeedproduces visible pulses travelling along the beam — like a power conduit with electricity flowing through it. - Stripes / chevrons indicating direction. Diagonal stripes scrolling at high
TextureSpeedgive a strong directional cue (“flow that way”).
Static
Section titled “Static”The texture is anchored in world space, not to the beam itself. As the beam moves through the world, the texture coordinate appears to slide under the beam — the world stays fixed, the beam reveals different parts of the texture as it passes over them.
Use cases:
- Beams “passing through” a fixed pattern. A laser drawn over a stationary energy-field background that the beam appears to be revealing rather than carrying.
- Backdrops glimpsed only along the beam’s path. A swirling gradient anchored to the world; the beam acts as a window onto it.
- Showing-through effects. Anything that should read as the beam being transparent with a world-locked pattern visible underneath.
Most beam effects use either Wrap (for typical animated streams) or Stretch (for end-to-end designs). Static is the specialty pick — reach for it when the visual semantics is “the beam reveals what’s there” rather than “the beam carries the texture with it.”
FaceCamera
Section titled “FaceCamera”A toggle. Default is false. When on, the beam re-orients each frame so its surface faces the camera — the line itself stays between the two attachments, but the flat side of the textured ribbon turns to the viewer. When off (the default), the beam has a fixed orientation in world space; rotating the camera can reveal the beam edge-on, where it disappears.
For most beam effects, turn FaceCamera on. The default-off makes sense when you’re building 3D mesh-like structures where the orientation should be physical (a flat shield drawn with a Beam, say), but for typical beam effects (laser, lightning, magic stream) you almost always want it on.
Emit Into
Section titled “Emit Into”An Instance field — the parent for emitted duplicate beams. Defaults to the same folder the source Beam is in. Overriding it lets you collect beam particles in a separate container, the same way EmitParent works for Part.
PreloadTexture
Section titled “PreloadTexture”A toggle. When on, the plugin calls Roblox’s ContentProvider:PreloadAsync() on the Texture before emission begins, ensuring the asset is loaded before the first beam-particle appears. Useful when the first emission is part of a tight cinematic timing — without preload, the first few beams may render with no texture for a frame or two while the asset streams in.
For most use cases, leave it off. Roblox’s default streaming is usually fast enough.
GraphBlender
Section titled “GraphBlender”Color and Transparency work differently for Beam than for any other type. There’s no single Color graph or Transparency graph on a Beam. There’s a GraphBlender folder with one or more states, each defining a Color graph and a Transparency graph and the moment in life when that state is “active.” The engine interpolates between adjacent states linearly.
This exists because beams routinely need dramatic shifts in colour and opacity at specific moments in their life — a lightning strike that flares from blue to white to red, a laser that charges blue and discharges yellow, a fade-in that crossfades two distinct colour ramps. A single ColorSequence doesn’t capture that well; you’d need many fine-grained keypoints or a complicated shape. Multiple states is cleaner.
Structure
Section titled “Structure”When you transform a Beam, the plugin creates a GraphBlender folder as a child of the source Beam and seeds it with one state — a Configuration named 1, with Time = 0, the source Beam’s current Color and Transparency, and an internal _AutoTime flag set so subsequent + Add State clicks know to redistribute the times evenly. Out of the box, that single seeded state means the Beam reads exactly like a regular Color / Transparency Beam until you add more states.
Each state is a Configuration instance inside the GraphBlender folder, with three attributes:
Time— a number from0to1representing where in the particle’s life this state applies.0is birth,1is death.Color— aColorSequence, the colour graph for this state.Transparency— aNumberSequence, the transparency graph for this state.
The plugin sorts states by Time ascending at emission, regardless of how they’re named. State names default to 1, 2, 3 but the order that drives interpolation is the Time value.
Add State, in detail
Section titled “Add State, in detail”Clicking + Add State spreads the existing states’ Time values evenly across [0, 1]: a single state at 0 becomes [0, 1], then [0, 0.5, 1], then [0, 0.33, 0.66, 1], and so on. The redistribution only touches states whose Time was placed by Add State itself — if you’ve manually retimed a state (typed a number into its Time field), that custom value stays put across subsequent Add State clicks. Deleting a state renumbers the remaining state names sequentially so the panel always shows 1, 2, 3, ….
The Time field validates input. Values outside [0, 1], or values that collide with another state’s Time, flash red and revert to the previous valid number — there’s no way to silently end up with two states sharing the same Time or a state at Time = 1.5.
Interpolation
Section titled “Interpolation”Each frame, the engine evaluates the duplicate’s age t (a value from 0 to 1 — elapsed / Lifetime). It finds the two states whose Time values straddle t and produces a blended gradient somewhere between them, weighted by how close t is to each state. The blended gradient is then applied to the beam’s Color and Transparency for that frame. Same algorithm for both.
The interpolation is linear between adjacent states. With the typical authoring shape — a state at Time = 0 and another at Time = 1 (Add State produces this by default for two states) — every value of t in life falls inside the range, and there’s no out-of-range case to think about. If you author your states such that the first one’s Time is greater than 0, the rendered gradient for the early portion of life isn’t well-defined; keep at least one state at Time = 0. Likewise keep one state at Time = 1 so the death-frame gradient is what you authored. For a higher-level description of how the engine renders multi-state beams, see GraphBlender Math.
Edge cases
Section titled “Edge cases”- Zero states (empty
GraphBlenderfolder, or no folder at all) — only happens if a state is manually deleted or the folder is hand-edited; Transform always seeds at least one state. With zero states, the engine skips colour and transparency animation entirely. The Beam renders at its nativeColorandTransparency(the values you’d see on the source Beam in Studio’s property panel) and holds those values throughout each emission. - One state — no interpolation; the engine evaluates the single state’s graphs directly each frame. Behaves identically to a hypothetical “single-graph Color and Transparency” mode.
- Many states — full multi-state interpolation as described.
A worked example: a lightning strike
Section titled “A worked example: a lightning strike”You want a lightning bolt that:
- Spawns dim and blue.
- Flares to bright white at 30% of its life.
- Decays to dim red at 70%, then fully transparent at 100%.
That’s three states:
| State | Time | Color graph | Transparency graph |
|---|---|---|---|
| 1 | 0.0 | dim blue (#1a3a8a to #3a5aaa at age 0–1) | 0.6 constant |
| 2 | 0.3 | white-hot (#ffffff solid) | 0.0 constant |
| 3 | 1.0 | red-fading (#aa3a3a to #aa3a3a, both ends) | 0.5 rising to 1.0 |
At age 0.15 (between states 1 and 2), the beam shows an interpolation: roughly halfway from “dim blue 0.6 trans” to “bright white 0.0 trans.” At age 0.3, exactly state 2. At age 0.65 (between states 2 and 3), the beam shows roughly halfway from “white” to “fading red” with transparency rising from 0 toward 0.5. At age 1.0, the beam is dim red and almost gone.
This kind of multi-stage progression is what GraphBlender is for. A single ColorSequence would need a dozen keypoints to express the same shape and would be hard to author cleanly.
What’s per-state vs global
Section titled “What’s per-state vs global”GraphBlender’s state-driven model only covers Color and Transparency. Every other Beam graph (Width0, Width1, CurveSize0, CurveSize1, Segments, TextureSpeed, TextureLength, Brightness, LightEmission, LightInfluence) is global on the Beam — one graph for the whole life, evaluated at the duplicate’s current age each frame. If you want widths or brightness to follow the same shape as your states, you have to manually shape those graphs to match.
Worth knowing
Section titled “Worth knowing”A few Beam-specific gotchas.
Attachments must be valid. A Beam without Attachment0 and Attachment1 set, or with attachments that have been destroyed mid-life, renders invisibly. The plugin doesn’t validate this — it’s a Roblox engine constraint. If your Beam effect doesn’t appear, check the attachments before checking anything else.
Transform forces LightInfluence = 0. Both on the source and the Render Template. If you’ve authored a LightInfluence graph that ramps up to 1, the Beam will obey that graph during emission — but the idle state of the source Beam (when not emitting) is forced to 0. The Fix tool re-applies this override if you accidentally undo it. Set your LightInfluence graph by hand if you need lighting integration.
Beams don’t move. No Speed, Acceleration, Drag, RotSpeed. The geometry is locked to the two attachments. If you want a beam to move, animate the attachments themselves with TweenService or a script — that’s the Roblox-native way to animate beam endpoints.
BeamFlipbooks is a separate folder from MeshFlipbooks. Beams read numbered Decal children from BeamFlipbooks and emit each child’s .Texture field as a frame asset-id, swapping the Beam’s own Texture field per frame. Same instance type as MeshFlipbooks, separate folder so the per-type runtime path can find them without ambiguity. The shared chapter Mesh Flipbooks covers the Mode/Framerate/StartRandom/Reverse properties — those work the same way for both folders.
Attribute name disambiguation. Several Beam-graph properties use prefixed attribute names (BeamBrightness, BeamLightInfluence, BeamFlipbookMode, etc.) to avoid colliding with native Roblox Beam attributes of the same plain name. The panel labels are still the unprefixed versions; the prefix is internal.
What’s next
Section titled “What’s next”You’ve now seen two emission models: Part / Attachment particles fly through space; Beam particles animate the look of a fixed line. The next type is stranger still. Trail doesn’t even use the duplication model. The plugin animates the source Trail directly, in place, every frame — which means there’s no “emit” event, no per-particle randomisation, no RenderTemplate. One Trail, animated. Why would the plugin work that way for one type and not others?