Particle systems, pooling and classes

Righty, everyone must have tinkered with this at some point, so I’m interested in different ways people have done particle effects in their games.

The very basic structure I was thinking of was a Particle class for each one, a ParticleSystem for a single effect (basically an emmiter + a collection of particles) and a global ParticleManager to organise all the systems. Structure shamlessly ripped from a Gamasutra article from ages ago. ;D

  1. Object pooling. Obviously we can’t go creating new particle objects contantly, or the GC would kill our performance and our first born. An initial idea would be to hold a single big pool in the manager, and dish them out to systems as they requested them. But since each effect is likely to just use a static amount of particles anyway, why not just just let each system allocate its own particles and pool the systems? Anyone any suggestions which may be a better idea?

  2. Parallel arrays vs. Objects. The OO way is obviously with a Particle object for each on screen particle, yet with high numbers allocated this may be GC and pool unfriendly. How about parallel arrays in each system for the required properties? This would imply system pooling rather than particle pooling. The downside being that we can’t just create a new Particle subclass for new behaviour, and probably a whole load of duplicate code if we have multiple particle system classes.

  3. Emmiters vs. complex systems. Should a particle system control emmision rate & properties (implying multiple ParticleSystem classes) or perhaps a single ParticleSystem class and allow different emmiters to be plugged into it?

  4. Single generic Particle class vs. Particle interface + several implementations. Things like dust, fire, smoke all need different behaviour, which is easiest to add with different particle classes. Or a generic particle class (essencially a no-code struct) with different controller classes to alter movement behaviour. Problems: becomes awkward when new controller behaviour needs extra data stored in particle object. Or with the other method, multiple particle subclasses makes pooling more tricky.

Ideas?

Oh just code it and stop blithering yer fool.

AF used pools, Super Elvis just uses new and lets the GC take care of it. It GCs here and there but not so you’d notice. AF almost never glitches once it’s loaded but really it wasn’t worth the effort for a 2-week game like Super Elvis.

AF uses all sorts of clever interfaces and emitters and particle classes for doing points, shadowed particles, and sprite particles, and smoke emitting dots, etc. Super Elvis has one Emitter class and one Particle class with a lot of parameters.

Cas :slight_smile:

Um, I don’t think so… unless you intend to treat each particle as a uniquely identifiable object that you operate on as individuals? (which IIRC would be unusual for a particle system?). Otherwise, that is not the “OO way”, but is symptomatic of a misunderstanding many people have about what OO is all about (IMHO because it’s tricky to understand, got taught originally by bad teachers, and then large numbers of people who didn’t understand but thought they did tried to explain it in simple terms, and now everyone’s confused ;). Took me - literally - years to meet a good teacher who also fully understood it and could explain it to me properly).

The OO way would be to identify the thing which has:

  • data
  • methods which only operate on that data.

(which would suggest to me you only want to work with groups of particles, rather than individuals)

To my mind, this is reinforced by the fact that you tend to emasculate OO if you ever knowingly attempt to assign objects in a way that will be hard to maintain (e.g. if it crosses boundaries that you just know you’ll need to split apart, or does NOT cross boundaries that you know you’ll NEVER need to split apart).

AFAICS this implies that each “set” of particles should be an object; if you intend all articles from an emitter to have one behaviour (which is sensible) then you would define your set as “everything from a particular emitter”. However, it would make sense to slightly decouple this and add the rider “…created in a particular timeframe” so that you could do runtime alteration of the emitter, perhaps change it’s sparks from blue to red - i.e. you would have all it’s emitted particles in one set, and then call a method “nextSet()” or simliar on the emitter that would cause it to switch to using a fresh set (i.e. because you want to treat the new particles differently without affecting the old).

FYI this is related to mobs in survivor - we do everything at the mob level, and monsters are just raw basic data, to the extent that many things you might expect us to store on a monster (like the particular skin, or 3D model) we don’t - you have to query their containing mob object instead. Although they do have full objects backing them this is mostly because Xith needs a 3D object for each to put in its scenegraph, and partly because java has no structs - so it’s a PITA to store small numbers of monsters (only a hundred or so, max) in custom struct-like data structures, instead of just being lazy and using objects :slight_smile:

I agree with Cas, if objects are small enough (just the case of particle entities) CG and contextual creations is not so bad.

We are using this direct technique on MK1 and without any apparent glitch even on low end PC (like 800Mhz or less).

Imagine that more or less the only things being created by your game are particles, emitters, and the odd alien. Think how much RAM a particle takes up - maybe 128 bytes. Then think how big the available heap space is in the VM and work out how many particles can get created before you run out and a GC needs to come along. It’s a lot! And then remember you could turn on concurrent incremental collection and they’d get cleared up continually whilst you’re waiting for vertical refreshes.

Cas :slight_smile: