Impact

What is Entity Pooling?

Entity Pooling allows Impact to re-use Entities that have been killed in the game already, instead of creating completely new ones.

When Pooling is enabled for an Entity Type and an instance of that Entity is removed from the game world (through .kill()), this instance is put into a Pool. The Pool is essentially just an array, that collects these killed Entities.

Now, when you want to create a new Entity, Impact first looks into the Pool to see if there already is an Entity of the same Type available and ready for re-use. If an Entity is available in the Pool, some of the properties are reset and the Entity is removed from the Pool and put back into the game. If there's no Entity in the Pool, Impact constructs a new one, as usual.

Why Pooling?

Sometimes you have an Entity Type that has a short lifetime and is spawned and killed very rapidly. Some examples include all sorts of particles, projectiles from guns or even some types of enemies.

Creating and releasing an Entity can be a costly operation, especially on lower-end hardware. Each time an Entity is killed and not re-used, it becomes garbage and will eventually be collected by the JavaScript Engine's Garbage Collector. Garbage Collection takes time and can cause some intermittent pauses in your game, so you should try to create as little garbage as possible. Pooling helps with that.

Pooling only makes sense for Entities that are frequently created and removed again. For instance, enabling Pooling for your Player Entity probably wont make any difference at all, because there's only one instance around at all times, and Player death doesn't happen frequently (in most kinds of games anyway).

On the other hand, if you have a Bullet Hell Shooter, where hundreds of bullets are spawned and removed again, by all means use Pooling.

Using ig.EntityPool

Impact (since 1.23) comes with the easy to use ig.EntityPool. To enable Pooling, all you have to do is to require 'impact.entity-pool, add a .reset() method that is called when the entity is revived from the Pool and call ig.EntityPool.enableFor() for your Entity Class.

For instance, if you have a Bullet entity for which you want to enable Pooling, it would work like this:

ig.module(
	'game.entities.bullet'
)
.requires(
	'impact.entity',
	'impact.entity-pool'
)
.defines(function(){

EntityBullet = ig.Entity.extend({		
	animSheet: new ig.AnimationSheet( 'media/bullet.png', 8, 8 ),
	shootSound: new ig.Sound( 'media/sounds/bullet.*' ),
	
	// (...)
	
	init: function( x, y, settings ) {
		this.parent( x, y, settings );
		this.addAnim( 'idle', 1, [0,1,3] );
		
		this.shootSound.play();
	},
	
	reset: function( x, y, settings ) {
		// This function is called when an instance of this class is
		// resurrected from the entity pool.
		// The parent implementation of reset() will reset the .pos to 
		// the given x, y and will reset the .vel, .accel, .health and 
		// some other properties.
		this.parent( x, y, settings );
		
		// Play the shoot sound again. Remember, init() is never called 
		// when the entity is revived from the pool.
		this.shootSound.play();
	},
	
	// (...)
});

// Enable Pooling!
ig.EntityPool.enableFor( EntityBullet );

});

With Pooling enabled, you can just spawn your Entity like usual and Impact will figure out the rest. E.g.:

ig.game.spawnEntity(EntityBullet, x, y, settings);

You can even still use the normal constructor for your Entity (i.e. var bullet = new EntityBullet(x, y, settings)) if you need this for your game for some reason.

For a concrete example, have a look at the Generic Jump'n'Run example game on your download page; the Fireball Entity in this game uses Pooling. Also see the documentation for ig.EntityPool for some more details.