Code of the Day
AdvancedVisual Effects

Particle systems

A particle system is an emitter that spawns, moves, ages, and culls short-lived visual elements — explosions, smoke, sparks, and rain all follow the same pattern.

Game DevAdvanced6 min read
By the end of this lesson you will be able to:
  • Describe a particle system in terms of emitter, particle pool, and update loop
  • Explain the role of velocity spread, lifetime, and colour in producing organic variation
  • Identify how object pooling avoids repeated allocation during gameplay

Explosions, smoke trails, sparkling collectibles, rain, and dust clouds are all different aesthetically, yet they are produced by the same underlying mechanism: a particle system. Once you understand the pattern, every visual effect of this type becomes a configuration exercise rather than a new engineering problem.

The three parts

A particle system has three logical parts.

The emitter is a point (or region) in the world that spawns new particles. It fires either in a burst (an explosion) or continuously (a smoke vent). The emitter stores the position to spawn from and the parameters that control what each particle looks like: speed range, angle spread, lifetime range, and colour palette.

The particle pool is the collection of currently alive particles. Each particle tracks at minimum:

  • pos — world position (a Vector2)
  • vel — velocity (a Vector2)
  • lifetime — seconds remaining before the particle is removed
  • colour or alpha — for fade-out or colour shifts over time

The update loop ticks every alive particle once per frame. It moves the particle (pos += vel * dt), ages it (lifetime -= dt), and removes it when lifetime <= 0.

Organic variation

A single explosion where all particles travel at the same speed in the same direction looks robotic. Variation makes it feel real:

  • Velocity spread — each particle gets a random direction within ±N degrees of the emission angle, and a random speed within a min/max range.
  • Size variation — draw particles as circles whose radius is randomly chosen at spawn (e.g. 2–5 px).
  • Lifetime variation — some particles die sooner than others, producing a natural trailing fade rather than all disappearing at once.
  • Gravity — add a small downward acceleration to pull sparks into arcs.

Object pooling

Spawning and discarding Python objects during gameplay invokes the garbage collector at unpredictable moments, which can cause frame-rate hitches. Object pooling sidesteps this by pre-allocating a fixed list of particle objects at startup. When a particle "dies", it is marked inactive rather than deleted. When the emitter needs a new particle, it finds an inactive slot and resets its fields.

For typical 2D games (spawning dozens of particles at a time, not thousands), the performance difference is small. For mobile targets or very dense effects, pooling becomes important. Start simple and add pooling if you measure a problem.

Python's dataclasses.dataclass is a clean way to define a particle: it auto-generates __init__ from the field annotations, and you can add a reset(pos, vel, lifetime) method for pool reuse.

Appropriate uses

EffectBurst or continuousKey variation
ExplosionBurstWide angle, gravity
SmokeContinuousSlow upward drift, alpha fade
SparksBurstHigh speed, gravity, short life
RainContinuousNarrow downward angle, long life
Magic trailContinuousColour shift (hot → cool)

Where to go next

Next: particle system in code — a complete pygame implementation of a burst emitter with random velocity spread and alpha fade-out.

Finished reading? Mark it complete to track your progress.

On this page