Many overlapping objects
by WesTT · in Torque Game Builder · 09/10/2008 (2:04 am) · 11 replies
Hi once again everyone. I am having a problem that I am sure someone on here will be able to answer, or at the very least point me in the right direction.
Our game is going well, but we have one small performance hitch: many overlapping animated sprite objects. For the most part, it's not an issue as most of our weapons (it's a shooter) don't fire fast enough to cause a lot of collisions to occur, however, the machine gun fire rate is high enough that when a lot of sprites (say, 60+) overlap so many collisions are registered that the framerate takes a massive nose dive.
I can see that a lot of collisions are being generated both visually via the objects being shot, and via the debug banners PotCol and ActCol output. You might be asking how we manager to get some many sprite objects overlapping, and the answer to that is that we have a forced perspective playfield, like Metal Slug but with depth, and with way more sprites on screen.
I've tried a few things, including:
1.) Altering the bin size and the bin count for the scene
2.) Lowering the number of enemies currently active
3.) Trying to realistically make entities avoid clumping together too much
The first and second help to a degree, but the problem is still apparent at times. The third seems like a bit of a hack though, so I am not too happy to go in that direction at the moment.
The bullets being shot from the MG have a behavior attached to them on which there is an onCollision called, so I assume this is part of the problem as it is being called for each of these collisions. If there is a way to control how many overlapped entities get hit by the bullet that would be a nice, simple way to handle this problem.
I could quite easily be missing a way to control such a thing in TGB, so if anyone can enlighten me, please do!
Cheers
Wes
Our game is going well, but we have one small performance hitch: many overlapping animated sprite objects. For the most part, it's not an issue as most of our weapons (it's a shooter) don't fire fast enough to cause a lot of collisions to occur, however, the machine gun fire rate is high enough that when a lot of sprites (say, 60+) overlap so many collisions are registered that the framerate takes a massive nose dive.
I can see that a lot of collisions are being generated both visually via the objects being shot, and via the debug banners PotCol and ActCol output. You might be asking how we manager to get some many sprite objects overlapping, and the answer to that is that we have a forced perspective playfield, like Metal Slug but with depth, and with way more sprites on screen.
I've tried a few things, including:
1.) Altering the bin size and the bin count for the scene
2.) Lowering the number of enemies currently active
3.) Trying to realistically make entities avoid clumping together too much
The first and second help to a degree, but the problem is still apparent at times. The third seems like a bit of a hack though, so I am not too happy to go in that direction at the moment.
The bullets being shot from the MG have a behavior attached to them on which there is an onCollision called, so I assume this is part of the problem as it is being called for each of these collisions. If there is a way to control how many overlapped entities get hit by the bullet that would be a nice, simple way to handle this problem.
I could quite easily be missing a way to control such a thing in TGB, so if anyone can enlighten me, please do!
Cheers
Wes
#2
09/10/2008 (4:45 am)
Hi Phillip. Yes, I am using both layers and graph grouping of objects. All the enemy entities are in layer 8, group 11. This problem primarily occurs when entities are virtually on top of each other, thus overlapping.
#3
I am about to look for a way to work around this by forcing it to only "hit" one entity at time (or a selected number of entities) via either code or script.
09/11/2008 (4:58 am)
I think I am going to need some help from Melv on this one (Melv, are you around?). I appears that when a bullet from a weapon collides with an entity, and there are many other entities occupying the same space as that entity then all the entities within that space are regarded as being hit, and then "onCollision" is called for all entities in that overlapping area. This makes sense as you do not want to have an engine that misses collisions, however in our case it doesn't work to well!I am about to look for a way to work around this by forcing it to only "hit" one entity at time (or a selected number of entities) via either code or script.
#4

