Skip to content

Particle systems ​

The Particle System component emits a continuous stream of GPU points — fire, smoke, sparks, magic, dust, rain, explosions. Add it from Add Component → Particle System, tune it in the Inspector, or set it from a script or the AI with setComponent('particleSystem', { … }).

One-shot vs. continuous

This page is the component — a persistent emitter attached to an entity. For a fire-and-forget burst from a script (a hit spark, a pickup pop) with no component to author, use particles.burst() instead. It cleans itself up when the particles fade.

Every property below is optional except where noted — leave one out and it takes its default.

Emission ​

How many particles, how often, and for how long.

PropertyTypeDefaultWhat it does
maxParticlesnumber100Pool size (50–1000). The hard cap on particles alive at once. Edits apply live — raising it mid-play grows the pool.
emissionRatenumber10Particles spawned per second (continuous emission).
durationnumber0Seconds the system emits, then stops. 0 = emit forever.
startDelaynumber0Seconds to wait before the first particle.
loopingbooleanfalseRestart emission when duration elapses (loop the effect).
playOnAwakebooleantrue*Start emitting as soon as the entity spawns. Turn off to start paused and wake it from a script — getComponent('particleSystem').play() or .emit(n). The editor's edit-mode preview always plays so you can tune the effect.
bursts{ time, count }[]—Emit count particles all at once at elapsed time seconds — shockwaves, puffs. Combine with a low emissionRate or none.

* The default depends on how the component is created; set it explicitly when the timing matters.

Shape — where particles are born ​

PropertyTypeDefaultWhat it does
shape'point' | 'sphere' | 'cone' | 'box''point'The emission volume. cone throws particles in a direction; sphere/box fill a volume.
shapeRadiusnumber1Radius of the sphere/box/cone base.
shapeAnglenumber30Cone half-angle in degrees (only for shape: 'cone'). Steers the spray: 5 is a tight jet, 80 a wide fan.

Movement ​

Initial velocity plus the forces acting over each particle's life.

PropertyTypeDefaultWhat it does
speednumber5Initial outward speed.
speedVariationnumber0Randomness added to the initial speed, 0–1 (0 = every particle identical, 1 = wide spread).
gravitynumber-9.8Constant Y acceleration. Positive floats particles up (embers, bubbles).
velocityOverLifetime[x, y, z]—A constant force/wind added every frame — drift smoke sideways, curve sparks.
dampingnumber0Velocity drag, 0–1. Higher = particles slow to a stop (settling dust).
simulationSpace'local' | 'world''local'Simulation Space — what happens when the emitter entity moves. local: every particle (in flight too) rides along — a torch flame that follows the torch. world: emitted particles keep their world trajectory and only new spawns follow, leaving a trail behind a mover — rocket smoke, rain. No difference for emitters that never move.

Turbulence ​

Organic, swirling motion (smoke, fire, magic).

PropertyTypeDefaultWhat it does
noiseStrengthnumber0Turbulence intensity. 0 = off.
noiseFrequencynumber1Turbulence scale — higher = tighter, more chaotic swirls.

Size ​

PropertyTypeDefaultWhat it does
sizenumber0.2Base particle size.
startSizeMinnumbersizeLow end of a random per-particle size range.
startSizeMaxnumbersizeHigh end of the random size range. Set both to vary particle sizes.
sizeOverLifetimebooleanfalseShrink each particle to nothing as it dies.

Rotation ​

Rotation spins the sprite texture inside each particle, so it only shows when a textureAssetId is set (a rotated soft point looks the same at every angle).

PropertyTypeDefaultWhat it does
startRotationnumber0Initial rotation in degrees.
rotationOverLifetimenumber0Spin speed in degrees/second.

Lifetime ​

PropertyTypeDefaultWhat it does
lifetimenumber2Seconds each particle lives.
lifetimeMinnumberlifetimeLow end of a random per-particle lifetime range.
lifetimeMaxnumberlifetimeHigh end of the random lifetime range.

Colour & appearance ​

