Enemy targeting
How an enemy chooses where to go, such as steering toward a target point the game computes for it.
On this page
Enemy targeting is how an enemy picks where to go. In Pac-Man each ghost has its own target tile, set from Pac-Man’s tile, his direction, and in Inky’s case Blinky’s tile1. At each step the ghost takes the open direction closest to its target and never reverses on its own2. Scatter phases send the ghosts to fixed tiles instead3.
Games
| Game | Year | How | Note |
|---|---|---|---|
| Pac-Man | 1980 | Target tile | each ghost steers toward its own target tile, picking the move that brings it closest |
Every claim about this mechanic, by game (7)
References
- ^ abIn chase mode each Pac-Man ghost steers toward its own target tile. Blinky targets Pac-Man's tile. Pinky targets Pac-Man's tile plus 4 times his direction vector, and Inky takes Pac-Man's tile plus twice the vector, doubles it, and subtracts Blinky's tile. The Z80 does both sums as 16-bit adds of a packed two-byte tile and vector (
add hl,hl,add hl,de), so a carry out of the low byte's axis spills into the other axis; away from such a carry, Pinky's target is 4 tiles ahead of Pac-Man and Inky's starts 2 ahead. Clyde targets Pac-Man's tile while the squared distance between them is 64 or more, that is 8 tiles or farther, and otherwise heads for his scatter corner. The translation reads MAME'spacmanset, Midway's release.Codemburkley/pacman-crevisedHow we know
11479 BLINKY_VECTOR2 = findBestOrientation_2966 (BLINKY_TILE, PACMAN_TILE2, &BLINKY_ORIENTATION);pacman.c line 11479 at 3277e56 · upstream ↗ 11525 /* Make a target tile for pinky that is 4 times pacman's current direction 11526 * of travel plus pacman's current tile */ ⋮ 11539 PINKY_VECTOR2 = findBestOrientation_2966 (PINKY_TILE, target, &PINKY_ORIENTATION);
pacman.c lines 11516–11539 at 3277e56 · upstream ↗ 11584 /* Inky tries to get pacman in a pincer movement with blinky so he targets 11585 * a tile that is 2 tiles ahead of pacman's current vector and then twice 11586 * the vector between that tile and blinky's tile */ ⋮ 11597 target.y = target.y * 2 - BLINKY_TILE.y; ⋮ 11605 target.x = target.x * 2 - BLINKY_TILE.x;
pacman.c lines 11576–11617 at 3277e56 · upstream ↗ 11637 random: ⋮ 11648 XYPOS target = { 0x40, 0x3b }; ⋮ 11661 uint16_t dist = computeDistance_29ea (PACMAN_TILE2, CLYDE_TILE); ⋮ 11669 if (dist < 0x40) 11670 goto random; ⋮ 11682 findBestOrientation_2966 (CLYDE_TILE, PACMAN_TILE2, &CLYDE_ORIENTATION);
pacman.c lines 11637–11682 at 3277e56 · upstream ↗ 12131uint16_t computeDistance_29ea(XYPOS ix, XYPOS iy) ⋮ 12139 int b = ix.y - iy.y; ⋮ 12152 uint16_t hl = calcSquare_2a12(b); ⋮ 12161 b = ix.x - iy.x; ⋮ 12178 hl += calcSquare_2a12(b);
pacman.c lines 12131–12178 at 3277e56 · upstream ↗ 20pacman.6e \ 21pacman.6f \ 22pacman.6h \ 23pacman.6j \
Makefile lines 20–23 at 3277e56 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-21.
Revised after a check by a second AI model, 2026-10-21.
- ^ ab
findBestOrientation_2966turns a target into a move: it tries the four directions in turn, skips the reverse of the ghost's current one and any that points into a maze wall, and keeps the one whose next tile has the smallest squared distance to the target; on a tie the later direction wins.Codemburkley/pacman-cHow we know
11993XYPOS findBestOrientation_2966 (XYPOS hl, XYPOS de, uint8_t *a) ⋮ 12008 OPPOSITE_ORIENTATION = *a ^ 2; ⋮ 12014 MIN_DISTANCE_FOUND = 0xffff; ⋮ 12032 if (OPPOSITE_ORIENTATION != TRIAL_ORIENTATION) ⋮ 12054 /* If the trial orientation points us at a maze wall then ⋮ 12067 uint16_t dist = computeDistance_29ea (DEST_TILE_POS, TMP_RESULT_POS); ⋮ 12079 if (MIN_DISTANCE_FOUND >= dist) ⋮ 12106 while (++TRIAL_ORIENTATION < 4);
pacman.c lines 11993–12106 at 3277e56 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-21.
Checked by a second AI model, 2026-10-21.
- ^ abA mode counter at
$4DC1runs from 0 to 7: on even values the ghosts head for fixed scatter tiles, on odd values they chase.ghostsChangeOrientation_0e36counts time and steps the counter when the count meets a 16-bit entry for the current mode, then flags all four ghosts to reverse. At 7 it stops, so the game holds four scatter phases and leaves the fourth chase phase on for good. The count pauses while Pac-Man is powered up.Codemburkley/pacman-cHow we know
4167void ghostsChangeOrientation_0e36 (void) ⋮ 4174 if (PACMAN_POWEREDUP) 4175 return; ⋮ 4182 if (NONRANDOM_MOVEMENT == 7) 4183 return; ⋮ 4191 ORIENTATION_CHANGE_COUNT++; ⋮ 4206 if (ORIENTATION_CHANGE_COUNT != DIFFICULTY_TABLE[NONRANDOM_MOVEMENT]) 4207 return; ⋮ 4214 NONRANDOM_MOVEMENT++; ⋮ 4222 BLINKY_ORIENT_CHG_FLAG = 4223 PINKY_ORIENT_CHG_FLAG = 4224 INKY_ORIENT_CHG_FLAG = ⋮
pacman.c lines 4167–4225 at 3277e56 · upstream ↗ 11434 if ((NONRANDOM_MOVEMENT & 1) == 0) ⋮ 11460 XYPOS target = { 0x1d, 0x22 }; 11461 BLINKY_VECTOR2 = ⋮ 11479 BLINKY_VECTOR2 = findBestOrientation_2966 (BLINKY_TILE, PACMAN_TILE2, &BLINKY_ORIENTATION);
pacman.c lines 11434–11479 at 3277e56 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-21.
Checked by a second AI model, 2026-10-21.
Sources
Code
- Burkley, Mark. 2025. “pacman-c: a C translation of the Pac-Man ROM.” Commit 3277e56. mburkley/pacman-c @ 3277e56 · licence, all uses