0 Favourites

On Collision Performance (Tracking)

  • Ashley,

    Could you please explain to me how the "On Collision Event" works internally?

    For example, hypothetically, let's say that I have Event Sheet 1:

    Obj1 On Collision Obj2 : Do some actions

    Event Sheet 2:

    Obj2 On Collision Obj1 : Do some actions

    If I assume that the events in both sheets are run as a single concatenated logic loop, would it be correct to assume that the collision detection stores a dictionary of prior checked collisions for objects? In this manner, Event Sheet 2's collision check cost would be minimal.

    The reason that I ask is because I have two ways of handling collision detection at this point.

    My original way was more modular, all objects belong to EntityFamily which has a local var called CollidedFn, which is a link to a function. All collision detection was centralized in a single CollisionEventSheet which would do something along the lines of:

    On EntityFamily Collided with EntityFamily : Call EntityFamily.CollidedFn which would hand off the collision to the object's collision routine.

    However, each object (which is represented in my project by a single event sheet) could also have an:

    On Object CollidedWith EntityFamily : Do something (note that this is Object-specific)

    However, if we're not tracking existing checked collisions in a single "loop cycle", having this On Collision statement repeatedly could get very computationally expensive.

    I'm just trying to look for best practices here.

    Thanks,

    -- Cacotigon

    P.S. I might be thinking about this the wrong way, are "On Events" different from regular events in the game loop? Are they maybe like delegate triggers?

  • Hi,

    i dont know the answer to your question, but i did see Ashley reply to another performance related question recently and he pointed to this.

    scirra.com/blog/83/optimisation-dont-waste-your-time

  • Construct 3

    Buy Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Buy Now Construct 3 users don't see these ads
  • Internally, 'On collision' is not a real trigger even though it appears like one in the event sheet - it works like 'Is overlapping' with 'Trigger once' after it. This is for performance reasons (it would be difficult to avoid unnecessary collision checks if it was a real trigger).

    Generally the performance of overlap tests is negligable unless you have hundreds of objects or more (see spongehammer's link). However it's good practice to only have one overlap or collision test, and do everything you need to in subevents under that. If you have two 'On collision' or 'Is overlapping' events, it will re-check the overlap both times.

    It could actually degrade performance to cache results, because if an object moves it has to remove any cached collision results. This means every time an object moves it has to do a little bit of work. Most games have a very large number of moving objects, which multiplies a little bit of work in to a lot of work. So I'm not sure that would actually make it faster.

  • Ashley,

    EDIT: I just re-read your post in which you kind of address this potential solution. :p Sounds like as you've said, it might actually hurt performance.

    Thanks for your reply.

    What if you invalidated all cached Collision results for a given entity after any command which results in a change of position/angle/scale using some kind of HasChanged boolean?

    So maybe you have a central collision Cache which is an internal dictionary, it is only added to when two elements collide. The key represents the unique instance of the object, and the value is a enumerable list of elements that it has collided with on this loop cycle.

    CollisionMap[Obj1] = { Obj2 }; // set of objects Obj1 has collided with

    CollisionMap[Obj2] = { Obj1 }; // set of objects Obj2 has collided with

    So in the game loop:

    <font size="2">

    <font face="Verdana, Arial, Helvetica, sans-serif">

    Clear Collision Dictionary at beginning

    Set all objects HasChanged = false

    On Obj1 Collision Obj2 routine: (doesn't actually do any bound checking yet)

    Foreach(Obj1 in Layout)

    -- Foreach(Obj2 in Layout)

    -- -- If Obj1.HasModified = false && CollisionMap[Obj1].Value.Contains(Obj2) { TriggerCollision(); }

    -- -- Else { Run Normal collision bounding checks -- save results into CollisionMap }

    </font>

    </font>

    Would this help to optimize collision performance at all?

Jump to:
Active Users
There are 1 visitors browsing this topic (0 users and 1 guests)
Similar Topics Posts Views Last Post
Unread hot topic
331 35,573
Lordshiva1948's avatar
Lordshiva1948
Unread hot topic
157 12,697
megatronx's avatar
megatronx
Unread hot topic Locked topic
112 7,122
Ashley's avatar
Ashley Construct Team Founder