I’m finally at the point where I had to tackle this problem, which can be briefly summarized as follows. Any game with a shooting mechanic needs to handle bullets, which are a large number of short-lived objects. The naive solution is to create a new bullet every time the player fires a weapon, and then forget about it when the bullet’s no longer ‘alive’. However, the Android garbage collector will punish you if you do that, and your game will experience large stalls every few seconds as it reclaims all that memory. You need to set up a pool of objects, and reuse them. Any Android developer who’s done a game with some kind of ‘bullet’ in it knows this. I dealt with this in Bus Jumper, where the falling objects are essentially bullets. But Neil Rajah presented some new challenges, which required a new solution.
The first difference is, I’m using Artemis. Artemis handles entities internally, so you can create and delete entities without generating garbage. However, you must create all component objects, and Artemis has no notion of pooled components. thelinuxlich has created a C# port of Artemis, and that has one solution to this problem – a callback mechanism where Artemis informs you when it’s deleting a component, so you can handle the pooling if you want to. It’s a pretty good approach, I think, and I started out copying that. But then I realized that I don’t really need to recycle entities or components. I’m using box2d, and I can leave a ‘dead’ bullet in the box2d world, and just deactivate it / make it invisible. This way, the physics simulation won’t start chugging trying to deal with all those bullet objects. The Artemis world will end up with a large number of entities, but so far Artemis has proved to be pretty fast. Also, if I’m aggressive with recycling bullets (they die if they collide with anything, they die if they leave the visible screen area, etc.), then hopefully I’ll reach steady state without too many bullet entities in Artemis. We’ll see – I may have to revisit this if that assumption proves to be wrong.
Anyway, with that background, here’s my solution. I started out trying to use generics (I still call them ‘templates’ in my head), got kinda lost, and finally ended up with something based on inheritance. Before I started using Artemis, I had written a weapon / bullet system that was fairly generic, and allowed different kinds of bullet behavior to be instantiated without any changes to the weapon logic. I wanted my new weapon system to have similar flexibility.
The basic idea uses an abstract class called Bullet, of which there is currently one derived class, Knife:
protected Body body;
public void activate(Vector2 position) {
body.setTransform(position, 0);
body.setActive(true);
}
public void deactivate() {
body.setActive(false);
}
}
This just handles the physics for now, I haven’t yet done anything with the render side of things. Anyway, a bullet can be activated and deactivated. Then we have it’s derived class, Knife, which actually builds an object with the behavior I want:
public Knife(World artemisWorld, FixtureDefBuilder fdBuilder,
BodyBuilder bodyBuilder) {
Entity e = artemisWorld.createEntity();
e.addComponent(new LabelComponent(Label.Bullet));
e.addComponent(new RenderableComponent(Layers.DynamicObjectsLayer));
e.addComponent(new FixedHorizontalVelocityComponent(25f));
e.addComponent(new AntiGravityComponent());
float hw = 0.5f;
float hh = 0.125f;
FixtureDef fd = fdBuilder
.boxShape(hw, hh)
.density(1.0f)
.friction(0)
.build();
// Can't use BodyBuilder here, since we're not adding it to
// the world
body = bodyBuilder
.fixedRotation()
.type(BodyType.DynamicBody)
.position(0, 0) // FIXME ???
.fixture(fd)
.userData(e)
.bullet()
.build();
e.addComponent(new PhysicsComponent(body));
// Use SpatialPhysicsImpl here, since this body will move
e.addComponent(new SpatialComponent(new SpatialPhysicsImpl(body,
hw * 2, hh * 2)));
e.addComponent(new DamageComponent(10));
e.refresh();
}
}
A knife has fixed horizontal velocity, anti-gravity (which means it moves in a horizontal line even though it’s a dynamic box2d object) and a box2d body. I’m using lots of helper classes from Ariel Coppes and Rubén Garat’s Gemserk library.
Then I have a couple of factory classes. I’m not sure if these are really factories in the strict sense of that design pattern, but they felt like factories to me, so that’s what I called them. The abstract BulletFactory:
protected final com.artemis.World artemisWorld;
protected final FixtureDefBuilder fdBuilder;
protected final BodyBuilder bodyBuilder;
public BulletFactory(World box2dWorld, com.artemis.World artemisWorld) {
this.artemisWorld = artemisWorld;
fdBuilder = new FixtureDefBuilder();
bodyBuilder = new BodyBuilder(box2dWorld);
}
public abstract Bullet create();
}
And the derived KnifeFactory:
public KnifeFactory(World box2dWorld, com.artemis.World artemisWorld) {
super(box2dWorld, artemisWorld);
}
@Override
public Bullet create() {
return new Knife(artemisWorld, fdBuilder, bodyBuilder);
}
}
And finally, I have a BulletPool, which is based on the libGDX pool, and uses the factory to create new bullets:
private BulletFactory factory;
public BulletPool(BulletFactory factory) {
this.factory = factory;
}
@Override
public void dispose() {
clear();
}
@Override
protected Bullet newObject() {
return factory.create();
}
}
That’s everything in my ‘weapons’ package. So how does this tie into Artemis?
When I create a new world for a new level in the ‘play’ gamestate, I set up the factory and pool objects:
artemisWorld = new com.artemis.World();
artemisWorldWrapper = new WorldWrapper(artemisWorld);
knifeFactory = new KnifeFactory(box2dWorld, artemisWorld);
bulletPool = new BulletPool(knifeFactory);
The ‘play’ gamestate also creates all the systems, including the weapons system:
Note that the weapon system knows nothing about the type of bullet that the weapon will fire. Similarly, when creating the entity for the main character / player, there’s a weapon component added. This uses the bullet pool created above.
The bullet pool was created with a reference to the KnifeFactory, so it will create Knife objects when requested. That’s the only place where the actual bullet type is nailed down. None of the other code knows anyhing about what kind of bullet it’s creating.
The weapon component is pretty simple. According to the entity-component-system design approach, components only have data, and systems only have logic. So here’s the weapon component:
private int shootDelay; // In ms
private BulletPool bulletPool;
private boolean shootRequested = false;
private long lastShoot;
public WeaponComponent(int shootDelay, BulletPool bulletPool) {
this.shootDelay = shootDelay;
this.bulletPool = bulletPool;
}
public int getShootDelay() {
return shootDelay;
}
public void requestShoot() {
shootRequested = true;
}
public boolean shootRequested() {
return shootRequested;
}
public void clearShootRequest() {
shootRequested = false;
}
public void shoot(Vector2 position) {
lastShoot = System.currentTimeMillis();
Bullet bullet = bulletPool.obtain();
bullet.activate(position);
}
public long getLastShoot() {
return lastShoot;
}
}
I’m a little bit undecided here. The shoot() method has a bit of logic in it
I had started out with the bullet pool handled in the weapon system, then moved it to the weapon component. I might move it back. Anyway, it’s a very small amount of logic
The weapon component keeps some state about the last time it was fired. When instructed, it gets a new bullet object from the pool and activates it.
The weapon system is also pretty simple:
protected void process(Entity e) {
WeaponComponent weaponComponent = Components.getWeaponComponent(e);
if (!weaponComponent.shootRequested()) {
return;
}
if (System.currentTimeMillis() - weaponComponent.getLastShoot() <
weaponComponent.getShootDelay()) {
return;
}
// Get the player's position, and launch the bullet a little bit
// in front of him
Spatial spatial = Components.getSpatialComponent(e).getSpatial();
Vector2 position = spatial.getPosition();
position.add(spatial.getWidth() / 2 + 0.1f, 0);
weaponComponent.shoot(position);
weaponComponent.clearShootRequest();
}
If the shoot button was clicked, and it’s been long enough since the last shot was fired, it launched a new bullet slightly ahead of the player’s position.
Here’s how it all works:
- The input system detects that the ‘shoot’ button was clicked / key was pressed, and sets the ‘shoot requested’ flag on the weapon component
- When the weapon system runs, it notices that, and tells the weapon component to launch a bullet
- The weapon component tells the bullet pool. If the pool has a free bullet, that is reused. The Artemis entity is already present with all its components, and the box2d object is already present in the box2d world. So all that needs to be done is to activate the body in box2d.
- If there are no free bullets in the pool, the factory is requested to make a new one
And that’s it. The part that’s still missing is reclaiming the bullets, but hopefully that shouldn’t be hard. I need a bullet processing system that checks for collisions and screen bounds, and deactivate bullets as necessary, applies damage, updates health, etc. Once I throw in the sprites, the activate/deactivate will have to enable/disable the sprites as well.
Overall, I like how this turned out. Specifically, I’m happy that all the bullet-specific code is in the Knife class. If I want to create spears that arc up and then fall back down, or something like that, all I need is a new Bullet-derived class and the corresponding factory.
I haven’t done any performance tests of this approach on the phone yet, so I might end up throwing all of this out if the performance sucks
But I’m hopeful it won’t, I think this design seems like a decent approach to the problem.
Related posts:

