No description
  • PHP 64.6%
  • JavaScript 21.5%
  • Shell 7.5%
  • CSS 1.9%
  • Rust 1%
  • Other 3.5%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-11-06 22:42:45 +01:00
.claude-plugin The JumPHP pane for Claude Code (claude-mod/jumphp-live): bin/jumphp test live, the screenshots, the playground's tests 2026-10-29 17:30:32 +01:00
.github/workflows gh for every forge (tools/bin/gh + tools/forge.php: GitHub -> real gh, git.jumphp.net -> forge API), JumPHP's addresses moved to git.jumphp.net, old projects' remotes follow, extension splits on the same forge 2026-11-06 21:36:17 +01:00
apps gh for every forge (tools/bin/gh + tools/forge.php: GitHub -> real gh, git.jumphp.net -> forge API), JumPHP's addresses moved to git.jumphp.net, old projects' remotes follow, extension splits on the same forge 2026-11-06 21:36:17 +01:00
bin runner:install / runner:remove (Docker, scoped to one org or user, isolated dind) and the CI docs 2026-11-06 21:38:18 +01:00
claude-mod/jumphp-live gh for every forge (tools/bin/gh + tools/forge.php: GitHub -> real gh, git.jumphp.net -> forge API), JumPHP's addresses moved to git.jumphp.net, old projects' remotes follow, extension splits on the same forge 2026-11-06 21:36:17 +01:00
docker gh for every forge (tools/bin/gh + tools/forge.php: GitHub -> real gh, git.jumphp.net -> forge API), JumPHP's addresses moved to git.jumphp.net, old projects' remotes follow, extension splits on the same forge 2026-11-06 21:36:17 +01:00
docs runner:install / runner:remove (Docker, scoped to one org or user, isolated dind) and the CI docs 2026-11-06 21:38:18 +01:00
engine gh for every forge (tools/bin/gh + tools/forge.php: GitHub -> real gh, git.jumphp.net -> forge API), JumPHP's addresses moved to git.jumphp.net, old projects' remotes follow, extension splits on the same forge 2026-11-06 21:36:17 +01:00
extensions gh for every forge (tools/bin/gh + tools/forge.php: GitHub -> real gh, git.jumphp.net -> forge API), JumPHP's addresses moved to git.jumphp.net, old projects' remotes follow, extension splits on the same forge 2026-11-06 21:36:17 +01:00
games IDE: sign-in tokens for the site's forge next to GitHub (Git, Playground, Creator, Main): repositories and extension pushes on git.jumphp.net 2026-11-06 21:37:47 +01:00
ide IDE: sign-in tokens for the site's forge next to GitHub (Git, Playground, Creator, Main): repositories and extension pushes on git.jumphp.net 2026-11-06 21:37:47 +01:00
skeleton gh for every forge (tools/bin/gh + tools/forge.php: GitHub -> real gh, git.jumphp.net -> forge API), JumPHP's addresses moved to git.jumphp.net, old projects' remotes follow, extension splits on the same forge 2026-11-06 21:36:17 +01:00
skeleton-app gh for every forge (tools/bin/gh + tools/forge.php: GitHub -> real gh, git.jumphp.net -> forge API), JumPHP's addresses moved to git.jumphp.net, old projects' remotes follow, extension splits on the same forge 2026-11-06 21:36:17 +01:00
skeleton-cli Web IDE read only for a read member (files, actions, status bar); CLI apps: hidden answers in the web terminal (QuestionHelper, Style) 2026-11-04 00:35:56 +01:00
skeleton-extension gh for every forge (tools/bin/gh + tools/forge.php: GitHub -> real gh, git.jumphp.net -> forge API), JumPHP's addresses moved to git.jumphp.net, old projects' remotes follow, extension splits on the same forge 2026-11-06 21:36:17 +01:00
skeleton-gui gh for every forge (tools/bin/gh + tools/forge.php: GitHub -> real gh, git.jumphp.net -> forge API), JumPHP's addresses moved to git.jumphp.net, old projects' remotes follow, extension splits on the same forge 2026-11-06 21:36:17 +01:00
skeleton-plugin Apps in apps/ beside games/, config/project.yaml beside config/game.yaml (both read) 2026-11-03 23:30:23 +01:00
tauri IDE: OpenCode permissions (no more 'rejected permission' on MCP tools), IA/HISTORY per turn (never in git), auto /compact, 'Install git/Docker' button on missing-program errors, OpenCode label, GitHub 401 message; Windows: WebView2 bootstrapper packed in the native library (silent install); IDE 0.1.61 2026-11-05 21:37:07 +01:00
tools gh for every forge (tools/bin/gh + tools/forge.php: GitHub -> real gh, git.jumphp.net -> forge API), JumPHP's addresses moved to git.jumphp.net, old projects' remotes follow, extension splits on the same forge 2026-11-06 21:36:17 +01:00
.env.dist Deploy behind an existing Traefik that works, a check after each deploy 2026-10-28 21:52:26 +01:00
.gitattributes Force LF line endings (Git for Windows' CRLF broke bin/jumphp: bash\r) 2026-11-05 23:24:30 +01:00
.gitignore IDE: OpenCode permissions (no more 'rejected permission' on MCP tools), IA/HISTORY per turn (never in git), auto /compact, 'Install git/Docker' button on missing-program errors, OpenCode label, GitHub 401 message; Windows: WebView2 bootstrapper packed in the native library (silent install); IDE 0.1.61 2026-11-05 21:37:07 +01:00
AGENTS.md gh for every forge (tools/bin/gh + tools/forge.php: GitHub -> real gh, git.jumphp.net -> forge API), JumPHP's addresses moved to git.jumphp.net, old projects' remotes follow, extension splits on the same forge 2026-11-06 21:36:17 +01:00
CLAUDE.md JumPHP: PHP framework for retro 2D games (desktop + WebAssembly) 2026-10-27 18:11:08 +01:00
compose.yaml JumPHP: PHP framework for retro 2D games (desktop + WebAssembly) 2026-10-27 18:11:08 +01:00
composer.json gh for every forge (tools/bin/gh + tools/forge.php: GitHub -> real gh, git.jumphp.net -> forge API), JumPHP's addresses moved to git.jumphp.net, old projects' remotes follow, extension splits on the same forge 2026-11-06 21:36:17 +01:00
install.ps1 Install in one line: curl -fsSL https://jumphp.net/install.sh | sh (Linux, macOS, WSL), install.ps1 for Windows (in WSL); jumphp new without composer or docker (git clone of the newest release) 2026-10-29 22:23:48 +01:00
install.sh Install in one line: curl -fsSL https://jumphp.net/install.sh | sh (Linux, macOS, WSL), install.ps1 for Windows (in WSL); jumphp new without composer or docker (git clone of the newest release) 2026-10-29 22:23:48 +01:00
LICENSE New projects: composer create-project jumphp/jumphp, a set-up wizard, server deployment 2026-10-28 17:52:39 +01:00
Makefile JumPHP: PHP framework for retro 2D games (desktop + WebAssembly) 2026-10-27 18:11:08 +01:00
README.md gh for every forge (tools/bin/gh + tools/forge.php: GitHub -> real gh, git.jumphp.net -> forge API), JumPHP's addresses moved to git.jumphp.net, old projects' remotes follow, extension splits on the same forge 2026-11-06 21:36:17 +01:00
TODO-AFTER.md TODO-AFTER.md: signing (Authenticode, Developer ID, notarization, TestFlight) on hold 2026-11-04 10:37:20 +01:00
TODO-FIRST.md TODO-FIRST: what was tried for real, names, a clean project 2026-11-05 03:09:36 +01:00
todo-migration-git.md TODO: studio git button, projects to move, 404 notes, multi-account 2026-11-06 22:42:45 +01:00
TODO-URGENT.md TODO-URGENT: todojumphp checked on GitHub and jumphp.net 2026-11-04 21:45:19 +01:00
TODO.md UDP and ICMP (engine->udp(), engine->icmp()), the SSH key ring (engine->sshKeyring(), several identities), crash reports of the browser engine with their log, early failures reach the listeners, examples apps/hello-tcp and apps/hello-ssh with tutorials, docs 2026-11-06 16:16:53 +01:00
VERSION Engine 0.5.21: FilePicker::open() in the browser (the chosen file is written into /tmp/jumphp-picked), applications without click-to-play, game page fullscreen at the first click 2026-11-06 15:38:23 +01:00

JumPHP

Français · English


Français

Un framework PHP pour créer des jeux rétro 2D (SDL2) qui tournent sur le bureau (PHP natif) et dans le navigateur (PHP compilé en WebAssembly), avec exactement le même code.

Essayer sans rien installer : jumphp.net, le playground (les jeux, un bac à sable, la documentation et les tutoriels).

Tiles et collisions au pixel (pentes, plateformes, cartes Tiled), entités et animations, caméra, son (fichiers ou sons générés), menus, sauvegardes, traductions, clavier / manette / tactile, multijoueur en ligne. Tout passe par Docker : la machine n'a besoin que de Docker (plus d'un écran et d'un serveur son pour jouer sur le bureau). Jamais de PHP, d'emscripten ou de node à installer.

Nouveau projet

En une ligne (Linux, macOS, WSL ; sous Windows dans PowerShell : irm https://jumphp.net/install.ps1 | iex) : la commande jumphp (install.sh), puis le projet. Windows sans Docker Desktop : Docker Engine dans WSL marche aussi (docs/windows-wsl.md).

curl -fsSL https://jumphp.net/install.sh | sh -s -- mon-jeu

Ou avec Composer :

composer create-project jumphp/jumphp mon-jeu

Le projet est une copie de JumPHP reliée au dépôt par git (remote jumphp : bin/jumphp update récupère les nouvelles versions). Un assistant démarre aussitôt (ou plus tard : cd mon-jeu && bin/jumphp). Chaque étape demande avant d'agir :

  1. les outils : git, curl, Docker (installés avec le gestionnaire de paquets du système s'ils manquent) ;
  2. ton jeu : nom, identifiant, description, résolution, langue → games/<id> ;
  3. le moteur navigateur (téléchargé déjà compilé, ou compilé sur place) et un premier test ;
  4. le déploiement sur ton serveur : FrankenPHP seul, Traefik + FrankenPHP, ou derrière un Traefik existant ;
  5. le dépôt GitHub (et GitHub Pages) ;
  6. Claude Code, lancé avec un prompt prêt : tu écris seulement ce que doit faire ton jeu.

Sans PHP sur la machine : docker run --rm -it -v "$PWD":/app -w /app composer create-project jumphp/jumphp mon-jeu, puis cd mon-jeu && bin/jumphp. Ou simplement git clone https://git.jumphp.net/jumphp/jumPhp.git mon-jeu. Détails : docs/projet.md.

Tutoriel de A à Z

Le tutoriel complet, pas à pas, est dans docs/tutoriel.md. En résumé :

Étape Commande Ce qui se passe
A. Créer composer create-project jumphp/jumphp mon-jeu JumPHP est copié et relié à son dépôt par git, puis l'assistant démarre
B. Configurer (l'assistant, ou bin/jumphp) outils (git, Docker...), nom et résolution du jeu, moteur navigateur, premier test
C. Écrire le jeu tu décris le jeu en quelques lignes Claude Code le code à partir de games/<id>/BRIEF.md, le teste et regarde les captures
D. Jouer bin/jumphp run <id> / test / shot fenêtre avec le son / contrôles automatiques / captures sans écran
E. Modifier games/<id>/src/Scene, src/Entity, config/ des scènes et des entités en PHP, voir AGENTS.md
F. Navigateur bin/jumphp build <id> puis bin/jumphp serve <id> le même PHP en WebAssembly sur http://localhost:8080
G. Serveur bin/jumphp deploy:setup puis bin/jumphp deploy ton domaine en HTTPS : FrankenPHP seul, Traefik + FrankenPHP, ou un Traefik existant
H. GitHub bin/jumphp github (bin/jumphp pages <id>) le dépôt créé avec gh (et le jeu sur GitHub Pages)
I. Mettre à jour bin/jumphp update la dernière version de JumPHP fusionnée dans le projet
J. Commande jumphp bin/jumphp cli:install (proposé par l'assistant) jumphp <commande> de n'importe quel dossier du projet, jumphp new <dossier>, et une question quand une nouvelle version sort sur Packagist
K. Google Play bin/jumphp twa <id> --url https://… le jeu en appli Android (.aab pour le Play Store, .apk), voir docs/android.md ; la publication pas à pas : docs/google-play.md
L. Mac, iPhone, iPad bin/jumphp apple <id> (macos / ios) le jeu en applis Apple natives (.dmg, .ipa), fabriquées et essayées sur les Mac de GitHub, voir docs/apple.md

Démarrage rapide

Démo en ligne : https://davidnurdin.github.io/jumPhp/ (JUMPBALL en 3D WebGL, hello-webgl, hello-threads, Pong, casse-briques).

git clone https://git.jumphp.net/jumphp/jumPhp.git && cd jumPhp
bin/jumphp setup              # images Docker (une fois, ~3 min)
bin/jumphp install pong       # dépendances du jeu
bin/jumphp run pong           # jouer sur le bureau (fenêtre + son)

Dans le navigateur :

bin/jumphp engine:build       # moteur WebAssembly (une fois par machine, ~25 min, en cache ensuite)
bin/jumphp build pong         # -> games/pong/dist/web (fichiers statiques)
bin/jumphp serve pong         # http://localhost:8080 (servi par FrankenPHP)

Pong : flèches + Entrée dans les menus, W / S (joueur 1), haut / bas (joueur 2), Échap ou P = pause, F11 plein écran, F3 FPS. En ligne : bin/jumphp relay up, puis « En ligne » → « Partie rapide » dans deux fenêtres (bureau et / ou navigateur).

Créer un jeu

bin/jumphp new mon-jeu "MON JEU"   # copie de skeleton/ (un petit jeu de plateforme)
bin/jumphp install mon-jeu
bin/jumphp test mon-jeu            # lint, phpstan, phpunit, 600 frames sans écran
bin/jumphp shot mon-jeu 60         # capture PNG sans écran : games/mon-jeu/var/screenshots/shot.png
bin/jumphp run mon-jeu

Un jeu = des scènes (src/Scene : écran titre, partie, pause...) et des entités (src/Entity), plus trois fichiers de configuration (config/project.yaml, input.yaml, lang.yaml). Aucun asset n'est obligatoire : police bitmap intégrée, pixel art dans le code, sons synthétisés.

Avec une IA : AGENTS.md contient tout ce qu'il faut pour qu'un agent (Claude Code, etc.) crée un jeu de A à Z sans rien connaître du projet : règles, commandes, API, recettes, vérifications. Le casse-briques games/breakout a été écrit ainsi, par une IA qui n'avait lu que ce fichier.

Contenu du dépôt

Dossier Contenu
bin/jumphp la ligne de commande (bin/jumphp help)
engine/ le framework (paquet composer jumphp/engine, namespace JumPHP\)
skeleton/ le modèle de jeu copié par bin/jumphp new
games/pong/ jeu de référence : contre l'ordinateur, à deux sur un clavier, en ligne
games/breakout/ casse-briques écrit par une IA à partir d'AGENTS.md
games/hello-threads/ POC des threads (TrueAsync) : une fractale calculée par un pool de threads
games/hello-desktop/ une application de bureau (Tauri) : un bloc-notes, page HTML + PHP
games/hello-hybrid/ un jeu hybride : un jeu SDL + un panneau de contrôle HTML, dialogues natifs, icône de notification
skeleton-app/, tauri/ le modèle d'application de bureau (bin/jumphp app:new) et son runtime natif (Rust + Tauri 2, piloté par PHP en FFI)
docker/ moteur WebAssembly, runtimes bureau (PHP 8.5, et PHP 8.6 ZTS + TrueAsync), relais réseau, serveur web FrankenPHP
tools/ scripts utilisés par bin/jumphp (packaging, captures, contrôles)
docs/ documentation détaillée (français)

Commandes

Commande Rôle
init (ou bin/jumphp seul) assistant : outils, jeu, moteur, serveur, GitHub, Claude Code
setup [async] construit les images Docker (async : aussi le runtime PHP 8.6 ZTS + TrueAsync)
engine:download / engine:build moteur WebAssembly dans build/engine/ : téléchargé (release GitHub) / compilé (~25 min)
update fusionne la dernière version de JumPHP dans le projet
new <jeu> ["Titre"] nouveau jeu depuis le squelette
install <jeu> / composer <jeu> ... dépendances composer (paquets PHP purs uniquement)
run <jeu> jouer sur le bureau (X11 ou Wayland, PulseAudio / PipeWire, GPU si disponible)
test <jeu> / test engine contrôles du jeu / tests du moteur
shot <jeu> [frames] capture d'écran sans écran
build <jeu> version navigateur (dist/web, à poser sur n'importe quel hébergement statique)
serve <jeu> [port] sert la version navigateur avec FrankenPHP
webshot <jeu> teste la version navigateur dans un Chrome sans écran
relay up|down|logs serveur multijoueur sur ws://localhost:8090/ws
export:desktop <jeu> une image Docker qui lance le jeu
export:standalone <jeu> [--linux] [--windows] le jeu en un seul exécutable, rien à installer (PHP, SDL, OpenGL, OpenAL dedans), voir docs/standalone.md
app:new / app:run / app:test / app:shot / app:export <app> applications de bureau : fenêtres natives aux pages HTML / CSS / JS, logique en PHP (Tauri, natif : Linux, Windows, macOS ; ui: hybrid pour un jeu), voir docs/tauri.fr.md
deploy:setup / deploy [jeux...] configure / déploie sur ton serveur (FrankenPHP seul ou avec Traefik, HTTPS Let's Encrypt) ; sans serveur : rsync vers JUMPHP_DEPLOY_TARGET
server:setup / server:logs installe Docker sur le serveur / journaux du serveur web
github met le projet sur GitHub (gh), et en option sur GitHub Pages
pages [jeux...] construit les jeux (tous par défaut) et les publie avec une page d'accueil sur GitHub Pages (branche gh-pages, remplacée à chaque fois)
lint / doctor contrôle de tout le dépôt / diagnostic de la machine

make run GAME=pong etc. existe aussi (Makefile).

Comment ça marche

  • Bureau : PHP 8.5 CLI + extensions SDL2 / SDL_image / SDL_mixer / SDL_ttf, OpenGL (php-opengl) et OpenAL (php-openal), dans Docker, avec l'affichage et le son de l'hôte. Boucle ReactPHP, conteneur Symfony DI, événements Evenement.
  • Navigateur : le même PHP 8.5 et les mêmes extensions compilés en WebAssembly avec emscripten (php-wasm-sdl) : OpenGL devient WebGL, OpenAL devient Web Audio, et la 3D s'écrit une seule fois pour les deux cibles. Le navigateur appelle une frame PHP par requestAnimationFrame. Les sauvegardes vont dans IndexedDB. Le jeu est un dossier statique.
  • Réseau : php-wasm-network — même API en natif et dans le navigateur (WebSocket / WebRTC), avec son serveur relais.
  • Serveur web : FrankenPHP (Caddy + PHP). Les jeux sont statiques ; FrankenPHP est là pour accueillir plus tard la partie PHP du portail de jeux (comptes, scores...).
  • Threads (optionnel) : runtime: async dans project.yaml fait tourner le jeu sur PHP 8.6 ZTS + TrueAsync : $this->engine->tasks() envoie le travail lourd dans de vrais threads, la frame n'attend jamais. Dans le navigateur, la même API passe par un pool de Web Workers (un moteur PHP WebAssembly chacun) ; sur le runtime par défaut, elle répartit le travail entre les frames. Voir docs/async.md et games/hello-threads.

Contraintes du navigateur (détaillées dans docs/navigateur.md) : ne jamais bloquer la frame (sleep, boucles infinies), entiers 32 bits, réseau uniquement via JumPHP\Net et JumPHP\Http, fichiers écrits seulement dans var/.

Avec Claude Code : le panneau JumPHP

Le mod jumphp-live (claude-mod/jumphp-live/) ajoute à Claude Code un panneau à côté de la conversation : les l'écran du jeu en direct pendant qu'il tourne, les vérifications de bin/jumphp test (✔ / ✘ par étape, les tests PHPUnit en échec), les captures que Claude prend et regarde, les tests du playground ; des boutons pour relancer les tests, prendre une capture, ou demander une correction à Claude, et un champ pour lui écrire. À taper dans Claude Code :

/plugin install jumphp-live --marketplace davidnurdin/jumPhp

puis /jumphp <jeu> dans le projet.

Documentation


English

A PHP framework to make retro 2D games (SDL2) that run on the desktop (native PHP) and in the browser (PHP compiled to WebAssembly), with exactly the same code.

Try it without installing anything: jumphp.net, the playground (games, a sandbox, documentation and tutorials).

Pixel-precise tiles and collisions (slopes, platforms, Tiled maps), entities and animations, camera, sound (files or generated sounds), menus, saves, translations, keyboard / gamepad / touch, online multiplayer. Everything runs in Docker: the machine only needs Docker (plus a display and a sound server to play on the desktop). Never install PHP, emscripten or node.

New project

In one line (Linux, macOS, WSL; on Windows in PowerShell: irm https://jumphp.net/install.ps1 | iex): the jumphp command (install.sh), then the project. Windows without Docker Desktop: Docker Engine inside WSL works too (docs/windows-wsl.md).

curl -fsSL https://jumphp.net/install.sh | sh -s -- my-game

Or with Composer:

composer create-project jumphp/jumphp my-game

The project is a copy of JumPHP linked to its repository with git (remote jumphp: bin/jumphp update brings new versions). A wizard starts right away (or later: cd my-game && bin/jumphp); each step asks before acting: tools (git, curl, Docker: installed with the system's package manager when missing), your game (name, id, description, resolution, language → games/<id>), the browser engine (prebuilt download or local build) and a first test, deployment to your server (FrankenPHP alone, Traefik + FrankenPHP, or behind an existing Traefik), the GitHub repository (and GitHub Pages), then Claude Code started with a ready-made prompt: you only write what your game should do.

Without PHP on the machine: docker run --rm -it -v "$PWD":/app -w /app composer create-project jumphp/jumphp my-game, then cd my-game && bin/jumphp. Or just git clone https://git.jumphp.net/jumphp/jumPhp.git my-game.

Tutorial from A to Z

The complete step-by-step tutorial is docs/tutorial.md. In short:

Step Command What happens
A. Create composer create-project jumphp/jumphp my-game JumPHP is copied and linked to its repository with git, then the wizard starts
B. Set up (the wizard, or bin/jumphp) tools (git, Docker...), the game's name and resolution, browser engine, a first test
C. Write the game you describe the game in a few lines Claude Code codes it from games/<id>/BRIEF.md, tests it and looks at the screenshots
D. Play bin/jumphp run <id> / test / shot a window with sound / automatic checks / headless screenshots
E. Change it games/<id>/src/Scene, src/Entity, config/ scenes and entities in PHP, see AGENTS.md
F. Browser bin/jumphp build <id> then bin/jumphp serve <id> the same PHP as WebAssembly on http://localhost:8080
G. Server bin/jumphp deploy:setup then bin/jumphp deploy your domain over HTTPS: FrankenPHP alone, Traefik + FrankenPHP, or an existing Traefik
H. GitHub bin/jumphp github (bin/jumphp pages <id>) the repository created with gh (and the game on GitHub Pages)
I. Update bin/jumphp update the newest JumPHP merged into the project
J. jumphp command bin/jumphp cli:install (offered by the wizard) jumphp <command> from any folder of the project, jumphp new <folder>, and a question when a new version is out on Packagist
K. Google Play bin/jumphp twa <id> --url https://… the game as an Android app (.aab for the Play Store, .apk), see docs/android.md; publishing step by step: docs/google-play.md
L. Mac, iPhone, iPad bin/jumphp apple <id> (macos / ios) the game as native Apple apps (.dmg, .ipa), built and tried on GitHub's Macs, see docs/apple.md

Quick start

Live demo: https://davidnurdin.github.io/jumPhp/ (JUMPBALL in 3D WebGL, hello-webgl, hello-threads, Pong, Breakout).

git clone https://git.jumphp.net/jumphp/jumPhp.git && cd jumPhp
bin/jumphp setup              # Docker images (once, ~3 min)
bin/jumphp install pong       # the game's dependencies
bin/jumphp run pong           # play on the desktop (window + sound)

In the browser:

bin/jumphp engine:build       # WebAssembly engine (once per machine, ~25 min, cached afterwards)
bin/jumphp build pong         # -> games/pong/dist/web (static files)
bin/jumphp serve pong         # http://localhost:8080 (served by FrankenPHP)

Pong: arrows + Enter in menus, W / S (player 1), Up / Down (player 2), Escape or P = pause, F11 fullscreen, F3 FPS. Online: bin/jumphp relay up, then "Online" → "Quick match" in two windows (desktop and / or browser).

Make a game

bin/jumphp new my-game "MY GAME"   # copy of skeleton/ (a small platformer)
bin/jumphp install my-game
bin/jumphp test my-game            # lint, phpstan, phpunit, 600 headless frames
bin/jumphp shot my-game 60         # headless PNG: games/my-game/var/screenshots/shot.png
bin/jumphp run my-game

A game = scenes (src/Scene: title, play, pause...) and entities (src/Entity), plus three config files (config/project.yaml, input.yaml, lang.yaml). No asset is required: built-in bitmap font, pixel art in code, synthesized sounds.

With an AI: AGENTS.md holds everything an agent (Claude Code, etc.) needs to build a game from scratch without knowing the project: rules, commands, API, recipes, checks. The games/breakout brick breaker was written that way, by an AI that had only read this file.

Repository

Folder Content
bin/jumphp the command line (bin/jumphp help)
engine/ the framework (composer package jumphp/engine, namespace JumPHP\)
skeleton/ the game template copied by bin/jumphp new
games/pong/ reference game: against the computer, two players on one keyboard, online
games/breakout/ brick breaker written by an AI from AGENTS.md
games/hello-threads/ threads POC (TrueAsync): a fractal computed by a thread pool
games/hello-desktop/ a desktop application (Tauri): a notepad, HTML page + PHP
games/hello-hybrid/ a hybrid game: an SDL game + an HTML control panel, native dialogs, tray icon
skeleton-app/, tauri/ the desktop app template (bin/jumphp app:new) and its native runtime (Rust + Tauri 2, driven by PHP through FFI)
docker/ WebAssembly engine, desktop runtimes (PHP 8.5, and PHP 8.6 ZTS + TrueAsync), network relay, FrankenPHP web server
tools/ scripts used by bin/jumphp (packaging, screenshots, checks)
docs/ detailed documentation (French)

Commands

Command What it does
init (or bin/jumphp alone) wizard: tools, game, engine, server, GitHub, Claude Code
setup [async] builds the Docker images (async: also the PHP 8.6 ZTS + TrueAsync runtime)
engine:download / engine:build the WebAssembly engine in build/engine/: downloaded (GitHub release) / built (~25 min)
update merges the newest JumPHP into the project
new <game> ["Title"] new game from the skeleton
install <game> / composer <game> ... composer dependencies (pure-PHP packages only)
run <game> play on the desktop (X11 or Wayland, PulseAudio / PipeWire, GPU when available)
test <game> / test engine game checks / engine tests
shot <game> [frames] headless screenshot
build <game> browser build (dist/web, put it on any static host)
serve <game> [port] serves the browser build with FrankenPHP
webshot <game> tests the browser build in headless Chrome
relay up|down|logs multiplayer server on ws://localhost:8090/ws
export:desktop <game> a Docker image that runs the game
export:standalone <game> [--linux] [--windows] the game as one executable, nothing to install (PHP, SDL, OpenGL, OpenAL inside), see docs/standalone.md
app:new / app:run / app:test / app:shot / app:export <app> desktop applications: native windows with HTML / CSS / JS pages, logic in PHP (Tauri, native: Linux, Windows, macOS; ui: hybrid for a game), see docs/tauri.md
deploy:setup / deploy [games...] sets up / deploys to your server (FrankenPHP alone or with Traefik, Let's Encrypt HTTPS); without a server: rsync to JUMPHP_DEPLOY_TARGET
server:setup / server:logs installs Docker on the server / web server logs
github puts the project on GitHub (gh), optionally on GitHub Pages
pages [games...] builds the games (default: all) and publishes them with a home page on GitHub Pages (gh-pages branch, replaced each time)
lint / doctor checks the whole repository / diagnoses the machine

make run GAME=pong etc. also exists (Makefile).

How it works

  • Desktop: PHP 8.5 CLI + SDL2 / SDL_image / SDL_mixer / SDL_ttf, OpenGL (php-opengl) and OpenAL (php-openal) extensions, in Docker, using the host's display and sound. ReactPHP loop, Symfony DI container, Evenement events.
  • Browser: the same PHP 8.5 and extensions compiled to WebAssembly with emscripten (php-wasm-sdl): OpenGL becomes WebGL, OpenAL becomes Web Audio, and 3D code is written once for both targets. The browser calls one PHP frame per requestAnimationFrame. Saves go to IndexedDB. The game is a static folder.
  • Network: php-wasm-network — same API natively and in the browser (WebSocket / WebRTC), with its relay server.
  • Web server: FrankenPHP (Caddy + PHP). Games are static; FrankenPHP is there to host the PHP side of the future games portal (accounts, scores...).
  • Threads (optional): runtime: async in project.yaml runs the game on PHP 8.6 ZTS + TrueAsync: $this->engine->tasks() sends heavy work to real threads, the frame never waits. In the browser the same API uses a pool of Web Workers (one PHP WebAssembly engine each); on the default runtime it spreads the work over the frames. See docs/async.md (French), AGENTS.md §9 and games/hello-threads.

Browser constraints (see AGENTS.md §2): never block the frame (sleep, endless loops), 32-bit integers, network only through JumPHP\Net, write files only into var/.

With Claude Code: the JumPHP pane

The jumphp-live mod (claude-mod/jumphp-live/) gives Claude Code a pane beside the conversation: the checks of bin/jumphp test live and the game's screen while it runs (✔ / ✘ per step, the failing PHPUnit tests), the screenshots Claude takes and looks at, the playground's test runs; buttons to run the tests again, take a screenshot or ask Claude for a fix, and a field to write to it. In Claude Code:

/plugin install jumphp-live --marketplace davidnurdin/jumPhp

then /jumphp <game> in the project.

Documentation

  • docs/tutorial.md: the tutorial from A to Z
  • AGENTS.md: the complete guide (English), for humans and AIs alike
  • docs/tauri.md: desktop applications (Tauri): HTML pages, PHP behind them, native dialogs, export
  • docs/: architecture, build, browser pitfalls, tiles and collisions, network, porting, portal (French)
  • dsk2jumphp: remake an Amstrad CPC game from its disc (emulator, extraction tools, AI skill)