SimonWaldherr/DIY-Arcade-Machine

Play classic arcade games on a 64x64 RGB LED Matrix, powered by the Raspberry RP2040.

26

stars

154

commits

Python

primary language

Sep 6, 2026

updated

simonwaldherr.github.io/DIY-Arcade-Machine/
arcade-game
arcade-machine
diy-electronics
game
hacktoberfest
hacktoberfest-accepted
interstate75
pygame
pygame-games
raspberry-pi-pico
rp2040

README

DIY Arcade Machine

Python MicroPython PyGame Deploy to GitHub Pages

Short video of the DIY Arcade Console in action (on YouTube)

A complete mini arcade system that runs on hardware, desktop, and in the browser: play a collection of classic-inspired games on a 64×64 RGB LED matrix (HUB75 + MicroPython), on your computer with a PyGame emulator, or directly in the browser via WebAssembly (pygbag).

Features

  • Triple Runtime Support
    • MicroPython + HUB75 LED Matrix: Runs on RP2040-based boards (Interstate 75)
    • Desktop (CPython) + PyGame: Full emulator for development and testing
    • Browser (WebAssembly) + pygbag: Play directly in any modern browser, no install needed
  • 70+ Games Available by Default: Classics, puzzle games, racers, shooters, reflex challenges, and compact original arcade games built for the 64×64 matrix
  • Intro Screen: Animated logo display on startup
  • 64×64 Display Layout
    • 58-pixel playfield (rows 0-57)
    • 6-pixel HUD at bottom (score + clock)
  • High Score System: Persistent scores with 3-letter initials entry
  • Memory-Optimized: Buffered framebuffer, packed grid storage, lazy font loading
  • Controller Support
    • MicroPython: Wii Nunchuk-style I2C controller (with auto-detection for variants)
    • Desktop: Keyboard emulation (arrow keys + Z/X)

Table of Contents


Quick Start

Run on desktop

pip install pygame-ce        # or: make install
python main.py               # or: make run

Test in browser locally

pip install pygame-ce pygbag==0.9.2   # or: make web-install
python -m pygbag .                    # build + serve at http://localhost:8000
# Safari: make web-safari (adds required COOP+COEP headers)

Deploy to GitHub Pages

Push to main — the GitHub Actions workflow builds the WebAssembly bundle with python -m pygbag --build . (Python 3.11) and deploys it to GitHub Pages automatically.


Web build (Pygbag)

