Legacy GM Malfunctioning Enemy AI within Finite State Machine


I'm working on a textbook game featured in The Game Maker's Apprentice called Pyramid Panic and currently around the mid-point to completion. Pyramid Panic is a maze game that has you controlling an explorer trapped inside a pyramid in search of a way out all while collecting treasures, navigating traps, and avoiding enemies like beetles, scorpions, and mummies. Now currently, I've encountered a problem when I was setting up the AI for the mummies. Following the instructions, I gave the mummy enemy 3 states via the finite state machine method: wander, search, and chase. I'm trying to get the mummy to slowly move around the maze in the wander state, enter the search state when the explorer is close by, chase the explorer when he is visible, go back to the search state when the explorer becomes hidden, and finally back to the wander state when the explorer is far away. Overall, it was supposed to go like this:

Pyramid Panic mummy finite state diagram stage 1.png

As it stands, I have the mummy objects, 3 of which represent the states, structured like this:

I have two scripts called scr_behavior_walk:

var ahead, left, right;
if (!place_snapped(32, 32)) exit;
if (vspeed == 0)
    ahead = place_free(x+hspeed, y);
    left = place_free(x, y+4);
    right = place_free(x, y-4);
    if (!ahead && !left && !right) {direction += 180; exit;}
    while (true) // Forever
        if (ahead && random(3)<1) {exit;}
        if (left && random(3)<1) {direction = 270; exit;}
        if (right && random(3)<1) {direction = 90; exit;}
    ahead = place_free(x, y+vspeed);
    left = place_free(x+4, y);
    right = place_free(x-4, y);
    if (!ahead && !left && !right) {vspeed = -vspeed; exit;}
    while (true) // Forever
        if (ahead && random(3)<1) {exit;}
        if (left && random(3)<1) {direction = 0; exit;}
        if (right && random(3)<1) {direction = 180; exit;}
and scr_behavior_towards:

if (!place_snapped(32, 32)) exit;
//Find out in which direction the explorer is located
var dir;
dir = point_direction(x, y, obj_explorer.x, obj_explorer.y);
dir = round(dir/90);
if (dir == 4) dir = 0;
//The four rules that move the mummy in the explorer's 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(x, y+4))
    { direction = 270; exit; }
//Otherwise do the normal walking behavior
I have obj_mummy with the the Create event that has it move downward at the speed of 4 via the Move Fixed action and the End Step event that execute this following code:

image_speed = 1/3;
if (hspeed < 0) sprite_index = spr_mummy_left;
if (hspeed > 0) sprite_index = spr_mummy_right;
if (vspeed < 0) sprite_index = spr_mummy_up;
if (vspeed > 0) sprite_index = spr_mummy_down;
Then, I created 3 mummy objects representing the 3 states and parented then to obj_mummy. Appropriately, they are called obj_mummy_wander, obj_mummy_search, and obj_mummy_chase.

For the obj_mummy_wander, I set the Step event to execute scr_behavior_walk and the Begin Step event to execute this code:

speed = 1; //Wandering mummies go slowly
if (point_distance(x, y, obj_explorer.x, obj_explorer.y) < 200)
    if (!place_snapped(2, 2)) exit;
    instance_change(obj_mummy_search, false);
For the obj_mummy_search, I set up the Step event to perform the following list of actions:

Pyramid Panic obj_mummy_search Create Event.png
And then set up its Begin Step event to execute this block of code:

speed = 2;
if (!collision_line(x+16, y+16, obj_explorer.x+16, obj_explorer.y+16, obj_Wall1, false, false))
    if (!place_snapped(4, 4)) exit;
    instance_change(obj_mummy_chase, false);
if (point_distance(x, y, obj_explorer.x, obj_explorer.y) > 200)
    instance_change(obj_mummy_wander, false);
For the obj_mummy_chase, I set up its Step event to execute scr_behavior_towards and its Begin Step event to execute this code:

speed = 4; //Chasing mummies really shift
if (collision_line(x+16, y+16, obj_explorer.x+16, obj_explorer.y+16, obj_Wall1, false, false))
    instance_change(obj_mummy_search, false);
While all this would work with Game Maker 8 aka the Legacy edition (I played one of the old builds featured on the disk that comes with The Game Maker's Apprentice just to make absolutely sure), this is not working the way it should with GameMaker: Studio. The mummy's wander state works fine. But the real problem becomes apparent whenever I move the explorer close to the mummy even with wall objects between them. Whenever I get close to a mummy, the mummy would just move in one direction and phase through walls, something that it should not be doing. In fact, the mummy was not actually chasing the explorer at all when close. When I move the explorer away from the mummy, it resumes its wandering movement through the maze without passing through walls. Obviously, something is obsolete in one of the two scripts or the code in the Begin Step events of all 3 mummy objects. I don't think the problem is being caused by parenting them to the original obj_mummy. But what could be causing the mummies to behave erratically when the explorer gets close to them whether or not there are walls between them?

Danny dos Santos

I have encountered the exact same problem. I started making this game in the free version of GM7. As I am about to finish the game I figure that the sword can not be included as the blending functions are not included in the free version (I also had to make extra sprites for the mummies because of the change sprite color function not being included.) So I started programming this game in GM Studio with only the nessesary objects to install this function (incl. the change sprite color function) and here I find out that the searching mummies aren't performing there actions properly. I see them mostly walking straight forward and going through walls, then returning to wandering again. Sometimes they change back to wandering when they get out of range but never change to chasing. It's mostly going straight forward until they hit the room barrier.

The blending function is working great though. And the mummy_afraid state is also no problem.

I also figured that I have to turn off the new sound engine to be able to use the sound_play() code.

This was not mentioned in the book (Dutch version) so I think that the writers haven't tested this out properly.

I think the problem lies somewhere in the scr_behavior_towards or the line with the !collision_line(...) code. I get no errors in the scripts. maybe some parameters within this code changed or became obsolete.