Phantom Slayer’s spooks get a shot of smarts

Phantom Slayer, the 1982 computer game I’ve restored on the Raspberry Pi Pico, has been updated to version 1.0.1 to give the titular spectres some extra smarts as they navigate the game maze in pursuit of the player.

Phantom Slayer's (slightly) smarter spooks
The Phantoms: certainly smarter — also more scary?

In the first release the Phantoms were moved around the game ‘board’ with a straightforward aim-for-the-player algorithm. All well and good, and widely used in everything from Pac-Man to Panic. But in mazes like Phantom Slayer’s they had a tendency to get caught. That’s fine if the player moves about plenty, but not when you pause for breath. Where’s the tension when there’s a chance the Phantoms won‘t get any closer?

Enter an updated algorithm which gives them a way out and keeps them on the move. Now the code matches where a Phantom wants to go against where it can go. Directions are stored as single-bit values: 1 for North, 2 for East, 4 for South and 8 for North. Add those together to express all of the available directions as a single integer. Do the same for the ways the Phantom wants to go. AND the two values and you’ve got a the directions the Phantom may take. If there’s only one direction, the choice is obvious; if there are two, pick one randomly — each is as good as the other. Because we always vector toward the player on two axes, there can’t be a third way.

The chosen direction might be a step toward the player, or it might not. The Phantom might get caught in a simple dead end, or in a corridor bend with an apex pointing toward the player, which keeps it trying to reach the player through a wall it just can’t penetrate.

Before the Phantom stayed where it was until the player moved so the vector changed. Now if it can’t move, the Phantom heads away in a different, randomly selected direction instead. That can leave it just as liable to get trapped, so as soon as it reaches a three- or four-way junction, it turns toward the player again. To prevent it just moving straight back to the dead end, it always rejects going back the way it came.

There’s still a chance it might not be able to move toward the player, of course. In that case the code picks a direction at random. It’s not just walls that can stop a Phantom, so can other Phantoms.

The upshot is a more satisfying play where pausing for breath isn’t guaranteed to let you stay safe until you start moving again. I testing the approach out using a top-down view of the game rather than the standard 3D view — just enable the map_mode variable in the function init_game() if you’d like to try it — and it was clear the Phantoms were now taking more interesting routes through the maze.

It’s not AI, of course, and not intended to be. But it was an interesting challenge to figure out a way to get the Phantoms moving without giving them privileged access to the map data.

The updated Phantom Slayer, version 1.0.1, is available over at my Pi Pico projects GitHub repo.