PropertyTypeDefaultWhat it does
colorhex string—Starting colour of each particle.
endColorhex string—Colour to fade toward over the particle's life (used when colorGradient is absent).
colorGradient{ t, color }[]—Multi-stop colour-over-lifetime (Color over Lifetime). Each stop is { t: 0–1, color: hex }. With 2+ stops it overrides the color → endColor fade.
opacityOverLifetime'none' | 'fadeOut' | 'fadeInOut''none'Alpha curve. fadeOut = dissolve as it dies; fadeInOut = ease in and out (soft smoke). none still applies a mild built-in fade (to half alpha at death) so hard pops are rare by default.
blending'normal' | 'additive''normal'additive makes overlapping particles glow — fire, magic, energy. normal for smoke/dust.

Rendering ​

PropertyTypeDefaultWhat it does
renderMode'billboard' | 'stretched''billboard'billboard always faces the camera; stretched streaks each particle along its velocity — sparks, rain, tracers.
stretchFactornumber1How far stretched particles elongate per unit of speed.
textureAssetIdstring—An imported texture asset drawn as every particle's sprite (leaves, snowflakes, smoke puffs — a PNG with transparency works best). Unset = the default soft points. Pick it in the Inspector's Renderer → Texture field or drag a texture in from the Project panel; color/gradient tints multiply on top.
flipbookTiles[cols, rows]—Texture-sheet animation: the sprite texture is a grid of tiles played as a flipbook over each particle's life (an explosion sheet, a smoke sequence). Needs textureAssetId.
flipbookFpsnumber0Flipbook speed in frames/second (loops). 0 = play the whole sheet exactly once over each particle's lifetime.
flipbookRandomStartbooleanfalseStart each particle at a random frame — varied puffs from one sheet.

Ground collision ​

PropertyTypeDefaultWhat it does
worldCollisionbooleanfalseBounce particles off the ground plane (Y = 0) instead of passing through.
bounceRestitutionnumber0.5Bounciness on collision, 0–1 (0 = stick, 1 = no energy lost). Only applies when worldCollision is on.

Sub-emitters ​

Spawn a burst of child particles when a particle dies — a rocket trail bursting into sparks, a firework shell exploding. World-space, one level deep (children don't sub-emit).

ts
subEmitters: [
  {
    count: 12,        // child particles per burst
    color: '#ffcc00', // child colour (default: parent's)
    sizeScale: 0.6,   // child size relative to parent
    speed: 4,         // child burst speed (default: parent's)
    lifetime: 0.5,    // child lifetime (default: half the parent's)
  },
]

Recipes ​

Campfire — additive, upward, flickering:

ts
setComponent('particleSystem', {
  shape: 'cone', shapeAngle: 12, emissionRate: 40,
  speed: 2, gravity: 1.5, lifetime: 1.2,
  size: 0.4, sizeOverLifetime: true,
  color: '#ffcc33', endColor: '#ff3300',
  blending: 'additive', opacityOverLifetime: 'fadeOut',
  noiseStrength: 0.8, noiseFrequency: 1.5,
})

Bouncing sparks — stretched, additive, collide with the ground:

ts
setComponent('particleSystem', {
  shape: 'point', emissionRate: 0, bursts: [{ time: 0, count: 30 }],
  speed: 8, speedVariation: 0.6, gravity: -18, lifetime: 1.5,
  size: 0.1, color: '#fff2a0', endColor: '#ff7700',
  renderMode: 'stretched', stretchFactor: 2, blending: 'additive',
  worldCollision: true, bounceRestitution: 0.5,
})

Firework — a shell that explodes into a coloured burst via a sub-emitter:

ts
setComponent('particleSystem', {
  shape: 'point', emissionRate: 0, bursts: [{ time: 0, count: 1 }],
  speed: 14, gravity: -6, lifetime: 1.4, size: 0.3, color: '#ffffff',
  subEmitters: [{ count: 60, color: '#66ccff', speed: 7, lifetime: 1.2, sizeScale: 0.5 }],
})

One-shot bursts ​

particles.burst() takes a shape option for how each particle looks. A burst always starts from its position, so this is the particle's outline, not where it is born.

ValueWhat it draws
'square' (default)Hard-edged square points.
'round'Soft round dots: solid in the middle, fading at the edge. Reads well with blending: 'normal' for dust, petals and sparks of colour.
ts
particles.burst([x, y + 1, z], {
  count: 16, color: '#ffd166', endColor: '#ef476f',
  size: 0.3, speed: 4, lifetime: 0.6, blending: 'normal', shape: 'round',
})

See also ​