• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

Deactivating/Reactivating only working every other step

M

McKayB

Guest
So I want to deactivate all objects of a certain type outside of a specific region. (I don't want to use the instance_deactivate_region function, because it doesn't discriminate the type of object.)

The way I'm implementing this currently is to activate all the objects of that type in the Begin Step event. Then, in the Step event, I update their position, then deactivate them if they're outside the desired range.

This is working ... inconsistently. It works on objects that begin outside the desired region, but not on objects that move outside of the desired region after their creation. Those, instead of any expected behavior, start flashing (as long as they remain outside the desired region), as if they're being activated and deactivated every second step.

Any idea what's going on here?
 

RangerX

Member
The outside view event is also like a step. When the object is outside the view, it could check its own position and deactivate itself when need be?
 
M

McKayB

Guest
Hey there, thanks for responding! However, I don't understand what you're saying. What do you mean by "the outside view event"?

I don't want to have the object check its own position and deactivate itself, because in my spaghetti code this same object is used other places (when it should probably just be a child object of the other uses) ... oh well. I could still move the deactivation effect onto the individual objects with some effort, but I don't understand why that might help?
 

The-any-Key

Member
Note that an active instance at start of the tick, can be deactivated in step begin and activated in the step event. And it will be active and run its step end event.

But if you have an active instance and deactivate it in step 1. And in step 2 activate the object in step begin. It will not be active at all in step 2. It will first be active in step 3.

So there is a difference depending if the instance was active from the tick start or not.
 
L

Ludorverr

Guest
I don't know if this will help but here's how I do things:
Code:
//Step event of main controller object

//List all the object types that you want to deactivate outside the view:
with oEnemy {instance_deactivate_object(id)}
with oTerrain {instance_deactivate_object(id)}
with oThing {instance_deactivate_object(id)}

//Activate all the ones inside the view: (use your own view coordinates)
instance_activate_region(viewx, viewy, view_width, view_height, true)

//OR with a buffer around the edges of the view so that you can't see objects pop-in/pop-out at the edges:
instance_activate_region(viewx-24, viewy-24, view_width+24, view_height+24, true)
As the view moves, the specified objects that fall outside the view will become deactivated and the ones that enter the view will become activated.

If you want to optimize further so that the on-screen objects don't deactivate and reactivate pointlessly (it's harmless but may cost FPS) then you write an is_on_screen() script which checks if that object is within the view.
Code:
with oEnemy {
   if is_on_screen()=false {instance_deactivate_object(id)}
}
with oTerrain {
   if is_on_screen()=false {instance_deactivate_object(id)}
}
with oThing {
   if is_on_screen()=false {instance_deactivate_object(id)}
}

instance_activate_region(viewx-24, viewy-24, view_width+24, view_height+24, true)
It's a worthwhile optimization, the masses of objects outside the view are unable to run this extra check because they're already deactivated.
 
Last edited by a moderator:
M

McKayB

Guest
Note that an active instance at start of the tick, can be deactivated in step begin and activated in the step event. And it will be active and run its step end event.

But if you have an active instance and deactivate it in step 1. And in step 2 activate the object in step begin. It will not be active at all in step 2. It will first be active in step 3.

So there is a difference depending if the instance was active from the tick start or not.
OK, that ... almost makes sense. At least it's a theory as to why (some of) the objects are flashing on and off every other frame. Any suggestions about how to fix it? Like, only deactivating the objects on even-numbered ticks or something?

I don't know if this will help but here's how I do things:
Code:
//Step event of main controller object

//List all the object types that you want to deactivate outside the view:
with oEnemy {instance_deactivate_object(id)}
with oTerrain {instance_deactivate_object(id)}
with oThing {instance_deactivate_object(id)}

//Activate all the ones inside the view: (use your own view coordinates)
instance_activate_region(viewx,viewy,viewx+480,viewy+270,true)

//OR with a buffer around the edges of the view so that you can't see objects pop-in/pop-out at the edges:
instance_activate_region(viewx-24,viewy-24,viewx+480+24,viewy+270+24,true)
As the view moves, the specified objects that fall outside the view will become deactivated and the ones that enter the view will become activated.

If you want to optimize further so that the on-screen objects don't deactivate and reactivate pointlessly (it's harmless but may cost FPS) then you write an is_on_screen() script which checks if that object is within the view.
Code:
with oEnemy {
   if is_on_screen()=false {instance_deactivate_object(id)}
}
with oTerrain {
   if is_on_screen()=false {instance_deactivate_object(id)}
}
with oThing {
   if is_on_screen()=false {instance_deactivate_object(id)}
}

instance_activate_region(viewx-24,viewy-24,viewx+480+24,viewy+270+24,true)
It's a worthwhile optimization, the masses of objects outside the view are unable to run this extra check because they're already deactivated.
If I deactivate first and then reactivate, rather than the other way around, it seems like the objects' positions would never get updated, so they would never move into the zone that activates them. (It is the objects that move, not the zone.) Am I thinking of this correctly?
 
L

Ludorverr

Guest
so they would never move into the zone that activates them
Correct, why would you expect deactivated objects to move around? If they can move around then you would not be saving FPS, it wouldn't be a good optimization.

I don't know what you're trying to achieve, I only assume you want FPS optimization. The point of deactivating objects outside the zone/region/view is that you gain FPS by losing the ability to access the objects at all. (Until the player moves the view region over the top of them, which reactivates them)

However you could add further conditions for deactivation - like say the enemy sees the player, so its variable is set "alerted=true", then the player runs away from that enemy so the view doesn't cover that enemy anymore. Normally the enemy would be deactivated and stop chasing, but with an additional condition it can stay in the game and continue chasing the player:
Code:
with oEnemy {
   if alerted=false && is_on_screen()=false {instance_deactivate_object(id)}
}
The only issue with that is the enemy can walk over positions of deactivated objects (off-screen). But if you reactivate a small region around them like with instance_activate_region(x-48,y-48,96,96,true) then that one alerted enemy will be able to collide with those off-screen objects.
 
M

McKayB

Guest
Correct, why would you expect deactivated objects to move around?
I didn't expect it, but I thought I'd ask anyway, as it would make your algorithm more useful to me if this was the case. Anyway, I didn't expect deactivate/activate to be asynchronous effects, either, yet they are and the whole problem stems from that.

I don't know what you're trying to achieve, I only assume you want FPS optimization. The point of deactivating objects outside the zone/region/view is that you gain FPS by losing the ability to access the objects at all. (Until the player moves the view region over the top of them, which reactivates them)
I'm actually just trying to achieve a scrollable menu. Like, there may be too many menu options to fit in the menu's area, so they move up and down as the user scrolls, and the option buttons are deactivated when they're outside the target area. I don't care much about FPS optimization, as this isn't an action game.

Is deactivation/activation really supposed to be only for FPS optimization? Should I not be using deactivation for this, even though I want the objects to turn invisible AND not be clickable outside the target area? It would be kind of a pain to program in my own "de-activated mode," but that might be where I'm at.
 
Top