The classic 1970s Pong game, remade in Java — first to 5 points wins! Originally built for a school ICS4U assignment, then packaged so anyone can play it with a single double-click, no Java install required.
No Java installation required — a trimmed Java runtime ships with the game for every OS.
Easiest — download & play: grab the zip for your operating system from the latest release, unzip it, and run the launcher inside:
| OS | Download | Launch |
|---|---|---|
| Windows | Pong-Windows.zip |
double-click RunMe.bat |
| macOS (Apple Silicon or Intel) | Pong-macOS.zip |
double-click RunMe.command |
| Linux | Pong-Linux.zip |
run ./RunMe.sh |
Or run straight from the repo: clone it (or Code → Download ZIP) and use the same launchers above — they live in the project root.
That's it — the game window opens. No install, no internet, no setup.
macOS note: the bundled runtime is unsigned, so Gatekeeper may block it on first launch (especially if you downloaded the ZIP via a browser, which "quarantines" it). The reliable fix is to open Terminal in the project folder and run once:
xattr -dr com.apple.quarantine . chmod +x RunMe.commandThen double-click
RunMe.command(or run./RunMe.command). Cloning withgitinstead of downloading the ZIP usually avoids the quarantine entirely.
Press space to start the game.
| Move up | Move down | |
|---|---|---|
| Player 1 | w |
s |
| Player 2 | ↑ |
↓ |
A Java program normally needs a JVM installed on the player's machine. To make this game "just work" on a clean computer, a minimal Java runtime travels with the project and each launcher runs the game against it directly.
- Trimmed runtimes via
jlink. Eachruntime/<os>/folder is a custom Java 21 image built withjlink, containing only thejava.desktopmodule the game needs (Swing +javax.sound). That keeps every runtime to ~45–58 MB instead of shipping a full ~300 MB JDK. - All four platforms, built from one machine.
jlinkis host-agnostic — pointed at another platform's modules it emits that platform's runtime — sowindows-x64,linux-x64,macos-aarch64, andmacos-x64are all produced from a single build. - Thin per-OS launchers.
RunMe.bat(Windows),RunMe.command(macOS, auto-selecting Apple Silicon vs. Intel viauname -m), andRunMe.sh(Linux) eachcdto the project folder — so the.wavsound files resolve — then runjava -cp bin Mainon the bundled runtime. - Per-OS release zips. Each release ships a small, single-platform zip built with
git archive, which bakes the tracked Unix executable bits into the archive so macOS/Linux players never needchmod.
See BUILD.md for the full, reproducible build recipe (compiling, jlink, cross-building,
and cutting a release).
Because the macOS and Linux runtimes are cross-built, a
GitHub Actions smoke test verifies them on real hardware —
on every release, and on any change to the runtimes or launchers. It runs on
windows-latest, ubuntu-latest (with an Xvfb virtual display), and macos-latest (Apple Silicon),
and additionally exercises the Intel (macos-x64) runtime on the Apple Silicon runner through
Rosetta 2. For each runtime it:
- checks the bundled runtime reports the right version and includes
java.desktop; - launches the actual game headlessly and asserts it starts and stays running;
- confirms the Unix runtime binaries keep their executable bit after a fresh checkout.
Pong/
├─ src/PingPong/ Java source (Main, GameFrame, GamePanel, Paddle*, PongBall, Score*, Music, End)
├─ bin/ compiled .class files
├─ runtime/
│ ├─ windows-x64/ bundled Java runtimes, one per platform (built with jlink)
│ ├─ linux-x64/
│ ├─ macos-aarch64/
│ └─ macos-x64/
├─ *.wav sound effects and music (Boop, Tap, Victory)
├─ RunMe.bat Windows launcher
├─ RunMe.command macOS launcher (auto-detects Apple Silicon / Intel)
├─ RunMe.sh Linux launcher
├─ BUILD.md how to rebuild the runtimes and cut a release
└─ .github/workflows/smoke-test.yml CI that boots each runtime


