1. Hello Guest! It's with a heavy heart that we must announce the removal of the Legacy GMC Archive. If you wish to save anything from it, now's the time! Please see this topic for more information.
    Dismiss Notice

Checking for multiple collision...

Discussion in 'Programming' started by maxdax5, Dec 3, 2019.

  1. maxdax5

    maxdax5 Member

    Joined:
    Nov 25, 2019
    Posts:
    5
    Hey hey buddies! I looked on how to check for multiple collision at once and only came up to the "instance_place_list" which happens to work. I just want to understand why this dont work:
    Code:
    if (instance_place(x,y,all) != noone){
        under = instance_place(x,y,all);
        with (under){
            if (variable_instance_exists(under,'hp')){
                hp -= 10;
            }
        }
    }
    and this work "with(this){ with(that){ with(i){ }}}"
    My first trouble was that when a projectile was at the same place as an other projectile and that they were over an enemy, they were basically looking for each other.
     
  2. Simon Gust

    Simon Gust Member

    Joined:
    Nov 15, 2016
    Posts:
    3,220
    The reason is that unlike instance_place_list, instance_place doesn't give you a list and only one instance of all to work with if multiple instances are in the same place.
    A tip:
    - use parenting for the objects that have the variable "hp", I don't know how slow variable_instance_exists is but I assume the worst case scenario, it will slow down your game if you have several projectiles on screen at once.
     
  3. TheouAegis

    TheouAegis Member

    Joined:
    Jul 3, 2016
    Posts:
    7,136
    Simple speed comparison test. You know the drill, repeat 10000 func(); get_timer()-t) comparing four functions -- variable_instance_exists(id, known variable); variable_instance_exists(id, unknown variable); sprite_exists(known sprite); and sprite_get_width(0) -- run 5 times, then I swapped the two variable_instance_exists() calls to account for 'startup lag', then run 5 more times. The results were:

    sprite_get_width(0) = 9/10000 of a second to run 10000 times
    sprite_exists(known) = 28/10000 of a second to run 10000 times
    variable_instance_exists(id,known) = 35/10000 of a second to run 10000 times
    variable_instance_exists(id,unknown) = 35/10000 of a second to run 10000 times

    Then to be fair, I replaced id with object_index expecting the same values since there was only one instance in the room. The results were identical.

    Then to really rub it in, I quadrupled the number of instances in the room. Surprisingly, it was only 5/10000 of a second slower. So I wondered if that meant it was only checking one instance rather than all. To test that, I modified the code to break if variable_instance_exists() was true. The expected result was a value of 0 or 1/1000000 of a second. Surprisingly, I got two values -- 1/1000000 and 5/1000000 of a second, always with the slower time first. It didn't matter if only one instance had the variable or all instances had the variable. This suggested to me that GM might be populating a data structure the first time the function is called each step; I'm not certain of it, but I even got the same values when I shuffled the order of function calls. Regardless, all this told me was that GM did search through all instances looking for a variable. Then the next question was if GM would break the subroutine as soon as a matching instance was found. To test this, I altered the code to now run the each test 1000 times (so repeat 1000 repeat 10000). This yielded more workable results:

    variable_instance_exists(object_index,known in all instances) = 4/10000 of a second to run 10000 times 1000 times
    variable_instance_exists(object_index,known in first instance) = 4/10000 of a second to run 10000 times 1000 times
    variable_instance_exists(object_index,known in last instance) = 6/1000 of a second to run 10000 times 1000 times

    Even allowing for the additional overhead of the repeat function, the results were clear.

    We can take away a couple obvious things from this:
    1. With very few instances, the difference in speed is negligible, as always
    2. GM will check all instances of the specified object, starting with the oldest instance, and stop upon success
    3. Passing object_index also affects all children of object_index and loops based on id (alternating between objects)
    4. The more instances there are, the more imperative it is that an actual id is passed instead of an object_index
    5. Any function that requires a string to be passed is at least twice as slow as a function that doesn't require a string
    6. Don't use variable_instance_exists() unless working with external functions which may necessitate it
     
    MartinK12 and Simon Gust like this.
  4. Simon Gust

    Simon Gust Member

    Joined:
    Nov 15, 2016
    Posts:
    3,220
    I do know the drill but I do not own GM:S 2, so I am glad you did.
     

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice