A retro 3D maze shooter coded in C for the Raspberry Pi Pico

Latest Release: 1.0.2


About Phantom Slayer

The original Phantom Slayer was created Ken Kalish for Med Systems. It was written in 6809 machine code for the Tandy Color Computer and was compatible with the Dragon 32 micro.

Phantom Slayer, Pi Pico-style

My version was inspired by Ken’s game. It offers the same look and feel — albeit in black and white rather than four colours — and gameplay. I have modified it for a smaller display — a 0.96in 128 x 64 OLED panel — even though the original’s horizontal resolution was also 128 pixels when played on a colour TV! It was also played with a Qwerty keyboard, but I’ve adapted it for joystick control and a couple of buttons.

You can read more about the background to this game in this blog post.

How to Play

You move through a 3D maze looking for the titular Phantoms — who are also looking for you. One touch and you’re dead, so don’t get too close. You fight back with the speed of your running and your laser. At the start, one shot will put down a Phantom — though another will appear somewhere else in the maze to take its place — and they move slowly. As the game progresses, the Phantoms get tougher and faster. Your end is inevitable — it’s just a question of how long you can last.

And there’s no running and gunning. To fire the laser, you have to stop moving. Press and hold the left-hand button to prime the laser and bring up the crosshair. Release the button to fire. Once fired, the laser takes two seconds to recharge. The Phantoms are canny — you can’t just sit and wait for them to wander into your sights.

Phantom Slayer the Phantom
Phantom Slayer aim
Phantom Slayer fire

Alongside the laser, you also possess a Phantom Detector. When they get close, it will signal their presence with a heartbeat. The Pico’s LED flashes too. The detector will pick up any Phantom within range: about four maze squares.

Early in the game, Phantoms can be dispatched with a single hit, but the longer you stay in the maze, the more resilient the Phantoms become. When you get one, you’ll be briefly shown the map. The game begins with one Phantom — when it’s killed two more immediately arrives to take its place, and then three. There are no more than three Phantoms in the maze at any one time, though.

When things get hairy, you can beam out — if you’ve found the maze’s single teleport square. Use it carefully — it can get out out of some tricky situations. But you’ll need to find it to use it. Every time you use it, it moves to another location.

Phantom Slayer the teleporter
Phantom Slayer the map
Phantom Slayer corridors

The joystick controls movement: push it forward or backward to step in that direction, or push it sideways to turn left or right.

The left-hand button triggers the laser: press to enable; release to fire.

The second button causes you to teleport, but only when you’re standing on the teleport square. Look for the grey floor tile.

The Game Hardware

Phantom Slayer game hardware

To build Phantom Slayer, you will need:

  • A Raspberry Pi Pico, or similar RP2040-based board.
  • An SSD1306-based OLED display with I²C support.
  • A two-way, self-centring analog joystick.
  • A piezo-electric buzzer.
  • Two buttons.
  • Two standard-size breadboards.
  • Wires.

Assemble the components in the following circuit:

The circuit layout for Phantom Slayer

The layout shown here is intentionally spaced out for clarity. Your own circuit can be condensed to fit on standard breadboards or a custom PCB.

Installing the Game

Either build the game from source, or copy the .uf2 file provided in the repo to the mounted Pico (press BOOTSEL and connect to USB).


My Phantom Slayer code is licensed under the MIT licence.

It also contains TinyMT, copyright © 2011 Mutsuo Saito, Makoto Matsumoto, Hiroshima University and The University of Tokyo. All rights reserved. Licensed under the three-clause BSD Licence.

Source Code

You can view Phantom Slayer’s source code at GitHub.

Release Notes

  • 1.0.2 6 April 2021
    • Added another map.
    • Function inkey() now returns key button pressed.
    • Moved some common routines into utils.h/utils.c.
  • 1.0.1 31 March 2021
    • Graphics tweaks.
    • Improved Phantom movement logic.
    • Fixed laser post-fire delay.
  • 1.0.0 26 March 2021
    • Initial public release.

Related Software

The Seal of RassilonThe Seal of Rassilon
Site and software copyright © 2022, Tony Smith