A 2D side-view turn-based artillery duel in Python + pygame. One human vs. one AI, best-of-five, destructible terrain, per-round wind, three difficulty levels.
Featuring a vibrant cyberpunk visual overhaul with procedural particle systems, screen shake, glowing neon artillery, and distinct team fire/impact sounds.
micromamba create -p ./.venv -c conda-forge -y python=3.13 pygame pytest
.venv/bin/python main.py(Plain python -m venv + pip install -r requirements.txt works too.)
| key | action |
|---|---|
| ← / → | aim angle |
| ↑ / ↓ | power |
| Space | fire |
| Tab | cycle shell type |
| 1 / 2 / 3 | menu — Easy / Medium / Hard |
| R | next round (after a round) / back to menu (after a match) |
| M | toggle audio |
| ESC | quit |
The game features an intelligent, multi-OS hybrid audio architecture that uses afplay natively on macOS to ensure absolute zero-latency playback. However, if you are using an Apple HomePod, AirPods, or any Bluetooth/AirPlay speaker, you will still experience up to a 2-second audio delay. This is an unavoidable hardware-level buffer introduced by AirPlay streaming over Wi-Fi/Bluetooth. To experience true zero-latency audio sync, plug wired speakers or headphones directly into your Mac.
.venv/bin/pytest tests/ -qThe game can be compiled to WebAssembly with pygbag so it runs in a browser tab.
.venv/bin/pip install pygbag
.venv/bin/python -m pygbag --build --width 1024 --height 640 --title "Tank Game" main.pyThe static bundle lands in build/web/ (~60 KB plus the standard pygbag runtime, fetched from CDN at first load). For a local browser test, drop --build and visit the URL pygbag prints. To publish on itch.io, zip build/web/, create a new project marked "HTML", and upload the zip with "This file will be played in the browser" checked.
pygbag.ini excludes .venv, tests, docs, and other dev directories from the bundle so only the source is shipped.
If the browser build misbehaves (grey/red screen, audio missing, stuck on load), see docs/browser-build.md for the gotchas we hit and how each one is worked around.
The web bundle can be pushed to a public itch.io page via butler (itch's CLI).
One-time setup:
- Create the project page on itch.io (web UI). Kind: HTML; remember the slug — it must match
fableworks/tank-2d(or setITCH_PROJECT). - Install butler. Note:
brew install butlerinstalls an unrelated Mac app (Butler.app) — itch.io's butler isn't on Homebrew under that name. Download the binary directly from itch's CDN:On Linux, swapARCH=$(uname -m); [ "$ARCH" = "arm64" ] && CH=darwin-arm64 || CH=darwin-amd64 mkdir -p ~/.local/bin && cd /tmp curl -fL -o butler.zip "https://broth.itch.zone/butler/${CH}/LATEST/archive/default" unzip -o butler.zip && chmod +x butler && mv butler ~/.local/bin/ grep -q '.local/bin' ~/.zshrc || echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.zshrc exec zsh && butler -V
darwin-arm64/darwin-amd64forlinux-amd64. - Get an API key from https://itch.io/user/settings/api-keys and export it in your shell:
echo 'export BUTLER_API_KEY=your-key-here' >> ~/.zshrc && source ~/.zshrc
Local one-liner:
scripts/deploy-itch.sh v0.1.1Builds the bundle and pushes to troyscott/tank-2d:html5 with the given userversion label. Override ITCH_PROJECT, ITCH_CHANNEL, or PYTHON via env if needed.
Auto-deploy on GitHub release:
.github/workflows/deploy-itch.yml triggers when you publish a GitHub release (or via the Actions tab → "Run workflow"). It needs the API key as a repo secret:
- GitHub → Settings → Secrets and variables → Actions → New repository secret → name
BUTLER_API_KEY, value = your itch API key.
After that, gh release create v0.1.1 --target main --title "..." --notes "..." will produce a build on itch.io within ~30 seconds.
70 tests cover terrain generation + craters, projectile physics, shell selection, damage falloff, AI solver convergence, input routing, state transitions, tank behavior, and match-flow logic.
See specs/SPEC.md for the full design and the slice-by-slice build roadmap. The architecture diagram is in specs/tank_artillery_architecture_v2.svg.
MIT — see LICENSE.
