Recreation of the Merlin electronic handheld game using the Adafruit MacroPad RP2040, now with expanded games from Merlin, Master Merlin, and retro-style 8-bit inspirations.
Thanks to Keith Tanner for the original starting point code and STL files for the MacroPad case.
This project recreates and modernizes the classic Merlin electronic handheld game on the Adafruit MacroPad running CircuitPython.
It includes a launcher system (code.py) that dynamically loads and runs multiple self-contained games, conserving RAM by unloading modules between runs.
You will need:
- Adafruit MacroPad Libraries
- CircuitPython 9.1 or higher (tested on 9.1.4)
Case for MacroPad Merlin:
Original Manuals:
-
Install CircuitPython 9.1+
Follow Adafruit’s guide:
https://learn.adafruit.com/adafruit-macropad-rp2040/circuitpython -
Install Required Libraries
Copy from the latest Adafruit CircuitPython bundle:adafruit_display_textadafruit_macropadadafruit_ticks- Any other dependencies listed in the MacroPad guide
-
Copy Game Files
- Place all
.pyfiles andMerlinChrome.bmpat the root of CIRCUITPY.
- Place all
-
Reboot MacroPad — menu will appear.
-
Play!
- Rotate encoder → select game
- Press encoder → start game
- Press encoder again (or Key 9, depending on title) → return to menu
The launcher dynamically loads any game listed in GAMES_REG. Each is a self-contained class exposing .new_game(), .tick(), .button(), and .cleanup().
| Game | Type / Inspiration | Notes |
|---|---|---|
| Asteroids-Lite | Retro arcade | Lightweight asteroid shooter with LED effects |
| Battleship | Master Merlin | Guess ship positions, LED grid feedback |
| Beat Trainer | Rhythm | Match timing patterns; sequencer-like |
| Blackjack 13 | Merlin | Simplified blackjack vs CPU |
| Echo | Merlin | Repeat sequence of tones/lights |
| Hit or Miss | Master Merlin | Find hidden “ships” by guessing |
| Hi/Lo | Master Merlin | Guess the hidden number (LED hints) |
| Horseracing | VFD-style | Pick a lane, watch horses race |
| Hot Potato | Master Merlin | Pass the “potato”; don’t be last |
| Knight’s Tour | Puzzle | Chess knight covers all squares |
| LED Pinball | Retro LED | Ball lane simulation on 12 keys |
| Lights Out | Puzzle | Toggle lights until all off |
| Macro Maze | 3D Maze (C64-style) | Ray-cast maze on OLED |
| Magic Square | Merlin | Arrange lights into magic square |
| Match It | Master Merlin | Flip LEDs to find pairs |
| Maze Muncher | Pac-like | Scrolling grid arcade game |
| Merlin Adventure | Roguelike | Procedural dungeons on 128×64 |
| Merlin Dice | Casino | Virtual dice roller / mini-games |
| Merlin Rogue | Rogue-lite | ASCII-style dungeon crawler |
| Mindbender | Master Merlin | Logic puzzle (Mastermind-like) |
| Mixed Game Bag | ZX81-style classics | Breakout + Invaders |
| Music Machine | Merlin | Play tones freely |
| Musical Ladder | Master Merlin | Climb notes with correct hits |
| Pair Off | Master Merlin | Memory matching game |
| Patterns | Master Merlin | Match scrolling LED patterns |
| Simon | Simon/Merlin | Classic sequence memory |
| Snake / Snake II | Nokia-style | Snake + wraparound/bonus variant |
| Slots | Casino | Slot machine reel game |
| Spin the Bottle | Party | Random player selector |
| Tempo | Music (Master Merlin) | Sequencer; double-press exit supported |
| Three Shells | Master Merlin | Track ball under shells |
| Tic Tac Toe | Merlin | Human vs CPU |
| Tower of Hanoi | Puzzle | Solve 3-peg disk puzzle |
| Whack-A-Mole | Arcade | Hit lit keys; versus mode supported |
| Demo Scenes (70s-00s) | Retro FX | Vector, plasma, tunnel, spectrum bags |
- Encoder rotate → Navigate menu
- Encoder press → Start selected game
- Encoder press (in game) → Exit to menu (single press, unless game opts into double-press)
- Keys 0–11 → Routed to current game’s controls
- Each game defines its own key map (
button(),button_up()) - Some titles use encoder rotation (e.g., Music Machine pitch shift, Maze scroll)
- Some titles use encoder press inside gameplay (e.g., Tempo double-press exit hint)
The launcher provides:
- Menu UI with MerlinChrome logo + game list
- Dynamic imports from
GAMES_REG - Targeted unloading (
_purge_game_modules) - RAM reporting with deltas per stage
- Freeze + detach strategy to maximize heap before load
- Diagnostic constructor that tries multiple signatures and prints detailed error info
- Graceful return to menu with
cleanup()and LED/display resets
- All games are self-contained modules exposing a consistent API.
- Avoid blocking loops; use
time.monotonic()for timing. - Use
displayio.OnDiskBitmapfor assets (saves RAM). - Respect LED etiquette: batch updates, restore state in
cleanup(). supports_double_encoder_exitallows double-press to exit; optionally implementon_exit_hint()andon_exit_hint_clear().- RAM logs help identify leaks; aim for ΔFree ≈ 0 after unloading.
code.py # Launcher (menu system)
90s_demoscene.py
adventure.py
asteroids_lite.py
blackjack13.py
battleship.py
battleship_ui.py
battleship_config.py
battleship_personalities.py
beat_trainer.py
demoscene_2000s.py
echo.py
hanoi.py
hi_lo.py
hit_or_miss.py
horseracing.py
hot_potato.py
knights_tour.py
led_pinball.py
lights_out.py
macro_maze.py
magic_square.py
maze3d.py
match_it.py
merlin_dice
mindbender.py
minirogue.py
mixed_game_bag.py
music_machine.py
musical_ladder.py
pacman.py
pair_off.py
patterns.py
simon.py
sinclair_demo_bag.py
slot_reels.py
snake.py
spin_the_bottle.py
tempo.py
three_shells.py
tictactoe.py
vector_dreams_bag.py
whack_a_mole.py
MerlinChrome.bmp # Menu background
lib/ # Adafruit libraries
- Add Level 2 to Match It
- Reconfirm sounds for all games
- 2-Player support for Match It and Pair Off