This is an old chestnut but I’ve been away from ecs for a while and I figured some users on here probably have some good real world experience with this topic by now.
There’s two types of collision handling models (that I know of) which is component based and event based.
In the component based model, collision data is added to the affected entities and then your systems can iterate by component. E.g.
BulletCollisionHandler<Bullet, Collision>(…remove bullet)
CollisionDamageHandler<Health, Collision>(… subtract damage from Health)
In the event based model, systems iterate the actual collision events and process them that way. E.g.
if (HasComponent(collisionEvent.EntityA) { etc. }
Generally speaking, in the component based model, you either add/remove buffers to affected entities each frame (structural change) or you use permanent buffer components which means iterating all entities whether a collision occurred or not.
In the event model, you end up iterating the events array multiple times but this is cache friendly and can mostly be optimised out. The downside is mostly in asking each entity if it has the components you’re interested in though even the component based approach suffers this too to a lesser extent.
I don’t particularly see one better than the other as there’s a lot of cons in both approaches. The component model probably makes for cleaner code in the collision handling systems though as half of the filtering is already done.
PhilSA provided a neat solution here for the component based model which covers that solution nicely but it seems quite heavy to me.
One issue I have with this approach is the amount of space the collision buffer takes up on each entity. In my own game I have an entity with a trigger zone that can receive 20 collisions in a single frame whereas most other items will only receive 1 to 3. This makes it tricky as to how much space to allocate to the buffer. Either lots of wasted space or some end up on the heap which is possibly worse.
I’m using the event approach in my own game but most of my collision handling is based on collision mask type as opposed to component type. So my collision handling systems are interested in if maskA collided with maskB (as defined by the collision layer) which has good optimisations for this model.
So I’m just after feedback on which approaches others have taken and how they’ve found it works in real world scenarios. Especially for those using the component based approach. What were their pros/cons/optimisations.
It’s not an easy thing to change models part way through development.