# llLinkParticleSystem

*LSL function*

```lsl
void llLinkParticleSystem(integer link, list rules);
```

- `integer link`: Link number (1 for root, >1 for children) or a LINK_* flag.
- `list rules`: A list of particle system rules and data pairs [rule1, data1, ...], or a ParticleParams dictionary.

- Energy: 10

These functions are almost entirely identical.

The big difference is that [llParticleSystem](/functions/llParticleSystem/) acts upon the prim the script is in, [llLinkParticleSystem](/functions/llLinkParticleSystem/) on the other hand can act upon any prim in the object.

A particle system defined by a list of **rules** is set for the prim(s) **link**.

```lsl title="How to use" frame="terminal"
llLinkParticleSystem(0, []);
```

## Specification

Constant group [ParticleParam](/constants/groups/ParticleParam/):

```lsl
PSYS_PART_BLEND_FUNC_DEST = 25
PSYS_PART_BLEND_FUNC_SOURCE = 24
PSYS_PART_END_ALPHA = 4
PSYS_PART_END_COLOR = 3
PSYS_PART_END_GLOW = 27
PSYS_PART_END_SCALE = 6
PSYS_PART_FLAGS = 0
PSYS_PART_MAX_AGE = 7
PSYS_PART_START_ALPHA = 2
PSYS_PART_START_COLOR = 1
PSYS_PART_START_GLOW = 26
PSYS_PART_START_SCALE = 5
PSYS_SRC_ACCEL = 8
PSYS_SRC_ANGLE_BEGIN = 22
PSYS_SRC_ANGLE_END = 23
PSYS_SRC_BURST_PART_COUNT = 15
PSYS_SRC_BURST_RADIUS = 16
PSYS_SRC_BURST_RATE = 13
PSYS_SRC_BURST_SPEED_MAX = 18
PSYS_SRC_BURST_SPEED_MIN = 17
PSYS_SRC_INNERANGLE = 10
PSYS_SRC_MAX_AGE = 19
PSYS_SRC_OMEGA = 21
PSYS_SRC_OUTERANGLE = 11
PSYS_SRC_PATTERN = 9
PSYS_SRC_TARGET_KEY = 20
PSYS_SRC_TEXTURE = 12
```

