GML Is an mp_grid REALLY slow?

Dr_Nomz

Member
I have a 5000x5000 room with cells of 50x50, and I can't seem to have more than 50 zombies at a time with massive frame rate drips. Any way to counteract that?
 

Coded Games

Member
What is likely taking a long time is pathfinding. What are you using to create paths and how often are you calculating them?
 

Evanski

Raccoon Lord
Forum Staff
Moderator
Mp_grids use a lot of CPU as it is, if your having zombies create there own individual ones it will cause huge memory leaks and big big problem
some steps you can take are
  1. Have all the objects use one grid
  2. make sure the grid is destroyed when you no longer need it
  3. check to see if its updating the grid every step, you just need the path that the zombies use to get to object that the zombies want to get too to be updated every step
  4. The size of your room also affects the grid
My best advice is at the start of the room have an object create the grid then just have the zombies use the path for that grid.
I have a video on grids if you'd like to check it out.
 

JackTurbo

Member
Basically what evan said. Make sure you have one grid that all enemies use.

Make sure your enemies don't pathfinder every frame. Better to do it in an alarm that is randomised to a degree. This helps make sure that they don't all pathfind on the same step, which could cause a hang.

If the size of the MP grid is what's causing the issue you could make it smaller than the whole room and simply update it every X number of seconds. I've not needed to do this, but should be relatively simple.

Here's my system in action. Runs about 1500fps with 50 enemies.
 

Dr_Nomz

Member
Basically what evan said. Make sure you have one grid that all enemies use.

Make sure your enemies don't pathfinder every frame. Better to do it in an alarm that is randomised to a degree. This helps make sure that they don't all pathfind on the same step, which could cause a hang.

If the size of the MP grid is what's causing the issue you could make it smaller than the whole room and simply update it every X number of seconds. I've not needed to do this, but should be relatively simple.

Here's my system in action. Runs about 1500fps with 50 enemies.
Now see THAT'S probably it. Mine does start off at the beginning once the room starts, but I didn't think they needed the pathfind only once in a while. Wait, what about for an action game where they consistently follow you? Wouldn't that be an issue?

Also 50 enemies is nice and all, but I was hoping more for at least 250 max...
 

JackTurbo

Member
Now see THAT'S probably it. Mine does start off at the beginning once the room starts, but I didn't think they needed the pathfind only once in a while. Wait, what about for an action game where they consistently follow you? Wouldn't that be an issue?

Also 50 enemies is nice and all, but I was hoping more for at least 250 max...
No that's fine. I think while the pathfinding is probably whats making your code so slow, really the issue is how you're thinking about your AI.

My current project (A Day In Valhalla) is a hack-n-slash action game so the requirements from the AI are probably pretty similar to what you need.

Essentially the key thing in my opinion is splitting out your decision making code (path finding for example) from the code that performs the action (like following a path). The code for moving/following a path of course needs to be ran every step, but the code for generating a path only really needs to be ran every now and then for them to convincingly follow the player.

By putting all decision making code into an alarm that triggers every so often, this also gives you enemies a convincing reaction time to changing situations, which in my opinion actually feels better and more realistic from a gameplay perspective. It gives enemies a nice reaction time.

You can vary how often you run the decision making code from enemy type to enemy type to give them differing reaction times. My goblins run it fairly in frequently as they are dim witted and so are naturally slow to react, other enemies do it much more frequently however.

As for number of enemies, while I've not tested it (my game design is more focused on around 20 max enemies at a time) I'm fairly certain it could easily handle 100+ and still run well on all but the most potato of machines. If you want really big groups of enemies however then you would want to look at other optimisations for that. You can group clusters of enemies when they're close to each other and have them all use a single path for example.
 
Last edited:

Dr_Nomz

Member
Well that sounds like awesome advice, but pertaining to my current system:
Code:
target_x = argument0;
target_y = argument1;

mp_grid_path(grid,path,x,y,target_x,target_y,true);
path_start(path,100,path_action_stop,false);
That script is called to give the NPC (zombie) the path it needs to follow. (based on a grid that's created at the start of the room) In this case "target_x/y" can be anything, but is currently the obj_Character. (Player Character)

The zombie's code:
Code:
///End Step
motion_add(point_direction(x,y,planner.x,planner.y),1);
  if speed>5{
    speed=5;
    }
  target_x = obj_Character.x;
  target_y = obj_Character.y;
  with (planner){
    x=follower.x
    y=follower.y
    scr_NPC_Path(other.target_x,other.target_y);
    }
The "planner" is just an object with the create event for making the path in the first place, and then the zombie follows it from there. It's basically done this way to provide smoother movement.
Code:
planner = instance_create(x,y,obj_Path_Planner);
planner.follower = id;
^That's the zombie's create event, which creates the planner with the ID and everything it needs to function for that specific instance of obj_Zombie.

Basically I'm wondering if anything here "looks wrong", and if so please tell me immediately.
Otherwise, I think I can figure out where to put the necessary code to point your idea into practice. (And if I still can't get it I'll come back)
 

JackTurbo

Member
On my phone atm, so haven't got my head round your code 100% however it looks like you're running mp_grid_path every frame?

If so then that is gonna eat CPU for sure.

As I said earlier, only do that every so often. About every half a second should be frequent enough.

There is really zero reason to be computing a path for every enemy every frame.
 

Dr_Nomz

Member
Okay, but what about the path_start code? Am I good to leave the script as is only using it every few frames, or do I need to have that one running every frame? (Just asking in case of glitches)

EDIT: I just tried to put a timer on my code and it just froze the zombie. I think it needs to have the planner constantly knowing where the player is or it just stops. Unless you guys can figure it out, of course.
 
Last edited:

Dr_Nomz

Member
Here's the tutorial I used if anyone's interested:

Also this is that script I mentioned earlier:
Code:
///scr_NPC_Path(target_x,target_y)
target_x = argument0;
target_y = argument1;

mp_grid_path(grid,path,x,y,target_x,target_y,true);
path_start(path,100,path_action_stop,false);
So basically what I need to do is stop it from running all that code at once every single frame, while still having my zombie moving. Any ideas?
 
Top