Envision, Create, Share

Welcome to HBGames, a leading amateur game development forum and Discord server. All are welcome, and amongst our ranks you will find experts in their field from all aspects of video game design and development.

AI with GML

I've gotten into GML ( Game Maker Language ) thanks to the game makers apprentice and some useful youtube videos and decided to make a complete game with nothing but GML.

I'm doing well apart from the enemy AI. It works for the most part apart from a few bugs that really hurt the gameplay.
I ripped and edited the code from the game makers aprentice, if you have it, it was on the pyramid maze game ( the last game
in GML ).

Here is the script. its in three parts, I'll explain...

Enemy AI : Acts as a control script that controls the behavior of the Enemy depending on the
visibility of the player. If the player is visible then it goes to the AlertAI script, otherwise it
goes to the MovementAI script, or it goes to the AlertAI to look for the player.

{
if ( !place_snapped(8,8) ) { exit; }
// Calculate distance and visibility
var dist, vis;

dist = point_distance(x,y,player.x,player.y);
vis = !collision_line(x+16,y+16,player.x+16,player.y+16,wall,false,false);

//Executes the rush on order

if ( vis ) { AlertAI(); exit; }
if ( dist>300 ) { MovementAI(); exit; }
if ( random(2)>1 ) { AlertAI(); exit; }
MovementAI();
}

Alert AI : This is the script that makes the enemy follow / chase the player if they are visible
{
if ( !place_snapped(8,8) ) { exit; }
// find out in which location the player is located

var dir;
dir = point_direction(x,y,player.x,player.y);
dir = round(dir/90);
if ( dir == 4 ) dir = 4;
// the 4 rules that move the enemy in players direction
if ( dir == 0 && direction != 180 && place_free(x+4,y))
{ direction = 0; exit;}
if ( dir == 1 && direction != 270 && place_free(x,y-4))
{ direction = 90; exit;}
if ( dir == 2 && direction != 0 && place_free(x-4,y))
{ direction = 180; exit;}
if ( dir == 3 && direction != 90 && place_free(4,y+4))
{ direction = 270; exit;}
// otherwise do the normal walking behavior
MovementAI();
}

MovementAI : general movement script so the enemy can maneuver around walls and obstacles without
getting stuck in a dead end.

{
var go_ahead, go_left, go_right;

if ( !place_snapped(8,8) ) { exit; }
if ( vspeed == 0 )
{
go_ahead = place_free(x+hspeed,y);
go_left = place_free(x,y+4);
go_right = place_free(x,y-4);
if ( !go_ahead && !go_left && !go_right ) { direction +=180; exit; }
while (true) //forever
{
if ( go_ahead && random(3)<1) {exit;}
if ( go_left && random(3)<1) {direction = 270; exit;}
if ( go_right && random(3)<1) {direction = 90; exit;}
}
}
else
{
go_ahead = place_free(x,y+vspeed);
go_left = place_free(x+4,y);
go_right = place_free(x-4,y);
if ( !go_ahead && !go_left && !go_right ) {vspeed = -vspeed; exit;}
while (true) //forever
{
if ( go_ahead && random(3)<1) {exit;}
if ( go_left && random(3)<1) {direction = 0; exit;}
if ( go_right && random(3)<1) {direction = 180; exit;}
}
}
}

Random Direction: This sets the enemy to move to any random direction during a collision with a wall
or obstacle.

var set_range;
set_range = choose(0,90,180,270);
// set_range limits direction to only straigth directions
{
motion_set(set_range,2);
exit;
}

The MovementAI script when set to run when the enemy collides with a wall results in them getting stuck at some
point moving forward.

The enemy chases the player for some time and then gets stuck moving in one direction untill a collision with a wall
or some instance.

The enemy can manover through a maze and walls when the enemy AI is set to run during a collision however they
get stuck again during unusual turns

Also if anyone has any advice on programming enemy AI, some tutorials ( preferably for Game Maker 8 ) or anything that might come of use It would be appreciated if you could post a link or reference.

Also ask if you want to take a look at the game and help me debug the AI and I'll send it to you in a PM.

Thanks.
 
I fixed it.

The gm-aprentice code was biased to the game, I re-write some of it ( just basically the MovementAI and added
comments to the EnemyAI and MovementAI )

The scripts now work as a basic AI system where the enemy chases you if you are visible, if not in continues to move around
walls e.t.c until it sees you.

Enemy AI
{
if ( !place_snapped(8,8) ) { exit; }
// Calculate distance and visibility
var dist, vis;

dist = point_distance(x,y,player.x,player.y);
vis = !collision_line(x+16,y+16,player.x+16,player.y+16,wall,false,false);

//Executes the rush on order

//if player is visible then go to AlertAI
if ( vis ) { AlertAI(); exit; }
//if distance is greater than 300 the go to movement AI
if ( dist>300 ) {
MovementAI();
exit;
}
//out of these two choices on choose to go to Alert AI
//( for 1 out of 2 choices )
if ( random(2)>1 ) { AlertAI(); exit; }
//if none of these conditions are met then go to Movement AI
MovementAI();
}

