I've been struggling with this for a while. I have been trying to create a bullet pool class for a game I have made that doesn't cause a significant fps drop.

I have tried creating a bullet pool and have also tried dynamically creating and deleting bullets, both of which drop the fps of the game around 10-15.

I ran a test a few days ago and just put a return statement in the bullet pool's firebullet function, which represented the logic leading up to this, function calling, etc.

This only dropped the fps 2-4. If I can fire bullets without dropping the fps more than another 2-3, I would be satisfied. My bullets are autorelease objects that are a subclass of a ccnode.

I create a ccsprite and a box2d b2body for each one. I am working on the ios platform. Any thoughts on how to make this more efficient? Has anyone managed to do something similar to this?

  • 3
    \$\begingroup\$ How many bullets do you have at one time? and have you run a profiler on the code? \$\endgroup\$ – John McDonald Feb 16 '12 at 21:10
  • 2
    \$\begingroup\$ @JohnMcDonald has the only good answer you will get: "have you run a profiler" and you should follow his advice and investigate ways of measuring runtime performance and stop shooting in the dark (pun intended). \$\endgroup\$ – Patrick Hughes Feb 16 '12 at 22:05
  • \$\begingroup\$ I can have up to 20 or 30 bullets at one time. I have tried running a profiler. The piece of code that takes the longest is the bullet's init code. So I tried creating a bullet pool and storing the bullets in an NSMutableArray. But the calls to NSMutableArray objectAtIndex and NSMutableArray insertObject: atIndex proved to be more time consuming than just creating the bullets when fired. Does anyone know how games like Call of Duty and Halo handle bullets? I recently started paying attention to the frame-rates when firing bullets in those games and they didn't drop at all. \$\endgroup\$ – user13565 Feb 17 '12 at 12:20
  • \$\begingroup\$ Call of duty and halo? I'm not sure, I didn't made any of them, but I think they don't manage any bullet as a entity. They probably cast a ray, collide something show a white line for the bullet path and that's it. \$\endgroup\$ – Gustavo Maciel Feb 18 '12 at 9:46
  • 1
    \$\begingroup\$ It's really hard to tell what the issue is here. Either profile and find out yourself or post some bits of code for us to look at (eg. how you initialize your bullet-pool, how you "create" new bullets and how you recycle them). \$\endgroup\$ – bummzack Feb 18 '12 at 12:23

Your idea about creating a pool is good (if you actually know that the creation/destruction is what's dragging down your fps) but not implemented efficiently. Simply use an array of pointers, no need for the NSMutableArray which is not useful at all. Create a global variable which is an array of pointers to your bullet objects. During startup loop over the array and assign them the individual bullet objects. Add a boolean flag to each bullet object which says if the bullet is in use or not. You avoid memory fragmentation and more importantly, memory operations at all.

This mechanism has the drawback of having a linear search when adding a bullet to the scene because you need to search for a bullet object with the boolean flag set to false. Since bullets tend to live not very long, start the search from the index position of where you created the last bullet + 1 (and wrap around in the array). But for 20-30 objects the linear search should not really be a problem, I've had linear searches for several arrays of 50-100 and that's never the bottleneck. You might want to keep a total counter at least for debug versions to know you don't ever overflow the array of active bullets and keep looping forever searching a valid position.

Now, if even this is too slow or you are scaling to thousands, I would ditch objects and create an array of structures which guarantees memory cache locality. Also, the boolean flag saying an object is free/used would be moved to a separate array. Having all the booleans in a separate structure helps the cache locality and you will have less CPU penalty than jumping around the whole structure block looking for the correct boolean offset (you could even use bit arrays for the separate on/off structure).

Having said this, I've rarely found my logic loop taking more than 20-30% of the time allocated for a frame, most of it going to the graphic loop, so I would first really look at the general performance of your game and see if you are not doing something wrong somewhere else. Remember that optimization is the root of all evil, be evil only in moderate amounts.

  • \$\begingroup\$ Thanks so much! That made the bullet firing system so efficient that it almost didn't drop the fps at all. Thanks again. \$\endgroup\$ – user13565 Mar 28 '12 at 11:43

Use a swap / remove system. When you iterate over your list of current bullets, you will encounter one which is dead. Swap this with the bullet at the end of the list, and decrement the count of exiting bullets. This way, your pool of bullets will always be contiguous. If you want to go for greater efficiency, use an SoA rather than AoS system; your bullets are stored as a series of parrallel arrays, so one array for all the positions, one for all the velocities, and so on. This guarantees cache efficiency.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.