Checking for multiple collision...

M

maxdax5

Guest
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.
 

Simon Gust

Member
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.
 

TheouAegis

Member
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.
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
 

Simon Gust

Member
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
I do know the drill but I do not own GM:S 2, so I am glad you did.
 
Top