AlertAI
{
if ( !place_snapped(8,8) ) { exit; }
// find out in which location the player is located
var dir;
dir = point_direction(x,y,player.x,player.y);
dir = round(dir/90);
if ( dir == 4 ) dir = 4;
// the 4 rules that move the enemy in players direction
if ( dir == 0 && direction != 180 && place_free(x+4,y))
{ direction = 0; exit;}
if ( dir == 1 && direction != 270 && place_free(x,y-4))
{ direction = 90; exit;}
if ( dir == 2 && direction != 0 && place_free(x-4,y))
{ direction = 180; exit;}
if ( dir == 3 && direction != 90 && place_free(4,y+4))
{ direction = 270; exit;}
// otherwise do the normal walking behavior
MovementAI();
}

MovementAI
{
//declare variables to act as decisions for AI to go ahead, left or right
var go_ahead, go_left, go_right, go_down;

if ( !place_snapped(8,8) ) { exit; }

if ( vspeed == 0 )
{


/* checks if place is free from current position + variable number in enemy's speed if that direction */
//set variables to their direction if the place of direction is empty
go_ahead = place_free(x,y+vspeed);
go_left = place_free(x+hspeed,y);
go_right = place_free(x-hspeed,y);
go_down = place_free(x-hspeed,y);

/* CHOICE IS MADE */
// if place is blocked ahead and left and right and down, set direction to turn left
//then exit if place is free
if ( !go_ahead && !go_left && !go_right && !go_down ) { direction +=180; exit; }
while (true) //loop forever untill place is free
{
//if enemy can go ahead once out of the 4 choices
//exit
if ( go_ahead && random(4)<1) {
RandomDirection();
exit;
}
//if enemy can go left once out of the 4 choices
//go to script RandomDirection
//exit this script ( RandomDirection returns to this script )
if ( go_left && random(4)<1) {
RandomDirection();
exit;
}
//if enemy can go down once out of the 4 choices
//go to script RandomDirection
//exit this script ( RandomDirection returns to this script )
if ( go_right && random(4)<1) {
RandomDirection();
exit;
}
//if enemy can go down once out of the 4 choices
//go to script RandomDirection
//exit this script ( RandomDirection script returns to this script )
if ( go_right && random(4)<1) {
RandomDirection();
exit;
}
}
}
else
{
go_ahead = place_free(x,y+vspeed);
go_left = place_free(x+hspeed,y);
go_right = place_free(x-hspeed,y);
go_down = place_free(x-hspeed,y);
//if the place is blocked ahead and left and right and down
//run RandomDirection script and exit
//RandomDirection script returns to this script
if ( !go_ahead && !go_left && !go_right && !go_down ) {
RandomDirection();
exit;
}
while (true) //forever
{
//if place direction is free
//the enemy continues to move in the same direction
//once in every 2 chances
if ( go_ahead && random(2)<1) {direction = 90; exit;}
if ( go_left && random(2)<1) {direction = 180; exit;}
if ( go_right && random(2)<1) {direction = 0; exit;}
if ( go_down && random(2)<1) {direction = 270; exit;}
}
}
}

RandomDirection
var set_range;
set_range = choose(0,90,180,270);
// set_range limits direction to only straigth directions
//make a random choice out of the 4 available directions
{
direction = set_range;
//set direction then return to the MovementAI
MovementAI()
exit;
}

How to Install:
You need Game Maker 8 Pro because thats what I use,

Create an enemy object,

Create a Create Event
Add an execute script command
Execute Script: RandomDirection

you will also need to set the speed manually
this can be done by adding an Execute a peice of code event to the Create Event, in this code write:

{
speed = x;
}

where x is any number you want to set for the speed ( I recommend something like 3 or 4 )

Create a Step Event,
Add an execute script command
Execute Script: EnemyAI

on collision with wall objects

Create a Collision Event,
Add an execute script command
Execute Script: RandomDirection

Execute a peice of a code
in it write

{
wall = obj_wall;
//obj_wall is the name of your wall object
//this is for the enemy to react to this specific wall object on collision
}


The script has variables, you can initialize these variables using this code, I recomend you put this in a script
and execute it during the create event of the player and enemy.

Global
{
globalvar player, wall;
//These variables will be used globaly and make coding easier
}

Hope this comes in handy for someone, if your stuck you can PM me.

Enemy Artificial Intelligence is basically a set of rules that the enemy should do in case of an event ( usually an event relating to
the player )
 

Thank you for viewing

HBGames is a leading amateur video game development forum and Discord server open to all ability levels. Feel free to have a nosey around!

Discord

Join our growing and active Discord server to discuss all aspects of game making in a relaxed environment. Join Us

Content

  • Our Games
  • Games in Development
  • Emoji by Twemoji.
    Top