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

smarter enemy

RODO

Member
hello guys, I came to ask for help with a code, how I could get the result I want.

I'm trying to make an enemy who can walk the map but, he recognizes obstacles along the way and try to "dodge" or go the other way. I tried to use collision_line or point_distance to see if I could but without result (with collision_line I even had a bit of success but he was still hitting the front)

the code below for better understanding:

GML:
switch(state_inimigo_2)

{

    case "parado": 

    troca_estado--;

    Hspeed = 0;

    Vspeed = 0;



    if(troca_estado <= 0)

    {

        state_inimigo_2 = "patrulha";     // here's where it changes state

        show_debug_message(state_inimigo_2)

        troca_estado = room_speed/2;

        pos_x = irandom(room_width);

        pos_y = irandom(room_height);

        move = point_direction(x,y,pos_x,pos_y);  // and this here defines a random direction that he can walk around the map   

    }

    break;



    case "patrulha":

    troca_estado--;

    Hspeed += lengthdir_x(0.04,move);

    Vspeed += lengthdir_y(0.04,move);



    if(point_distance(x,y,obj_solido.x,obj_solido.y) < 110) //in this part, I tried to make sure that when he got close to the wall, he would change the direction to an opposite path  
    }                                                                                
                                                                             
        Hspeed += lengthdir_x(0.04,-move);

        Vspeed += lengthdir_y(0.04,-move);

    }



    if(troca_estado <= 0)

    {

        state_inimigo_2 = "parado"

        show_debug_message(state_inimigo_2)

        troca_estado = room_speed/2; 

    }
    break;
}
I hope it was clear, anything, you can ask a question that I will try to explain better
if you can help me I thank you very much
 

Joe Ellis

Member
This is quite a deep subject, like whole universities have theories on it and stuff (probably). It's kind of like english or language study, there's no clear right or wrong answer, but a lot to think about and decide what is best for your\what situation.

I think using collision_line, from itself to a random position is a good idea, using lengthdir_xy with length within a certain range (say 100 to 300 pixels, depending on the scale of your game), and if the enemy can see the player, then make the random angle be (angle to player + random_range(-45, 45)) or some kind of range where it will be walking mostly towards the player (or definitely more towards it than away from it). Also collision_line can be used to check whether the enemy can see the player or not, and if it can't it could just stand there and wait, or wander randomly, like the same process just aiming in any direction, but maybe set a "last seen player position" and make it venture towards that and maybe find the player.
From what I've gathered this is pretty much how the ai early fps games worked like doom, quake, wolfenstein, which had the best\most complicated ai in those days, like platformer games and stuff didn't have any of this kind of stuff. Games later on, say in 1999 onwards started using pathfinding, navpoints etc. which made enemies' decisions seem more intelligent. So you could look into that, it depends what your game is like I suppose. I think for a fast paced shoot em up style game, the basic ai I was talking about should be fine, enemies are supposed to be stupid after all, and it's fun blowing them up when they're dumb pieces of ****.
 

rytan451

Member
For pathfinding, I recommend taking a look at built-in mp_grid functions. They give you access to a native implementation of the A* pathfinding algorithm, which is a pretty fast pathfinding algorithm. If you want to be fancy, you can also implement your own A* algorithm, and stop the object when you reach certain conditions (such as "within range of the player" or "has line of sight of the player").