First of all, nice post. I was thinking to follow a similar approach when I was prototyping Jetpac clone to solve the bullets reuse problem.
For our Vampire Runner game, we needed to reuse objects like trees, ground, mountains, etc too, what we did in this case is to create a Store of objects of each type and we have two inner collections, the free objects and the created. Each time an object should be removed from the world, we add it to the free collection. Each time we need a new object to be spawned, we get one from the free collection, if there is none then we create a new one, we reuse one otherwise. This works, but we are not disabling “removed” entities because for this particular game we didn’t need, however I believe that disabling collisions, rendering and script processing could be a great addition.
Hope I was clear, I written everything in one paragraph and seems a bit confusing.
I might look at your solution some day and see if I want to ‘borrow’ it
The specifics of my game drove my design to a large extent. If I throw a knife in front of me and it collides with a wall, I don’t want the player to run up and collide with the knife. So I have to remove it from the physics simulation to some extent. I came up with a solution that seems to work fine for now. See the next post for details.
Yeah, as I said, we lack for now things about disabling entities (physics, render, etc), and that is a problem since they keep interacting with the world. That’s our next step in the reuse entities/components path.
[...] since their life cycle is really short. Ziggy made two blog posts about this topic some weeks ago here and here, however we followed a slightly different approach and we will explain it in this [...]