I hope this helps make the problem clearer.
09/11/2008 (5:30 am)
Another update, this time with pictures! This is a shot of our game with some pretty hardcore overlapping occurring:
I hope this helps make the problem clearer.
#5
Another possibility is to check for enemies at the location the bullet would be spawned before actually spawning it via pickradius, then if you any rather than spawning the bullet just pick one and deal damage directly.
09/11/2008 (1:17 pm)
Are you dealing damage in onCollision? Perhaps set a flag on the object causing the collision (the bullet?) in the first oncollision that occurs, then in later oncollisions you early out (return) if that flag is already set. That should work ok, but you might need more control over which one of the overlapping zombies gets hit because it might not be the closest one.Another possibility is to check for enemies at the location the bullet would be spawned before actually spawning it via pickradius, then if you any rather than spawning the bullet just pick one and deal damage directly.
#6
If the zombies are set not to collide with each other, there shouldn't be any problem.
If it's when you shoot bullets in the bunch, then keep the zombies polys to their simplest form, and for the bullets, use circle detection mode instead of polygons, it is quicker.
Also, don't use oncollision on the zombies, instead do it on the bullet itself.
I'm also sure you already saw Melv's PDF on collisions tdn.garagegames.com/wiki/images/a/a3/Collision_Detection_and_Response_Rev2.pdf, if not, go read it and try to optimize with it in mind.
Redo your collisions so that your zombies won't have 'send collision' active, only the bullets and players.
If you've already done everything I said, then... hum... I'm sure you could keep the zombie numbers by trick. Not syncing the zombies at the same time, but delaying some part of it, you don't have to make every function happens at the exact same frame. I'm sure there's some other possible tricks.
09/12/2008 (6:16 pm)
(I will say a bunch of obvious stuff, don't hit me)If the zombies are set not to collide with each other, there shouldn't be any problem.
If it's when you shoot bullets in the bunch, then keep the zombies polys to their simplest form, and for the bullets, use circle detection mode instead of polygons, it is quicker.
Also, don't use oncollision on the zombies, instead do it on the bullet itself.
I'm also sure you already saw Melv's PDF on collisions tdn.garagegames.com/wiki/images/a/a3/Collision_Detection_and_Response_Rev2.pdf, if not, go read it and try to optimize with it in mind.
Redo your collisions so that your zombies won't have 'send collision' active, only the bullets and players.
If you've already done everything I said, then... hum... I'm sure you could keep the zombie numbers by trick. Not syncing the zombies at the same time, but delaying some part of it, you don't have to make every function happens at the exact same frame. I'm sure there's some other possible tricks.
#7
Sorry I'm late on the scene here. Let me absorb what you've said and I'll get back to you shortly.
Melv.
09/15/2008 (7:39 am)
Wes,Sorry I'm late on the scene here. Let me absorb what you've said and I'll get back to you shortly.
Melv.
#8
Something like:
Also, Benjamins advice is spot-on. A few senders being sent to lots of receivers is more efficient than the other way around. The overhead of performing the "OnCollision" script callback isn't that's high unless you're doing thousands per-frame, mostly it's what's being done in the callback that matters.
There are a number of smoke and mirror techniques you can employ to reduce the actual collision-callback requirement but let's try to understand what you've got now before we go there.
If you want to take this private (for the moment) then send me a mail to "melv (dot) may [at] gmail (dot) com".
Melv.
09/15/2008 (8:04 am)
Okay so what's missing here (at least to me) is a detailed view of the layers/groups and send/receive collision status of all the objects involved. Can you quickly provide that to save a lot of back and forward questions.Something like:
Object Name / Layer / Group / SendCol / ReceiveCol Zombie / 8 / 11 / Yes / Yes Bullet / ? / ? / ? / ? Player / ? / ? / ? / ?
Also, Benjamins advice is spot-on. A few senders being sent to lots of receivers is more efficient than the other way around. The overhead of performing the "OnCollision" script callback isn't that's high unless you're doing thousands per-frame, mostly it's what's being done in the callback that matters.
There are a number of smoke and mirror techniques you can employ to reduce the actual collision-callback requirement but let's try to understand what you've got now before we go there.
If you want to take this private (for the moment) then send me a mail to "melv (dot) may [at] gmail (dot) com".
Melv.
#9
The short of it is that I have solved the problem for the most part, or at least cut down the overhead a great deal. The major problem was that I was simply performing too many collision responses using the setImpulseForce call in a single frame. That code was so old (months and months) that I had overlooked it during my attempts to solve the problem.
Zombies are hit by the players weapon projectile and a setImpulseForce call was applied to those that are hit, once this got into the range of >100 objects it created a large dip in frame rate. This probably should have been an obvious place to look for such a performance issue. *ahem*
That said, I've also cut down the zombie collision polys to simply triangles and will probably institute some form of randomized handling of the zombie responses where not all zombies perform their full response all the time, as at the moment they can:
1.) Spawn blood pools (on the ground).
2.) Spawn a particle "jet stream" of blood.
3.) Play an impact animation.
4.) Fly back from the force of the projectile.
5.) Play death animation and spawn a points/experience popup on death
So it can be quite a heavy procedure in the case of a lot of entities present. The machine gun ended up being problematic due to the sheer number of projectiles it can throw out at a time.
@Melv: I went over my collision groups again and they are set up like so:
Player objects have receive collisions on almost solely because they can get hit by some moving objects, such as cars and trains. Zombie attacks are actually handled via a behavior that times a call to the players takesDamage behavior from a "marked" animation frame, so it only hits on that frame. This way I cold turn off body->body collisions between player and zombies.
Erm, apologies for being long winded! Even though it was actually something else causing the problem you have all helped greatly with the solving process.
Regards,
Wes
09/15/2008 (8:35 am)
Hi Guys! Sorry for the lateness of my reply, a massively busy weekend with RL stuff prevented me from being in close proximity with a computer (argh, the pain!).The short of it is that I have solved the problem for the most part, or at least cut down the overhead a great deal. The major problem was that I was simply performing too many collision responses using the setImpulseForce call in a single frame. That code was so old (months and months) that I had overlooked it during my attempts to solve the problem.
Zombies are hit by the players weapon projectile and a setImpulseForce call was applied to those that are hit, once this got into the range of >100 objects it created a large dip in frame rate. This probably should have been an obvious place to look for such a performance issue. *ahem*
That said, I've also cut down the zombie collision polys to simply triangles and will probably institute some form of randomized handling of the zombie responses where not all zombies perform their full response all the time, as at the moment they can:
1.) Spawn blood pools (on the ground).
2.) Spawn a particle "jet stream" of blood.
3.) Play an impact animation.
4.) Fly back from the force of the projectile.
5.) Play death animation and spawn a points/experience popup on death
So it can be quite a heavy procedure in the case of a lot of entities present. The machine gun ended up being problematic due to the sheer number of projectiles it can throw out at a time.
@Melv: I went over my collision groups again and they are set up like so:
Object Name / Layer / Group / SendCol / ReceiveCol Zombie / 8 / 11 / No / Yes Bullet / 8 / 9 / Yes / No Player / 8 / 1 / Yes / Yes
Player objects have receive collisions on almost solely because they can get hit by some moving objects, such as cars and trains. Zombie attacks are actually handled via a behavior that times a call to the players takesDamage behavior from a "marked" animation frame, so it only hits on that frame. This way I cold turn off body->body collisions between player and zombies.
Erm, apologies for being long winded! Even though it was actually something else causing the problem you have all helped greatly with the solving process.
Regards,
Wes
#11
09/18/2008 (12:54 am)
Thanks Melv, we're looking forward to finishing it soon. :D
Associate Phillip O'Shea
Violent Tulip