• 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!

GML AI pathfinding and sudden reaction to world objects

M

Monster25

Guest
Hey, I have a problem regarding enemy pathfinding and how I can make them react to sudden doors closing and things like that.

In my game I have pathfinding for enemies using an mp_grid and mp_grid_path.
It is simple, I create the grid at the start of the room and I modify it if there are any door openings, walls removed and things like that, it has no bugs and works amazingly, but... here's how my enemies work:

They use 2 states with a state machine, idle and roaming.
Heres the idle state:
-----
if (state_new)
{

dir = irandom_range(0,360); //Switch to a random direction when idle
patrol_x1 = x; //1st patrol coord X
patrol_y1 = y; //1st patrol coord y
patrol_x2 = irandom_range(1,room_width/obj_grid.cell_width); //2nd patrol coord X
patrol_y2 = irandom_range(1,room_height/obj_grid.cell_height); //2nd patrol coord Y
scr_find_free_place(); //Script to find a free space in the grid
alarm[0] = 3*room_speed; //Idle alarm to switch to Roam 3 seconds
}
------
Heres the roaming state:
------
if (state_new)
{
path_end(); //End any previous paths
if (mp_grid_path(global.grid,path,x,y,patrol_x2*obj_grid.cell_width-obj_grid.cell_width/2,patrol_y2*obj_grid.cell_height-obj_grid.cell_height/2,1)) //If you find suitable path
{
dir = point_direction(x,y,patrol_x2*obj_grid.cell_width-obj_grid.cell_width/2,patrol_y2*obj_grid.cell_height-obj_grid.cell_height/2) //Switch direction to it
path_start(path, spd, path_action_stop, true); //Start path
}
}

if (path_index == -1) //If path ends
state_switch("Idle"); //Switch to Idle
-------


While they are idle they set themselves a random end patrol coordinate in the room and an initial patrol point (the object's coordinate). If that coordinate's grid cell is occupied it uses a while loop inside a script to search for a new viable random coordinate to reach. Heres the code of the script:

///Find a free space in the npc grid
while(!mp_grid_path(global.grid, path, x, y, patrol_x2*obj_grid.cell_width-obj_grid.cell_width/2, patrol_y2*obj_grid.cell_height-obj_grid.cell_height/2,1)) //While theres a path and a collision with solid objects
{

patrol_x2 = irandom_range(1,room_width/obj_grid.cell_width); //Keep shuffling the 2nd patrol coords
patrol_y2 = irandom_range(1,room_height/obj_grid.cell_height); //Keep shuffling the 2nd patrol coords
}

Basically it will always find a free space and if it doesn't it goes in a infinite loop, crashing the game.

Thing is, I also have doors that open in the game and I do not know how to incorporate that into their pathfinding.

For example, currently I only give them a path to follow at the start of the roaming state and never check the path again, this however lets them go through a door if the path is already started.

If I make them check the path every step of the way, if they somehow end up in an occupied grid zone, then the script that finds them a new free cell enters the infinite loop and crashes the game because mp_grid_path thinks its stuck.

TL;DR
I need a solution for having roaming enemies using mp_grid functions and also at the same time having them react to sudden things such as doors closing in front of their path and them finding a path around it or simply doing something else if that happens. I also need them not to crash the game if they suddenly get stuck somewhere for example if a door closes right on top of them. (would prefer them to slide away from the stuck point to the nearest free cell)
 
M

Monster25

Guest
Been thinking, if I can atleast ignore the AI's initial position if that position is occupied I can atleast avoid the crashing part...
 
W

Wraithious

Guest
What you could try is have a variable that is true when you can follow the path, and when something happens to pause the path immediatly put the objects x and y positions in either an array or 2 variables and then set the true/false variable to false, now you can do your other stuff and when done use move_towards_point(savedX,savedY) and then if distance_to_point(savedX,savedY) <= speed set your true false variable back to true and your object will continue on it's path.
 
Top