Quick answer: Set path_endaction to path_action_stop, clamp path_position to 1.0 each frame, and handle arrival in the Path Ended event. The overshoot happens because the per-frame position increment is larger than the remaining distance to 1.0.
You set an enemy to follow a patrol path. It walks smoothly along the waypoints, reaches the last one, and then teleports 20 pixels past it before snapping back. Or it loops when it should stop. Or it freezes at 99% of the path and never quite arrives. All three bugs come from the same place: the relationship between path_speed and path_position at the endpoint.
How Path Position Works
path_position is a normalized value from 0.0 (start) to 1.0 (end). Each frame, GameMaker advances it by an amount proportional to path_speed / path_length. A 200-pixel path at speed 4 advances by 4/200 = 0.02 per frame, reaching 1.0 in exactly 50 frames.
But if the remaining distance is 0.015 and the increment is 0.02, the position goes to 1.005 — past the end. What happens next depends on path_endaction.
The Fix
Step 1: Use path_action_stop.
// Create event
path_start(pth_patrol, 3, path_action_stop, true);
// Speed 3, stop at end, absolute position
path_action_stop halts the instance at position 1.0 and fires the Path Ended event. It is the safest option for one-shot movement like a patrol leg, a cutscene camera move, or a projectile arc.
Step 2: Clamp in the Step event.
// Step event - belt and braces
if (path_position >= 1.0) {
path_position = 1.0;
path_speed = 0;
// Arrival logic here, or handle in Path Ended event
}
Step 3: Handle arrival in Path Ended.
// Path Ended event
if (state == "patrol_to_B") {
state = "wait_at_B";
alarm[0] = room_speed * 2; // wait 2 seconds
}
The Path Ended event fires exactly when the path finishes. It is the cleanest place to put arrival logic because you do not need to poll path_position in the Step event.
Closed vs. Open Paths
A closed path (loop) wraps path_position from 1.0 back to 0.0 automatically. An open path with path_action_continue keeps incrementing past 1.0, which moves the object in a straight line beyond the last waypoint. Use closed paths for patrol loops and open paths with path_action_stop for one-way trips.
Verifying the Fix
Draw path_position as text in the Draw GUI event. Walk the object along the path and watch the number climb to 1.0. It should stop at exactly 1.0 and never exceed it. If it flickers between 0.99 and 1.0, the speed increment is fighting the clamp — set path_speed = 0 on arrival.
“Path following in GameMaker is reliable once you understand that path_position is a fraction, not a pixel distance. Clamp it, stop it, and handle arrival in the event designed for that purpose.”
Related Issues
For instance variable resets on room change (which can reset path state), see GameMaker instance variables resetting on room change. For sprite animation during path movement, see GameMaker sprite_index wrong after state change.
Always use path_action_stop for one-shot paths. The other end actions are for specialized cases and will surprise you at the endpoint.