JumPHP: write retro 2D games in PHP that run on desktop, in the browser and on phones
For the past few months I've been working on JumPHP, an open-source framework for writing 90s-style 2D games in plain PHP.
https://github.com/davidnurdin/jumPhp
The idea is simple: you write your game once, in PHP, and the same code runs in three places.
- On the desktop: a native window with sound, using PHP 8.3 and the SDL2 extensions.
- In the browser: PHP 8.3 and SDL2 are compiled to WebAssembly, so the game is a plain static web page. PHP runs on the player's machine; you don't need a PHP server, any static host works.
- On phones: the browser build ships with touch controls (floating joystick, buttons, fullscreen and landscape lock).
What it's for
- Platformers, shoot 'em ups, brick breakers, adventure games, puzzle games.
- Porting old games whose source code is available. Many C games from the 80s and 90s translate to PHP surprisingly well.
- Learning game programming with a language you already know, without switching to JavaScript, C# or Lua.
- Small multiplayer games you can share with a link.
What's in the box
- Scenes, sprites and animations, a camera, menus and HUD helpers, bitmap and TTF fonts.
- Saves (stored in IndexedDB in the browser), options and translations.
- Online multiplayer through a small relay server: rooms, 4-letter codes, quick match. The same code works on desktop and in the browser.
- A single CLI, bin/jumphp, that runs everything in Docker: PHP, Composer, Emscripten, tests, headless screenshots, browser builds, deployment. You only need Docker on your machine.
- An AGENTS.md that documents the whole contract, so you can also build a game with an LLM coding agent. Most of the games below were made that way, with me reviewing, testing and fixing.
The constraints are few: never block the frame (no sleep()), remember that integers are 32-bit in the browser, and use the engine's network layer instead of raw sockets.
What I've built with it so far
- Pong (bundled with the engine): against the computer, two players on one keyboard, or online. It's the reference game for the networking layer.
- Breakout (bundled with the engine): three lives, a new wall every level.
- Invaders: waves of aliens, shields, a bonus saucer. https://github.com/davidnurdin/php-invaders
- Moktar, a 1991 French DOS platformer, ported from OpenTitus (the open-source C engine for the game). Everything is PHP, down to the original file formats and an AdLib/OPL2 FM synth emulator that renders the original soundtrack. Play: https://moktar.mimichat.fr, code: https://github.com/davidnurdin/moktarPhp
- Sapiens, a 1986 prehistoric adventure game by Didier and Olivier Guillion. Its C sources were released under GPL v3 in 2018, and the port follows them function by function: a first-person 3D landscape, side-view fights, dialogues with the tribes, flint knapping. I also decoded the music files of the 1996 version (an undocumented Harmony Assistant format) to play the soundtrack with its original sampled instruments. Play: https://sapiens.mimichat.fr, code: https://github.com/davidnurdin/sapiensPhp
- Sonic PHP, a fan remake of the Master System game built on the same PHP + SDL2 + WebAssembly stack. It runs at 60 fps and has online multiplayer for up to 6 players (race, flag, rings, deathmatch). Play: https://sonic.mimichat.fr, code: https://github.com/davidnurdin/sonicGamePhp
Getting started
git clone https://github.com/davidnurdin/jumPhp
cd jumPhp
bin/jumphp new mygame "MY GAME"
bin/jumphp install mygame
bin/jumphp run mygame # desktop window
bin/jumphp build mygame # browser build
The new game starts from a small platformer skeleton you can replace bit by bit.
Feedback is welcome, especially from people who try to build something with it. And if you could bring back one old game in PHP, which one would it be?