I don't actually recommend having all the enemies pathfind towards the player. If they do, then the player need only stand in a defensible position and kill the enemies coming towards them. Instead, give a few types and states. A guard enemy might be in a patrol state (patrolling a given route), and enter a chase state (pathfind towards player) if it sees the player. A dog enemy might be in the "follow handler" state (following a nearby enemy) until it "smells" the player, then enters the chase state. A sentry enemy might stay in the "guard position" state, and never go beyond a certain radius of their start position. And the "chase state" most enemies (except dogs) might end if they can't find the player (dogs have a good sense of smell and keep running after the player even if they can't see them, and the dogs might be followed by other guards).

If you want a few tricks, I also recommend looking up the pacman ghost enemies.
 

RODO

Member
For pathfinding, I recommend taking a look at built-in mp_grid functions. They give you access to a native implementation of the A* pathfinding algorithm, which is a pretty fast pathfinding algorithm. If you want to be fancy, you can also implement your own A* algorithm, and stop the object when you reach certain conditions (such as "within range of the player" or "has line of sight of the player").

I don't actually recommend having all the enemies pathfind towards the player. If they do, then the player need only stand in a defensible position and kill the enemies coming towards them. Instead, give a few types and states. A guard enemy might be in a patrol state (patrolling a given route), and enter a chase state (pathfind towards player) if it sees the player. A dog enemy might be in the "follow handler" state (following a nearby enemy) until it "smells" the player, then enters the chase state. A sentry enemy might stay in the "guard position" state, and never go beyond a certain radius of their start position. And the "chase state" most enemies (except dogs) might end if they can't find the player (dogs have a good sense of smell and keep running after the player even if they can't see them, and the dogs might be followed by other guards).

If you want a few tricks, I also recommend looking up the pacman ghost enemies.
This is quite a deep subject, like whole universities have theories on it and stuff (probably). It's kind of like english or language study, there's no clear right or wrong answer, but a lot to think about and decide what is best for your\what situation.

I think using collision_line, from itself to a random position is a good idea, using lengthdir_xy with length within a certain range (say 100 to 300 pixels, depending on the scale of your game), and if the enemy can see the player, then make the random angle be (angle to player + random_range(-45, 45)) or some kind of range where it will be walking mostly towards the player (or definitely more towards it than away from it). Also collision_line can be used to check whether the enemy can see the player or not, and if it can't it could just stand there and wait, or wander randomly, like the same process just aiming in any direction, but maybe set a "last seen player position" and make it venture towards that and maybe find the player.
From what I've gathered this is pretty much how the ai early fps games worked like doom, quake, wolfenstein, which had the best\most complicated ai in those days, like platformer games and stuff didn't have any of this kind of stuff. Games later on, say in 1999 onwards started using pathfinding, navpoints etc. which made enemies' decisions seem more intelligent. So you could look into that, it depends what your game is like I suppose. I think for a fast paced shoot em up style game, the basic ai I was talking about should be fine, enemies are supposed to be stupid after all, and it's fun blowing them up when they're dumb pieces of ****.
thank you very much for the answers, they were great. I thought that AI and building them was something simple and I, a beginner, didn’t know how to do it or that I needed a little more reading in the GML documents, I’m very grateful and I’ll try to do something nice with what happened to me
 
I thought that AI and building them was something simple and I, a beginner, didn’t know how to do it
A.I. is arguably one of the hardest thing to nail down. Like @Joe Ellis said, there's tons of books on that subject alone. You are on the right path, tho, a Finite State Machine like that is usually the basis of every AI. In a very compleex one, you could have switc within switch with sub-states, and things like that...this has no potential end.
Just take it in small bites, and use toy projects to test stuff in a simple context for proof of concept. Once you nail things like line of sight, awareness of [fake] noise, obstacle avoidance, etc. separately in small projects, it'll be much easier to see how to do it all in a real-life session. You can also try to make it as simple as possible and try to handle the edge cases separately, that may simplify your functions a bit.
But yeah...if Sid Meier struggled with it, imagine what us mere mortals have to endure to make a convincing AI...not easy at all!
 

Yal

🐧 *penguin noises*
GMC Elder
Pathfinding is a vital part of AI, but you need to figure out where to pathfind as well. Enemies always moving directly towards the player is highly abusable, even a very early game like Pac-Man had separate pathfinding logic for all four ghosts to prevent the game from becoming trivialized (once you have all enemies in a conga line, you can't get surrounded anymore, so you just need to keep moving and picking them off one by one and you will be safe). So you probably want to have an AI logic with some of these quirks:
  • Enemies try to approach the player from different directions.
    • One easy way to do this is to first pathfind to a random point near the player, then pathfind towards the player once you reach it.
  • Enemies change their approach randomly with set intervals so the player can't trap them in an "infinite approach" loop
  • Enemies with long-range attacks prioritize staying on the further chunk of that range, including moving away from the player if they're too close.
  • Enemies that can't pathfind to the player but are being attacked by them try to find a spot where they are in cover
  • Enemies might have set patrol zones that they move around through autonomously when not chasing down a player, and try to stay within those zones if the player moves too far away (this removes exploits where you can lure away enemies on a wild goose chase to leave something they were guarded undefended, and luring enemies to a chokepoint where it's easy to cheese-kill them)
 

RODO

Member
A.I. is arguably one of the hardest thing to nail down. Like @Joe Ellis said, there's tons of books on that subject alone. You are on the right path, tho, a Finite State Machine like that is usually the basis of every AI. In a very compleex one, you could have switc within switch with sub-states, and things like that...this has no potential end.
Just take it in small bites, and use toy projects to test stuff in a simple context for proof of concept. Once you nail things like line of sight, awareness of [fake] noise, obstacle avoidance, etc. separately in small projects, it'll be much easier to see how to do it all in a real-life session. You can also try to make it as simple as possible and try to handle the edge cases separately, that may simplify your functions a bit.
But yeah...if Sid Meier struggled with it, imagine what us mere mortals have to endure to make a convincing AI...not easy at all!
wow, thank you very much for the information. Honestly I ended up running away from it because I really couldn't do it and I prefer to change it later (in the end, I implemented another mechanic for this enemy from my top-down game that was much more interesting than I had before), messing with some things difficulties for a long time end up stressing me and in the end it takes me a long time to understand, and apparently we are talking about a subject that is very advanced for me who is a beginner. I will try to address these tips to try to learn better about I.A

Pathfinding is a vital part of AI, but you need to figure out where to pathfind as well. Enemies always moving directly towards the player is highly abusable, even a very early game like Pac-Man had separate pathfinding logic for all four ghosts to prevent the game from becoming trivialized (once you have all enemies in a conga line, you can't get surrounded anymore, so you just need to keep moving and picking them off one by one and you will be safe). So you probably want to have an AI logic with some of these quirks:
  • Enemies try to approach the player from different directions.
    • One easy way to do this is to first pathfind to a random point near the player, then pathfind towards the player once you reach it.
  • Enemies change their approach randomly with set intervals so the player can't trap them in an "infinite approach" loop
  • Enemies with long-range attacks prioritize staying on the further chunk of that range, including moving away from the player if they're too close.
  • Enemies that can't pathfind to the player but are being attacked by them try to find a spot where they are in cover
  • Enemies might have set patrol zones that they move around through autonomously when not chasing down a player, and try to stay within those zones if the player moves too far away (this removes exploits where you can lure away enemies on a wild goose chase to leave something they were guarded undefended, and luring enemies to a chokepoint where it's easy to cheese-kill them)
thank you very much for the ideas, I really thought of something like him trying to walk around my map that is totally randomly generated, until he bumps into the player and starts trying to annihilate it, I will keep these tips in mind and implement in the future, thank you very much
 
Top