Local preview (build + serve at http://localhost:8000):

pip install pygame-ce pygbag==0.9.2
python -m pygbag .

CI / offline bundle (writes to build/web/):

python -m pygbag --build .

GitHub Pages: in your repo go to Settings → Pages → Source and select GitHub Actions. Every push to main triggers the workflow which builds and deploys automatically.


Hardware Requirements

For Physical Arcade Machine


Software Requirements

MicroPython Hardware

  • MicroPython Firmware (Pimoroni build recommended)
  • Optional: Thonny IDE for uploading files
  • Optional: mpy-cross for compiling to bytecode (reduces boot RAM usage)

Desktop

  • Python 3.7+
  • pygame-ce 2.x (Community Edition — drop-in replacement for pygame)

Installation

Desktop Setup

  1. Install dependencies:

    pip install pygame-ce
    
  2. Run the game:

    make run
    # or manually: python main.py
    

A 640×640 window will appear showing the emulated LED matrix (10× scale).

Browser Setup (pygbag)

pygbag packages the game as WebAssembly so it runs in any modern browser — no Python installation needed.

  1. Install dependencies:

    pip install pygame-ce pygbag==0.9.2
    # or via make: make web-install
    
  2. Build and serve locally:

    python -m pygbag .    # build + serve at http://localhost:8000
    make web              # same, via Makefile (Chrome / Firefox)
    make web-safari       # Safari (adds required COOP+COEP headers)
    make web-ios          # iPhone/iPad fullscreen-oriented variant
    make web-ios-safari   # iOS/Safari variant with COOP+COEP headers
    
  3. Controls in browser: same keyboard mapping as desktop — Arrow Keys, Z/Space to confirm, X/Escape to cancel. On touch devices the browser build exposes an on-screen D-pad plus A/B action buttons; tapping the game canvas triggers the primary action, and swiping the canvas sends directional taps.

Browser support: Chrome and Firefox work out of the box. Safari requires Cross-Origin-Isolation headers (make web-safari handles this automatically).

iOS fullscreen: the iOS build keeps the game logic at the original 64×64 matrix resolution and scales the canvas fullscreen with safe-area-aware touch controls. This avoids rewriting every game for a new coordinate system while still filling the phone or tablet screen. On GitHub Pages it is published under /ios/; locally use make web-ios-safari for the closest Safari/iOS behavior.

Automated deployment: every push to main triggers the GitHub Actions workflow which builds the regular WebAssembly bundle plus the /ios/ variant and deploys both to GitHub Pages automatically.

Note: High scores are stored in-memory while the page is open and reset on page reload.

MicroPython Setup

The project now uses a tiny bootstrap approach to avoid on-device compilation memory errors:

  1. Install mpy-cross (optional but highly recommended):

    brew install micropython  # macOS
    # or: pip install mpy-cross
    
  2. Connect your Interstate 75 via USB

  3. Upload with Make:

    make upload
    # or manually: ./upload.sh
    

    The script will:

    • Auto-detect connected devices
    • Compile arcade_app.pyarcade_app.mpy (if mpy-cross available)
    • Upload both main.py (tiny bootstrap) and the compiled module
  4. Reboot the device - games start automatically

Manual Method

If you prefer manual upload via Thonny or ampy:

  1. Flash MicroPython firmware to Interstate 75
  2. Upload main.py (tiny bootstrap file)
  3. Upload arcade_app.py or arcade_app.mpy (the main application)
  4. Optional: Upload highscores.json if you want to preserve scores

Make Commands

For ease of use, a Makefile is provided with the following commands:

  • make install: Installs desktop dependencies (PyGame)
  • make run: Runs the PyGame emulator locally (python main.py)
  • make arcade-bundle: Rebuilds arcade_app.py from the modules in arcade_src/
  • make test: Rebuilds the bundle and runs the unit tests
  • make check: Verifies the committed bundle and runs the unit tests
  • make targets-check: Builds and smoke-tests desktop, MicroPython and both web targets
  • make desktop-check: Initializes PyGame and presents a headless frame
  • make hardware-check: Compiles main.py and arcade_app.py with mpy-cross
  • make web-check: Builds and validates the regular and iOS/touch web bundles
  • make web-install: Installs pygbag for browser/WebAssembly builds
  • make web-build: Builds the regular browser version into build/web/
  • make web-ios-build: Builds the fullscreen-oriented iOS version into build/ios/
  • make web-pages-build: Builds the Pages artifact with the regular version at / and the iOS version at /ios/
  • make web: Builds the WebAssembly version and serves it at http://localhost:8000
  • make web-ios: Builds and serves the iOS fullscreen-oriented version at http://localhost:8000
  • make web-ios-safari: Serves the iOS build with COOP+COEP headers for Safari
  • make upload: Compiles and uploads the code to the hardware (./upload.sh)
  • make build: Precompiles arcade_app.py into bytecode (arcade_app.mpy)
  • make clean: Cleans up previous build artifacts and pycache
  • make clean-all: Cleans up all files and the python virtual environment

Modular source workflow

The editable application source lives in arcade_src/. Its ordered fragments share one namespace and are concatenated into arcade_app.py. This preserves the single-module deployment model and low runtime overhead required by MicroPython while keeping development work split into manageable files.

After changing a fragment, run make arcade-bundle and commit both the source fragment and the regenerated arcade_app.py. make check detects a stale bundle.

Target support and validation

TargetRuntime and inputValidation
HUB75 consoleMicroPython, Interstate 75, Nunchuk/I2C controllermake hardware-check, then a physical-device smoke test before release
DesktopCPython, pygame-ce, keyboardmake desktop-check
Browserpygbag/WebAssembly, keyboard and optional touchmake web-check plus a browser canvas smoke test
iOS/touch browserpygbag/WebAssembly, on-screen D-pad, action buttons and gesturesIncluded in make web-check; published below /ios/

make targets-check runs every automated check. The HUB75 check proves that both deployable modules compile to MicroPython bytecode; display timing, brightness, I2C wiring and controller behavior still require the physical console because those properties cannot be reproduced faithfully on a host.


Content Selection

The configuration block at the top of arcade_src/00_runtime.py can hide content for a smaller or curated build. Add menu IDs to CONFIG_DISABLED_GAMES and effect IDs to CONFIG_DISABLED_DEMOS; leave the lists empty to show everything. CPU game previews in DEMOS use G:NAME, for example "G:DOOMLT".

CONFIG_DISABLED_GAMES = ("DOOMLT", "RAYRCR")
CONFIG_DISABLED_DEMOS = ("MANDEL", "G:DOOMLT")

Game List

The default configuration offers more than 70 selectable games plus demo animations. The table below documents the complete built-in catalog; entries can be enabled or disabled through the content-selection settings above.

Game IDNameDescription
DEMOSDemo ShowcaseZero-player demos: Snake, Life, Cube, Spark, Plasma, Orbit, Warp, Bounce, Tunnel, Matrix, Fire, Spring, Cradle
20482048Sliding tile puzzle with merge scoring
AIRHKYAir HockeyFast puck-and-mallet game with CPU or 2-player support
ARENAArenaTop-down wave survival with movement and shooting
ARTILLArtillery SimulatorTurn-based angle-and-power shell duel with wind and deforming terrain
ASTRDAsteroidsRotate, thrust, shoot asteroids in space
BEATBeat GridTap matching directions as notes cross the beat line and build a combo
BEJWLBejeweledMatch-3 gem swapping puzzle
BILLIBilliardsPool/Snooker-style table game with cue aim, pockets, rails, and ball collisions
BLOBBYBlobby VolleyOne-button beach volleyball against a compact CPU blob
BOMBERBomberTimed bombs, block clearing, and maze enemies
BRKOUTBreakoutBrick breaker with rainbow bricks and optional powerups
BUBBLEBubble BobbleTrap enemies in bubbles and touch them to pop them
BTLZONBattlezoneAtari-style vector tank combat with radar, rocks, projectile shots, and waves
CAVEFLCave FlyerTunnel navigation (starts wide, narrows progressively)
CENTICentipedeAtari-style segmented shooter with mushrooms and waves
CGOLGConway's Game of Life GameCompetitive Life battle with directed gliders and spaceships
CITYCity ChaseTop-down city driving with jobs, traffic, police heat, and drop-offs
CLIMBClimberPlatform-jumping tower climb with scrolling height
COLMNSColumnsMatch falling columns of colored gems in horizontal, vertical, or diagonal lines
CONNECTConnect FourDrop counters against a compact CPU opponent and make four in a row
DEFUSEDefuseCut colored wires in sequence before the timer expires
DEFENDDefenderPatrol a wrapping planet and rescue settlers from raiders
DIGDUGDig DugDig tunnels, collect gems, and pump burrowing enemies
DODGEDodgeAvoid falling blocks, dash to dodge
DONKEYDonkey KongClimb girders, use ladders, and jump rolling barrels
DOOMLTDoom LiteTarget-aware raycaster FPS with textured walls, enemy archetypes, and Quad burst fire; also powers the WINMAZE demo renderer
FLAPPYFlappy BirdNavigate through moving pipe gaps
FLOODFloodRecolor the connected corner region to clear the seven-by-seven board
FIGHTStreet FightersFootwork and timing duel against an aggressive CPU fighter
FROGGRFroggerHop across traffic lanes and advance through harder levels
GALAGAGalagaFormation shooter with diving enemy attacks
GALAXYGalaxyCapture planets by sending fleets across a compact star map
GOLFGolfTiny minigolf courses with aim, power, bounces, and obstacles
INVADRInvadersShoot marching alien waves, protect shields, hit saucers
JOUSTJoustFlap between platforms and defeat riders from above
KEENKeenPlatformer with jumps, gems, keys, enemies, and exit doors
KERBALKerbal ArcadeLaunch, circularize, and optionally return in a tiny orbital flight sim
LANDERLunar LanderMulti-level landing challenge plus optional scrolling v2 route mode with fuel powerups
LASERLaserMirror-rotation puzzle: guide the beam into the target
LIGHTSLights OutToggle a light and its neighbors to clear the five-by-five grid
LOCOLocoMotionRotating railway puzzle with train routing
LOOPTime LoopRecord movement loops whose ghosts hold switches for the next run
MAZEMaze ExplorerFog-of-war maze with gems, enemies, shooting
MARBLEMarble MadnessAccelerate a marble through walls, holes, and a finish gate
MINESMinesMinesweeper-style reveal puzzle for the LED matrix
MOONMoon PatrolArmed lunar rover with jumps, craters, and airborne hazards
ORBITOrbitAbsorb smaller blobs, avoid larger ones, and navigate gravity wells
ORBTALOrbitalBounce shots through numbered circles until they burst
PACMANPac-ManCollect pellets, avoid ghosts, power pellets
PAIRSPairsMemory card matching on a 4x4 board
PAPERPaperboyCycle through hazards and throw papers into marked mailboxes
PEGGLEPeggleAim a bouncing ball and clear orange pegs with limited shots
PICROSPicrossSolve five-by-five picture logic puzzles from row and column clues
PINBALPinballPlunger launch, flippers, bumpers, targets, and multipliers
PITFALPitfall RunnerEndless runner with snakes, pits, treasures (safe start zone)
POLARMagnetronSwitch polarity and steer charged particles into matching collectors
PONGPongPaddle vs. CPU or optional 2-player paddle duel
QIXQixTerritory capture, avoid the enemy
RACINGTop-Down RacingOverhead circuit racer with curved road, boost, laps, and traffic
RAYRCRRay RacerRaytrace-style anti-grav racing with boost, energy gates, and rival hovercars
REACTReaction GridHit green pads before time expires and avoid red decoys
REVRSOthello/ReversiBoard game with simple CPU opponent
RTYPER-Type ShooterSide-scrolling endless shooter
SABOTRSaboteur StealthSneak through multiple patrol maps and reach the objective
SIMONSimon SaysMemory sequence game with colored quadrants
SIGNALSignal ControlSwitch traffic lights and keep a busy intersection collision-free
SLALOMSlalomCarve through downhill gates; tuck for more speed and double points
SNAKESnakeClassic snake with red/green targets, wraparound
SOCCERChampionship SoccerAtari-style soccer with direction-based passes and shots
SONARSonar RuinsExplore a dark maze with limited sonar pulses, recover beacons, and find the exit
SOKOSokobanMulti-level crate-pushing puzzle campaign
STACKStackerTiming game: trim and stack moving blocks
STKARCStick ArcherArchery duel with charged shots, wind, and simple arrow physics
TAPPERTapperServe four bar lanes and catch every returning mug
TEMPESTTempestCircle a wireframe tunnel and shoot enemies before the rim
TETRISTetrisFalling blocks with line clearing
TILTTiltSlide across ice, collect every crystal, and reset with Z if you get stuck
TRONTron LightcycleLeave a trail, steer 90° turns, dodge CPU or optional second player
TWRDEFTower DefenseBuild towers across rotating road and open-field layouts
UFODEFUFO DefenseMissile Command-style defense with turret/base and wave/time settings
WIRESWiresRotate cable tiles to power one fully connected circuit
WORMSWorms MiniTurn-based team artillery with destructible terrain and CPU/2-player settings
ZAXXONZaxxonIsometric fortress flight through moving energy gates

Each game tracks high scores with optional initials entry.


Controls

Common Controls

Menu Navigation:

  • Up/Down: Navigate menu
  • Z (or Space/Enter): Start/Confirm
  • C (or X/Escape): Open game options when available; otherwise Back/Cancel

In-Game:

  • Directional movement: Arrow keys / Joystick
  • Primary action (jump/shoot/rotate): Z button / Space / Enter
  • Secondary/Back: C button / X / Escape

Desktop Keyboard Mapping

ActionKeys
MoveArrow Keys
Confirm/ActionZ, Space, or Enter
Back/CancelX or Escape
Player 1 Move in 2PW, A, S, D
Player 1 Action in 2PShift where used
Player 2 Move in 2PArrow Keys
Player 2 Action in 2PZ, Space, or Enter where used

Game Settings Highlights

  • AIRHKY: PLAYR switches between 1P and 2P; GOALS sets the match length.
  • BILLI: RULE switches between POOL and SNOOK; AIM changes the aim guide length.
  • PONG: PLAYR switches between 1P and 2P.
  • TRON: PLAYR switches between CPU opponent and 2P.
  • CITY: JOBS sets mission count; TRAF toggles civilian traffic.
  • KERBAL: MISN switches between orbit-only and return mission; ASST toggles arcade flight assist.
  • LANDER: MODE switches between classic V1 and scrolling V2 with route pads and fuel pickups.
  • RACING: LAPS sets race length; TRAF toggles traffic cars.
  • WORMS: PLAYR switches between CPU opponent and 2P; TEAM sets two or three worms per side.

MicroPython Controller

  • I2C Address: 0x52 (standard Nunchuk)
  • Pins: SCL=21, SDA=20 (configurable in code)
  • Buttons:
    • C button: Back/Cancel
    • Z button: Confirm/Action
  • Analog stick: 8-directional movement (includes diagonals)

The code auto-detects controller variants including the "new signature" controllers (A0 20 10 00 FF FF).


Usage

Start the app, select a game with Up/Down, and press Z to launch it. If a game has settings, press C on the game list to open the shared settings menu before starting the game.

High scores are stored per game ID. The shared game-over menu offers retry, high-score view, and return-to-menu actions.


Architecture

The modular source workflow is documented in arcade_src/README.md. Per-game descriptions are listed in the game table above.

The short version:

  • GameSelect.GAME_REGISTRY controls which games appear in the selector.
  • GameSettings.DEFINITIONS declares per-game settings for the shared settings menu.
  • Games that accept a constructor context read settings with get_context_setting().
  • Callback-based games inherit FrameLoopGame for portable sync/async frame pacing.
  • Grid games can inherit GridCursorGame for shared, debounced cursor movement.
  • Games report final results through set_game_over_score() so the shared lost/won and high-score flow can handle them.

Troubleshooting

  • If the browser build appears blank, rebuild with python -m pygbag . and check the console for import or asset errors.
  • If settings do not appear for a game, confirm the game ID in GameSettings.DEFINITIONS exactly matches the ID in GameSelect.GAME_REGISTRY.
  • If a game class exists but is missing from the menu, add it to GameSelect.GAME_REGISTRY.
  • If desktop input behaves differently from the cabinet, check the keyboard mapping in the Controls section and the joystick/button helper functions in arcade_app.py.

Contributors

SimonWaldherr

140 commits

Copilot

14 commits

SimonWaldherr/DIY-Arcade-Machine

Play classic arcade games on a 64x64 RGB LED Matrix, powered by the Raspberry RP2040.

26

stars

154

commits

Python

primary language

Sep 6, 2026

updated

simonwaldherr.github.io/DIY-Arcade-Machine/
arcade-game
arcade-machine
diy-electronics
game
hacktoberfest
hacktoberfest-accepted
interstate75
pygame
pygame-games
raspberry-pi-pico
rp2040

README

DIY Arcade Machine

Python MicroPython PyGame Deploy to GitHub Pages

Short video of the DIY Arcade Console in action (on YouTube)

A complete mini arcade system that runs on hardware, desktop, and in the browser: play a collection of classic-inspired games on a 64×64 RGB LED matrix (HUB75 + MicroPython), on your computer with a PyGame emulator, or directly in the browser via WebAssembly (pygbag).

Features

  • Triple Runtime Support
    • MicroPython + HUB75 LED Matrix: Runs on RP2040-based boards (Interstate 75)
    • Desktop (CPython) + PyGame: Full emulator for development and testing
    • Browser (WebAssembly) + pygbag: Play directly in any modern browser, no install needed
  • 70+ Games Available by Default: Classics, puzzle games, racers, shooters, reflex challenges, and compact original arcade games built for the 64×64 matrix
  • Intro Screen: Animated logo display on startup
  • 64×64 Display Layout
    • 58-pixel playfield (rows 0-57)
    • 6-pixel HUD at bottom (score + clock)
  • High Score System: Persistent scores with 3-letter initials entry
  • Memory-Optimized: Buffered framebuffer, packed grid storage, lazy font loading
  • Controller Support
    • MicroPython: Wii Nunchuk-style I2C controller (with auto-detection for variants)
    • Desktop: Keyboard emulation (arrow keys + Z/X)

Table of Contents


Quick Start

Run on desktop

pip install pygame-ce        # or: make install
python main.py               # or: make run

Test in browser locally

pip install pygame-ce pygbag==0.9.2   # or: make web-install
python -m pygbag .                    # build + serve at http://localhost:8000
# Safari: make web-safari (adds required COOP+COEP headers)

Deploy to GitHub Pages

Push to main — the GitHub Actions workflow builds the WebAssembly bundle with python -m pygbag --build . (Python 3.11) and deploys it to GitHub Pages automatically.


Web build (Pygbag)

Local preview (build + serve at http://localhost:8000):

pip install pygame-ce pygbag==0.9.2
python -m pygbag .

CI / offline bundle (writes to build/web/):

python -m pygbag --build .

GitHub Pages: in your repo go to Settings → Pages → Source and select GitHub Actions. Every push to main triggers the workflow which builds and deploys automatically.


Hardware Requirements

For Physical Arcade Machine


Software Requirements

MicroPython Hardware

  • MicroPython Firmware (Pimoroni build recommended)
  • Optional: Thonny IDE for uploading files
  • Optional: mpy-cross for compiling to bytecode (reduces boot RAM usage)

Desktop

  • Python 3.7+
  • pygame-ce 2.x (Community Edition — drop-in replacement for pygame)

Installation

Desktop Setup

  1. Install dependencies:

    pip install pygame-ce
    
  2. Run the game:

    make run
    # or manually: python main.py
    

A 640×640 window will appear showing the emulated LED matrix (10× scale).

Browser Setup (pygbag)

pygbag packages the game as WebAssembly so it runs in any modern browser — no Python installation needed.

  1. Install dependencies:

    pip install pygame-ce pygbag==0.9.2
    # or via make: make web-install
    
  2. Build and serve locally:

    python -m pygbag .    # build + serve at http://localhost:8000
    make web              # same, via Makefile (Chrome / Firefox)
    make web-safari       # Safari (adds required COOP+COEP headers)
    make web-ios          # iPhone/iPad fullscreen-oriented variant
    make web-ios-safari   # iOS/Safari variant with COOP+COEP headers
    
  3. Controls in browser: same keyboard mapping as desktop — Arrow Keys, Z/Space to confirm, X/Escape to cancel. On touch devices the browser build exposes an on-screen D-pad plus A/B action buttons; tapping the game canvas triggers the primary action, and swiping the canvas sends directional taps.

Browser support: Chrome and Firefox work out of the box. Safari requires Cross-Origin-Isolation headers (make web-safari handles this automatically).

iOS fullscreen: the iOS build keeps the game logic at the original 64×64 matrix resolution and scales the canvas fullscreen with safe-area-aware touch controls. This avoids rewriting every game for a new coordinate system while still filling the phone or tablet screen. On GitHub Pages it is published under /ios/; locally use make web-ios-safari for the closest Safari/iOS behavior.

Automated deployment: every push to main triggers the GitHub Actions workflow which builds the regular WebAssembly bundle plus the /ios/ variant and deploys both to GitHub Pages automatically.

Note: High scores are stored in-memory while the page is open and reset on page reload.

MicroPython Setup

The project now uses a tiny bootstrap approach to avoid on-device compilation memory errors:

  1. Install mpy-cross (optional but highly recommended):

    brew install micropython  # macOS
    # or: pip install mpy-cross
    
  2. Connect your Interstate 75 via USB

  3. Upload with Make:

    make upload
    # or manually: ./upload.sh
    

    The script will:

    • Auto-detect connected devices
    • Compile arcade_app.pyarcade_app.mpy (if mpy-cross available)
    • Upload both main.py (tiny bootstrap) and the compiled module
  4. Reboot the device - games start automatically

Manual Method

If you prefer manual upload via Thonny or ampy:

  1. Flash MicroPython firmware to Interstate 75
  2. Upload main.py (tiny bootstrap file)
  3. Upload arcade_app.py or arcade_app.mpy (the main application)
  4. Optional: Upload highscores.json if you want to preserve scores

Make Commands

For ease of use, a Makefile is provided with the following commands:

  • make install: Installs desktop dependencies (PyGame)
  • make run: Runs the PyGame emulator locally (python main.py)
  • make arcade-bundle: Rebuilds arcade_app.py from the modules in arcade_src/
  • make test: Rebuilds the bundle and runs the unit tests
  • make check: Verifies the committed bundle and runs the unit tests
  • make targets-check: Builds and smoke-tests desktop, MicroPython and both web targets
  • make desktop-check: Initializes PyGame and presents a headless frame
  • make hardware-check: Compiles main.py and arcade_app.py with mpy-cross
  • make web-check: Builds and validates the regular and iOS/touch web bundles
  • make web-install: Installs pygbag for browser/WebAssembly builds
  • make web-build: Builds the regular browser version into build/web/
  • make web-ios-build: Builds the fullscreen-oriented iOS version into build/ios/
  • make web-pages-build: Builds the Pages artifact with the regular version at / and the iOS version at /ios/
  • make web: Builds the WebAssembly version and serves it at http://localhost:8000
  • make web-ios: Builds and serves the iOS fullscreen-oriented version at http://localhost:8000
  • make web-ios-safari: Serves the iOS build with COOP+COEP headers for Safari
  • make upload: Compiles and uploads the code to the hardware (./upload.sh)
  • make build: Precompiles arcade_app.py into bytecode (arcade_app.mpy)
  • make clean: Cleans up previous build artifacts and pycache
  • make clean-all: Cleans up all files and the python virtual environment

Modular source workflow

The editable application source lives in arcade_src/. Its ordered fragments share one namespace and are concatenated into arcade_app.py. This preserves the single-module deployment model and low runtime overhead required by MicroPython while keeping development work split into manageable files.

After changing a fragment, run make arcade-bundle and commit both the source fragment and the regenerated arcade_app.py. make check detects a stale bundle.

Target support and validation

TargetRuntime and inputValidation
HUB75 consoleMicroPython, Interstate 75, Nunchuk/I2C controllermake hardware-check, then a physical-device smoke test before release
DesktopCPython, pygame-ce, keyboardmake desktop-check
Browserpygbag/WebAssembly, keyboard and optional touchmake web-check plus a browser canvas smoke test
iOS/touch browserpygbag/WebAssembly, on-screen D-pad, action buttons and gesturesIncluded in make web-check; published below /ios/

make targets-check runs every automated check. The HUB75 check proves that both deployable modules compile to MicroPython bytecode; display timing, brightness, I2C wiring and controller behavior still require the physical console because those properties cannot be reproduced faithfully on a host.


Content Selection

The configuration block at the top of arcade_src/00_runtime.py can hide content for a smaller or curated build. Add menu IDs to CONFIG_DISABLED_GAMES and effect IDs to CONFIG_DISABLED_DEMOS; leave the lists empty to show everything. CPU game previews in DEMOS use G:NAME, for example "G:DOOMLT".

CONFIG_DISABLED_GAMES = ("DOOMLT", "RAYRCR")
CONFIG_DISABLED_DEMOS = ("MANDEL", "G:DOOMLT")

Game List

The default configuration offers more than 70 selectable games plus demo animations. The table below documents the complete built-in catalog; entries can be enabled or disabled through the content-selection settings above.

Game IDNameDescription
DEMOSDemo ShowcaseZero-player demos: Snake, Life, Cube, Spark, Plasma, Orbit, Warp, Bounce, Tunnel, Matrix, Fire, Spring, Cradle
20482048Sliding tile puzzle with merge scoring
AIRHKYAir HockeyFast puck-and-mallet game with CPU or 2-player support
ARENAArenaTop-down wave survival with movement and shooting
ARTILLArtillery SimulatorTurn-based angle-and-power shell duel with wind and deforming terrain
ASTRDAsteroidsRotate, thrust, shoot asteroids in space
BEATBeat GridTap matching directions as notes cross the beat line and build a combo
BEJWLBejeweledMatch-3 gem swapping puzzle
BILLIBilliardsPool/Snooker-style table game with cue aim, pockets, rails, and ball collisions
BLOBBYBlobby VolleyOne-button beach volleyball against a compact CPU blob
BOMBERBomberTimed bombs, block clearing, and maze enemies
BRKOUTBreakoutBrick breaker with rainbow bricks and optional powerups
BUBBLEBubble BobbleTrap enemies in bubbles and touch them to pop them
BTLZONBattlezoneAtari-style vector tank combat with radar, rocks, projectile shots, and waves
CAVEFLCave FlyerTunnel navigation (starts wide, narrows progressively)
CENTICentipedeAtari-style segmented shooter with mushrooms and waves
CGOLGConway's Game of Life GameCompetitive Life battle with directed gliders and spaceships
CITYCity ChaseTop-down city driving with jobs, traffic, police heat, and drop-offs
CLIMBClimberPlatform-jumping tower climb with scrolling height
COLMNSColumnsMatch falling columns of colored gems in horizontal, vertical, or diagonal lines
CONNECTConnect FourDrop counters against a compact CPU opponent and make four in a row
DEFUSEDefuseCut colored wires in sequence before the timer expires
DEFENDDefenderPatrol a wrapping planet and rescue settlers from raiders
DIGDUGDig DugDig tunnels, collect gems, and pump burrowing enemies
DODGEDodgeAvoid falling blocks, dash to dodge
DONKEYDonkey KongClimb girders, use ladders, and jump rolling barrels
DOOMLTDoom LiteTarget-aware raycaster FPS with textured walls, enemy archetypes, and Quad burst fire; also powers the WINMAZE demo renderer
FLAPPYFlappy BirdNavigate through moving pipe gaps
FLOODFloodRecolor the connected corner region to clear the seven-by-seven board
FIGHTStreet FightersFootwork and timing duel against an aggressive CPU fighter
FROGGRFroggerHop across traffic lanes and advance through harder levels
GALAGAGalagaFormation shooter with diving enemy attacks
GALAXYGalaxyCapture planets by sending fleets across a compact star map
GOLFGolfTiny minigolf courses with aim, power, bounces, and obstacles
INVADRInvadersShoot marching alien waves, protect shields, hit saucers
JOUSTJoustFlap between platforms and defeat riders from above
KEENKeenPlatformer with jumps, gems, keys, enemies, and exit doors
KERBALKerbal ArcadeLaunch, circularize, and optionally return in a tiny orbital flight sim
LANDERLunar LanderMulti-level landing challenge plus optional scrolling v2 route mode with fuel powerups
LASERLaserMirror-rotation puzzle: guide the beam into the target
LIGHTSLights OutToggle a light and its neighbors to clear the five-by-five grid
LOCOLocoMotionRotating railway puzzle with train routing
LOOPTime LoopRecord movement loops whose ghosts hold switches for the next run
MAZEMaze ExplorerFog-of-war maze with gems, enemies, shooting
MARBLEMarble MadnessAccelerate a marble through walls, holes, and a finish gate
MINESMinesMinesweeper-style reveal puzzle for the LED matrix
MOONMoon PatrolArmed lunar rover with jumps, craters, and airborne hazards
ORBITOrbitAbsorb smaller blobs, avoid larger ones, and navigate gravity wells
ORBTALOrbitalBounce shots through numbered circles until they burst
PACMANPac-ManCollect pellets, avoid ghosts, power pellets
PAIRSPairsMemory card matching on a 4x4 board
PAPERPaperboyCycle through hazards and throw papers into marked mailboxes
PEGGLEPeggleAim a bouncing ball and clear orange pegs with limited shots
PICROSPicrossSolve five-by-five picture logic puzzles from row and column clues
PINBALPinballPlunger launch, flippers, bumpers, targets, and multipliers
PITFALPitfall RunnerEndless runner with snakes, pits, treasures (safe start zone)
POLARMagnetronSwitch polarity and steer charged particles into matching collectors
PONGPongPaddle vs. CPU or optional 2-player paddle duel
QIXQixTerritory capture, avoid the enemy
RACINGTop-Down RacingOverhead circuit racer with curved road, boost, laps, and traffic
RAYRCRRay RacerRaytrace-style anti-grav racing with boost, energy gates, and rival hovercars
REACTReaction GridHit green pads before time expires and avoid red decoys
REVRSOthello/ReversiBoard game with simple CPU opponent
RTYPER-Type ShooterSide-scrolling endless shooter
SABOTRSaboteur StealthSneak through multiple patrol maps and reach the objective
SIMONSimon SaysMemory sequence game with colored quadrants
SIGNALSignal ControlSwitch traffic lights and keep a busy intersection collision-free
SLALOMSlalomCarve through downhill gates; tuck for more speed and double points
SNAKESnakeClassic snake with red/green targets, wraparound
SOCCERChampionship SoccerAtari-style soccer with direction-based passes and shots
SONARSonar RuinsExplore a dark maze with limited sonar pulses, recover beacons, and find the exit
SOKOSokobanMulti-level crate-pushing puzzle campaign
STACKStackerTiming game: trim and stack moving blocks
STKARCStick ArcherArchery duel with charged shots, wind, and simple arrow physics
TAPPERTapperServe four bar lanes and catch every returning mug
TEMPESTTempestCircle a wireframe tunnel and shoot enemies before the rim
TETRISTetrisFalling blocks with line clearing
TILTTiltSlide across ice, collect every crystal, and reset with Z if you get stuck
TRONTron LightcycleLeave a trail, steer 90° turns, dodge CPU or optional second player
TWRDEFTower DefenseBuild towers across rotating road and open-field layouts
UFODEFUFO DefenseMissile Command-style defense with turret/base and wave/time settings
WIRESWiresRotate cable tiles to power one fully connected circuit
WORMSWorms MiniTurn-based team artillery with destructible terrain and CPU/2-player settings
ZAXXONZaxxonIsometric fortress flight through moving energy gates

Each game tracks high scores with optional initials entry.


Controls

Common Controls

Menu Navigation:

  • Up/Down: Navigate menu
  • Z (or Space/Enter): Start/Confirm
  • C (or X/Escape): Open game options when available; otherwise Back/Cancel

In-Game:

  • Directional movement: Arrow keys / Joystick
  • Primary action (jump/shoot/rotate): Z button / Space / Enter
  • Secondary/Back: C button / X / Escape

Desktop Keyboard Mapping

ActionKeys
MoveArrow Keys
Confirm/ActionZ, Space, or Enter
Back/CancelX or Escape
Player 1 Move in 2PW, A, S, D
Player 1 Action in 2PShift where used
Player 2 Move in 2PArrow Keys
Player 2 Action in 2PZ, Space, or Enter where used

Game Settings Highlights

  • AIRHKY: PLAYR switches between 1P and 2P; GOALS sets the match length.
  • BILLI: RULE switches between POOL and SNOOK; AIM changes the aim guide length.
  • PONG: PLAYR switches between 1P and 2P.
  • TRON: PLAYR switches between CPU opponent and 2P.
  • CITY: JOBS sets mission count; TRAF toggles civilian traffic.
  • KERBAL: MISN switches between orbit-only and return mission; ASST toggles arcade flight assist.
  • LANDER: MODE switches between classic V1 and scrolling V2 with route pads and fuel pickups.
  • RACING: LAPS sets race length; TRAF toggles traffic cars.
  • WORMS: PLAYR switches between CPU opponent and 2P; TEAM sets two or three worms per side.

MicroPython Controller

  • I2C Address: 0x52 (standard Nunchuk)
  • Pins: SCL=21, SDA=20 (configurable in code)
  • Buttons:
    • C button: Back/Cancel
    • Z button: Confirm/Action
  • Analog stick: 8-directional movement (includes diagonals)

The code auto-detects controller variants including the "new signature" controllers (A0 20 10 00 FF FF).


Usage

Start the app, select a game with Up/Down, and press Z to launch it. If a game has settings, press C on the game list to open the shared settings menu before starting the game.

High scores are stored per game ID. The shared game-over menu offers retry, high-score view, and return-to-menu actions.


Architecture

The modular source workflow is documented in arcade_src/README.md. Per-game descriptions are listed in the game table above.

The short version:

  • GameSelect.GAME_REGISTRY controls which games appear in the selector.
  • GameSettings.DEFINITIONS declares per-game settings for the shared settings menu.
  • Games that accept a constructor context read settings with get_context_setting().
  • Callback-based games inherit FrameLoopGame for portable sync/async frame pacing.
  • Grid games can inherit GridCursorGame for shared, debounced cursor movement.
  • Games report final results through set_game_over_score() so the shared lost/won and high-score flow can handle them.

Troubleshooting

  • If the browser build appears blank, rebuild with python -m pygbag . and check the console for import or asset errors.
  • If settings do not appear for a game, confirm the game ID in GameSettings.DEFINITIONS exactly matches the ID in GameSelect.GAME_REGISTRY.
  • If a game class exists but is missing from the menu, add it to GameSelect.GAME_REGISTRY.
  • If desktop input behaves differently from the cabinet, check the keyboard mapping in the Controls section and the joystick/button helper functions in arcade_app.py.

Contributors

SimonWaldherr

140 commits

Copilot

14 commits

Languages

Python

97.0%

Go Template

2.1%