What is a collision pair, and how can I minimize them?

Hey man, I’m facing the same problem, have programming background so your answer can be technical.

I am not pooling as instancing is not a problem for performance in my case (yet - I’ll add pooling at the end). But when enemies get on top of each other, performance dips a lot. I’m also around 28k collision pairs.

Each enemy is an Area2D with a collision shape + 2 areas under it, a hurt_box and a hit_box (“attack box”). The masks are already setup so that only the main collision_shape is interacting with another enemy’s collision shape, hurt_box is only affected by player projectiles, and hit_box/attack_box only interacts with player’s hurt_box. I’m guessing the issue is that when 50+ enemies are near a player, that’s a lot of combinations between those 3 collision shapes and player’s own hurt_box and that explodes my Collision Pairs, is that correct?

I’m thinking of 2 possible solutions, would love your take on these:

  1. Easy solution: disable main Collision Shape on enemies when they’re close enough to the player. Those are used so enemies can knock other enemies away from themselves so they keep some minimum distance between them. However, once they’re close enough to the player, they’re already so bunched up that I suppose letting them just walk over each other is okay. Of course, once player moves away from bunched-up enemies, their collision shapes will re-enable and it will cause a spike, but… better a spike than constant lag.
  2. Hard and lower priority solution: if we have multiple enemies on top of player, disable hit_box of all enemies in that group but one, and increase the damage of that one enemy by sum of damage of all other enemies that touch the player. This is lower priority b/c, realistically, once enough enemies are on top of the player, the player should be dead. At the same time, you don’t want to lag in the final second of your life, and if you have invulnerability item that triggers, you can still escape so for those moments this optimization will be good.

Outside of reducing physics grid cell size, is there anything else I could realistically do here? (I already limit max enemy count on-screen to ).

Thank you so much!!

UPDATE: Ok, implementing #1 has solved all problems for now. Literally 1 line of code (collision_shape.disabled = distance_to_player < 100). Collision Pairs dropped by 10x down to ~2500 max. I think #2 solution isn’t necessary b/c there’s only 1 player, so every enemy’s attack_box/hit_box only pairs with 1 hurt_box (on the player), whereas with collision shape on enemies themselves we had each enemy creating a collision pair for each nearby enemy, which is ofc exponential growth in pairs. But if you have more wisdom, still would love to hear it!