Train a reinforcement learning agent to play Jetpack Joyride on PPSSPP (PSP emulator) using PPO and screen capture.
- ๐ฎ Real-time training on PPSSPP emulator via screen capture
- ๐ข OCR-based rewards using distance/score extraction
- ๐ผ๏ธ Tkinter calibration GUI for region selection
- ๐ TensorBoard + Weights & Biases logging
- ๐พ Checkpoint support - resume training anytime
- ๐ง Network visualization - see the CNN architecture
- ๐ Capture diagnostics - diagnose background capture issues
| Limitation | Details |
|---|---|
| Windows only | Uses pywin32 for capture and input |
| Input requires focus | Keyboard events need PPSSPP in foreground; --background helps with capture, not input |
| DPI scaling | Tested at 100%; higher scaling may need verification |
| PrintWindow + Vulkan | Background capture may fail with Vulkan renderer; use D3D11 |
- Python 3.10+
- PPSSPP Emulator: Download here
- Jetpack Joyride PSP ROM (
.isoor.cso) - Tesseract OCR (optional, for score extraction)
# Option A: Using winget
winget install UB-Mannheim.TesseractOCR
# Option B: Manual download
# https://github.com/UB-Mannheim/tesseract/wikicd jetpack_joyride_rl
pip install -r requirements.txtOpen PPSSPP โ Settings โ Controls โ Control Mapping:
| Action | Recommended Key |
|---|---|
| Cross (โ) / Boost | Z |
| Start | Enter |
python ppsspp_jetpack_rl.py --launchOr open PPSSPP manually and load the ROM.
python ppsspp_jetpack_rl.py --calibrateA Tkinter window opens. Click and drag to select the game area, then click "Save".
python ppsspp_jetpack_rl.py --play-randomRuns 30 seconds of random play to verify everything works.
# Short test run
python ppsspp_jetpack_rl.py --train --timesteps 10000
# Full training with logging
python ppsspp_jetpack_rl.py --train --timesteps 300000 --wandbRun these commands to verify your setup:
# 1. Run tests (no PPSSPP required)
python -m pytest tests/ -q
# 2. Check capture reliability (PPSSPP required)
python ppsspp_jetpack_rl.py --diagnose-capture
# 3. Test keyboard input (PPSSPP required)
python ppsspp_jetpack_rl.py --play-random| Flag | Description |
|---|---|
--launch |
Launch PPSSPP with configured ROM |
--calibrate |
Open Tkinter GUI to set game capture region |
--calibrate-score |
Set OCR region for score extraction |
--play-random |
Run 30s of random actions (test mode) |
--capture-gameover |
Capture game-over template for detection |
--diagnose-capture |
Test capture reliability (foreground & background) |
--train |
Start PPO training |
--timesteps N |
Training duration (default: 300000) |
--resume PATH |
Resume training from checkpoint |
--eval PATH |
Run trained model (no training) |
--wandb |
Enable Weights & Biases logging |
--visualize-network |
Render CNN architecture diagram |
--background |
Enable background capture (BitBlt) |
- Make sure PPSSPP is running
- Check that window title contains "PPSSPP"
- DPI Scaling: If using >100% scaling, try setting Windows display to 100%
- Multi-monitor: Ensure PPSSPP is on primary monitor, or recalibrate
- Run
--diagnose-captureto check for capture issues
- PPSSPP Vulkan renderer doesn't support PrintWindow
- Fix: Settings โ Graphics โ Backend โ Direct3D 11
- Run
--diagnose-captureto verify
- Recalibrate score region with
--calibrate-score - Ensure Tesseract is installed and in PATH
- Try adjusting the game's display settings
- Reduce
agent_hz(fewer decisions/second) - Consider that input always requires focus
- Train for longer (300k+ timesteps minimum)
- Check that game-over detection works (
--capture-gameover) - Verify reward is being tracked in TensorBoard
- This should be fixed (try/finally protection added)
- If it happens, press the stuck key to unstick it
jetpack_joyride_rl/
โโโ ppsspp_jetpack_rl.py # Main script
โโโ backends.py # Capture/Input/Window protocols
โโโ requirements.txt # Python dependencies
โโโ pyproject.toml # Project configuration
โโโ README.md # This file
โโโ ppsspp_capture_config.json # Saved capture region
โโโ score_roi_config.json # Saved score ROI
โโโ gameover_template.png # Game-over detection template
โโโ spec/ # Specifications
โ โโโ SPEC.md
โ โโโ ACCEPTANCE.md
โ โโโ TEST_PLAN.md
โ โโโ RISKS.md
โ โโโ TRACEABILITY.md
โโโ tests/ # Automated tests
โ โโโ conftest.py
โ โโโ fakes/
โ โโโ test_env.py
โ โโโ test_done.py
โ โโโ test_cleanup.py
โ โโโ test_preprocess.py
โโโ checkpoints/ # Training checkpoints
โโโ models/ # Final trained models
โโโ tb_jetpack/ # TensorBoard logs
# Install dev dependencies
pip install pytest pytest-cov ruff
# Run all tests
python -m pytest tests/ -v
# Run with coverage
python -m pytest tests/ --cov=ppsspp_jetpack_rl
# Lint code
ruff check .MIT License - Feel free to use and modify!
- Stable-Baselines3 for PPO implementation
- PPSSPP for PSP emulation
- Halfbrick Studios for Jetpack Joyride