GML with () using a parent skips instance when deactivating

Desix

Member
Hi. So, I use this code to activate and deactivate instances. I call it spawning here, but still.

Only things you need to know is objGameObject is parent to all enemies and other... game objects. And spawn_* variables are basically the view size and despawn_* variables are a much larger area. This is to allow objects to spawn but you need to move further to despawn them. The objects keep a flag which lets them remember if they were still meant to be despawned even after they are activated. The game objects have a GameObjectSpawnWidth and GameObjectSpawnHeight which lets them spawn appropriately with their size.

GML:
        //activate all
        instance_activate_all();
        
        var rectangle_test;
        with (objGameObject)
        {
            if (GameObjectFlagCanDeactivate)
            {
                //check if in spawn region
                if (GameObjectIsDespawned)
                {
                    rectangle_test = rectangle_in_rectangle(x-GameObjectSpawnWidth, y-GameObjectSpawnHeight, x+GameObjectSpawnWidth, y+GameObjectSpawnHeight, spawn_left, spawn_top, spawn_right, spawn_bottom);
                    if (rectangle_test) GameObjectIsDespawned = 0; //object can avoid being despawned again as it's in the active region
                }
                
                //despawn if outside despawn region
                rectangle_test = rectangle_in_rectangle(x-GameObjectSpawnWidth, y-GameObjectSpawnHeight, x+GameObjectSpawnWidth, y+GameObjectSpawnHeight, despawn_left, despawn_top, despawn_right, despawn_bottom);
                
                //if not resurrected or outside despawn region
                if (GameObjectIsDespawned || (!rectangle_test)) //if still marked to be despawned or it needs to be forced to despawn
                {
                    GameObjectIsDespawned = 1; //mark as despawned
                    instance_deactivate_object(id);   
                }
            }
        }
Let's say there's 3 game objects in the room, but only one of them has the GameObjectFlagCanDeactivate flag set, and it's an enemy (objEnemy). objEnemy of course is a child of objGameObject. To be specific, it's a child of a child of objGameObject. I don't suppose this matters and I have never had an issue with that before.

The enemy is only part of the loop every other frame. Even though I activate all right before, only on every other frame does the with loop include the enemy. So the enemy will flash in and out of existence every frame. I have checked this by showing a debug message at the start of the loop. The frame which doesn't process it in the with() means it stays active for that frame, then the next frame, it is included win the with again. It should work every frame since I activate all. This all happens off screen, yes, but is very wrong. If I check directly after the activation for if objEnemy exists, it does. Each frame.

I can only assume this is some weird quirk of GameMaker's deactivation I didnt know about. What's going on here?

But it gets weirder:
If I instead use the actual objEnemy in the with instead of objGameObject, the enemy despawns and respawns perfectly, with no issues. This rules out it being anything else on my end.
So yeah.
Riddle me that... But of course, I cant keep it this way as there are many objGameObject that need despawning.

So... I guess it must be a parent quirk I suppose? But I have no idea what or why. Shouldnt with (objGameObject) always work through all of them? And well, it does, but only on every other frame like I said... so that again makes me think its not a parenting issue...

Very strange. Appreciate any help!
 

chamaeleon

Member
Would it be related to this quote from the manual about instance activation?
Note too that activation is not instantaneous, and an instance that has been activated in this way will not be considered to be active until the end of the event in which the function was called.
 

Desix

Member
Oh man that's a... that's a very frustrating fact to read.

Ok, well I had good reason to assume this wasnt it because changing the object in with() worked..... but
Yeah so putting the instance_activate in begin step instead of step works... that seems hella janky though... especially since I can't contain it all in one place, even if I wanted to.

Still confuses me why using the object name itself works? How even after 13 years I still have issues with this basic stuff (I've never really had an issue till now though)
 
Last edited:
Top