Defines a particle system that sets the state of the [particle emitter](https://wiki.secondlife.com/wiki/particle_emitter) within the [prim](https://wiki.secondlife.com/wiki/primitive) that contains the [script](https://wiki.secondlife.com/wiki/Script). Any other scripts, in the same prim, that call this function will modify the state of the same particle emitter. As such, the particle system defined by this function is a [prim property](https://wiki.secondlife.com/wiki/primitive_property), just like its size, shape, color, etc.

Each prim has only **one (1)** particle emitter, located at its [geometric center](https://wiki.secondlife.com/wiki/geometric_center), and aligned along the prim's [local](https://wiki.secondlife.com/wiki/Viewer_coordinate_frames#local) Z-axis, pointing in the positive Z direction.

This is the one of the only [functions](/categories/particles/) which alters the state of the prim's particle emitter; thus, if you wish to change the emitter to a different state (i.e., emitting a different particle system entirely, or shut off the emitter completely), just call the function with the parameters of the new particle system you wish to render instead. Specifying an empty list (i.e., `llParticleSystem([])`; ) turns the emitter off.

Particles are essentially 2D [sprites](https://en.wikipedia.org/wiki/Sprite_%28computer_graphics%29) and are always rendered facing the viewer's camera (except when [PSYS_PART_RIBBON_MASK](/constants/PSYS_PART_RIBBON_MASK/) is enabled).

The rule / data values are defined below.

## Shared wiki article

This page transcludes [LlParticleSystem](/functions/llParticleSystem/). The following text is from that archived revision.

## Caveats

- When using particle systems that have a non-zero emitter age ([PSYS_SRC_MAX_AGE](/constants/PSYS_SRC_MAX_AGE/)) setting, you may notice that the particle system may restart without any scripted trigger going off. This is due to a bug which causes the emitter to "reset" when any of the prim properties are updated or otherwise sent to the viewer. As a result, you may have to use a [timer](/events/timer/) or a forced [sleep](/functions/llSleep/) and then clear the particle system once the age has expired. Debbie Trilling has posted a work-around here: https://forums-archive.secondlife.com/54/fa/260031/1.html#post1996465
- The spin defined by [PSYS_SRC_OMEGA](/constants/PSYS_SRC_OMEGA/) is relative to the [region](https://wiki.secondlife.com/wiki/Viewer_coordinate_frames#region) coordinate system, NOT the prim's [local](https://wiki.secondlife.com/wiki/Viewer_coordinate_frames#local) coordinate system.
- New non-zero vector values for [PSYS_SRC_OMEGA](/constants/PSYS_SRC_OMEGA/) will not re-align the emitter with the prim before they take effect. The viewer will continue rotating the emitter with the new omega values, starting from the last known orientation of the emitter. The emitter's current orientation is determined by the viewer, not the simulator, and two people looking at the same effect may see different results. To re-align the emitter with the prim, create an effect with [PSYS_SRC_OMEGA](/constants/PSYS_SRC_OMEGA/) set to [ZERO_VECTOR](/constants/ZERO_VECTOR/) long enough for the viewer to have a chance to render it.
- Particles moving towards a humanoid avatar, specified by [PSYS_SRC_TARGET_KEY](/constants/PSYS_SRC_TARGET_KEY/) rule and setting the [PSYS_PART_TARGET_POS_MASK](/constants/PSYS_PART_TARGET_POS_MASK/) flag, will end up at the geometric center of the avatar's bounding box which, unfortunately, make them appear to be striking the person in the groin area. If you want them to end up at another point on a target avatar, you instead have to place a target prim that is moved to the position where you wish them to end up, and use the key of that prim for the value of the [PSYS_SRC_TARGET_KEY](/constants/PSYS_SRC_TARGET_KEY/) rule.
- The Second Life viewer uses optimizations in culling objects which are too small to see at certain distances. If your emitter is very small, and is culled due to distance, the particle system associated with it will not be rendered either.
- Particles will also be culled beyond a maximum distance depending on their own scale. If particles are desired to be visible from further away yet be visually smaller, a larger scale and a texture with empty padding space are needed. If using [PSYS_PART_RIBBON_MASK](/constants/PSYS_PART_RIBBON_MASK/), make sure the Y scale is set properly, as it is used for this calculation even the rendering of the ribbon particles themselves ignores it.
- When [PSYS_PART_FOLLOW_VELOCITY_MASK](/constants/PSYS_PART_FOLLOW_VELOCITY_MASK/) is enabled, particles with zero velocity (e.g. generated by the DROP pattern, without acceleration, wind or target position following) are not rendered at all. Particles following their source via [PSYS_PART_FOLLOW_SRC_MASK](/constants/PSYS_PART_FOLLOW_SRC_MASK/) does not count as having a velocity, even if the source is moving.

## Examples

<details open>
<summary>Example 1</summary>

- [Example Particle Script](https://wiki.secondlife.com/wiki/Example_Particle_Script)
- [Neurocam Particle Engine](https://wiki.secondlife.com/wiki/Neurocam_Particle_Engine)

This example produces an effusion of glowing red spheres:

```lsl
llParticleSystem( [
        PSYS_PART_FLAGS,       PSYS_PART_WIND_MASK | PSYS_PART_EMISSIVE_MASK,
        PSYS_SRC_PATTERN,      PSYS_SRC_PATTERN_EXPLODE,
        PSYS_PART_START_COLOR, <1.0, 0.0, 0.0>
    ] );
```

</details>

## Helper functions

**Useful functions for storing/retrieving color and alpha values to/from integers:**

```lsl
integer ColorAlphatoRGBA(vector color, float alpha) {
    return (((integer)(alpha   * 255.0) & 0xFF) << 24) |
           (((integer)(color.x * 255.0) & 0xFF) << 16) |
           (((integer)(color.y * 255.0) & 0xFF) <<  8) |
            ((integer)(color.z * 255.0) & 0xFF);
}

vector RGBAtoColor(integer rgba) {
    return < ((rgba >> 16) & 0xFF) / 255.0, ((rgba >> 8) & 0xFF) / 255.0, (rgba & 0xFF) / 255.0 >;
}

float RGBAtoAlpha(integer rgba) {
    return ((rgba >> 24) & 0xFF) / 255.0;
}
```

## Notes

### Other Notes

- The default particle count for the client is normally set at 4096. That is the max particle count the client will render for ALL active particle systems within view range. Good particle system design is key to avoid "spamming" everyone with your particles, and starving out other people's particle systems. As such, if you are experiencing trouble getting your particle emitter to emit as many particles as you like, it may be the victim of particle starvation. Client/viewer lag (low frame rates) can also cause this issue, as particles are a rather low priority for rendering. The best solution for this is to move to a less laggy environment relatively free of other particle systems when designing and testing your own.
- Once particles are emitted, their direction of motion can only be affected by [PSYS_SRC_ACCEL](/constants/PSYS_SRC_ACCEL/), the [PSYS_PART_TARGET_POS_MASK](/constants/PSYS_PART_TARGET_POS_MASK/) flag, or the [PSYS_PART_FOLLOW_SRC_MASK](/constants/PSYS_PART_FOLLOW_SRC_MASK/) flag. As such, there is no good way to create the "swirling vortex" effect (like the one used in the viewer to indicate an object talking, begin derezzed, or when an avatar leaves the sim/grid). The effect can be created with a moving particle source (E.G. An orbiting script.)
- Although the declared particle sizes are always in multiples of 0.03125 meters, [PSYS_PART_INTERP_SCALE_MASK](/constants/PSYS_PART_INTERP_SCALE_MASK/) allows smooth transitions between the start and end values. This also applies to a size of [ZERO_VECTOR](/constants/ZERO_VECTOR/), e.g. scaling a particle from or to nothing.
- [https://wiki.secondlife.com/wiki/User:Talia_Tokugawa/concept/CrazyParticle Something Talia realised that blew her mind](https://wiki.secondlife.com/wiki/https://wiki.secondlife.com/wiki/User:Talia_Tokugawa/concept/CrazyParticle_Something_Talia_realised_that_blew_her_mind), Documenting experiments with particles, including tutorial of how to do video particles, and how to (disputably) massively exceed the 8192 Limit in terms of how many particles SL can render at one time. (Whilst rendering video on particles is not new just (until now) undocumented, I am fairly confident in saying the method to exceed the particle limit is new.)

## History

- Date of release [llParticleSystem](/functions/llParticleSystem/) [21-02-2007](https://wiki.secondlife.com/wiki/Release_Notes/Second_Life_Release/1.13#release-notes-for-second-life-1-13-4-281-29-february-21-2c-2007) or [14-03-2007](https://wiki.secondlife.com/wiki/Release_Notes/Second_Life_Release/1.14)
- Date of release `llLinkParticleSystem`[29-03-2010](https://wiki.secondlife.com/wiki/Release_Notes/Second_Life_Server/1.38#new-features)

## Known issues

From the issue templates included by the wiki article:

- SVC-1640 (nf): Particle Glow Parameters for llParticleSystem
- SVC-4897 (nf): **llSetSyncTime**() - a function for synchronising client side effects
- SVC-185 (bug): llParticleSystem (and others) anal about types

## Related functions

The original wiki page documents these functions together with this one:

- [llParticleSystem](/functions/llParticleSystem/)

---

*Source: [LlParticleSystem](https://wiki.secondlife.com/wiki/LlParticleSystem#llLinkParticleSystem) on the Second Life Wiki. Content from the Second Life Wiki articles LlParticleSystem (revision 1216482, 2024-04-14), Template:LSL Function/link (revision 1216622, 2024-05-04), Template:Issues/SVC-1640 (revision 1168182, 2012-06-01), Template:Issues/SVC-4897 (revision 1050552, 2010-10-02), Template:Issues/SVC-185 (revision 1166529, 2012-04-30) and Template:LSL Function/ParticleSystem (revision 1215395, 2023-11-05), CC BY-SA 3.0.*

---

From lsl.dev: https://lsl.dev/functions/llLinkParticleSystem/
