Porypal is a sprite tool for Pokémon Gen 3 ROM hacking (pokeemerald, pokefirered, pokeemerald-expansion).
The GBA can only display 16 colors per sprite. This is a hardware limitation, not 16 colors total, but 16 per palette, and every sprite has to use exactly one.
This means you can't just export a PNG from your art program and drop it into the game. Your sprite needs two things first:
- A palette: a
.palfile listing the 16 colors your sprite is allowed to use - A converted sprite: every pixel remapped to the nearest color in that palette
Porypal handles both.
- Import a sprite to extract a palette (
sprite.pal) from it. - Automatically detects the sprite's transparent/background color.
- Reduces the sprite's colors down to 16, so it's ready for insertion.
- Import a sprite to see it converted against every palette in your library at once.
- The best-matching palettes are automatically highlighted and applied.
- Download the converted
sprite.png, ready for use with the selected palette.
- Create a Shiny Palette
- Import
sprite.png+shiny_sprite.pngto get two index-aligned palettes (normal.palandshiny.pal).
- Import
- Create a Shiny Sprite
- Import
sprite.png+normal.pal+shiny.palto get ashiny_sprite.png.
- Import
- Slice a spritesheet into tiles and rearrange them into any layout you want.
- Save layouts as presets and reuse them across spritesheets of the same dimensions.
- Build a multi-step pipeline (Extract Palette, Apply Tileset, Apply Palette) and run it across an entire folder.
- Results download as a zip with a per-file summary.
- Manage the palettes available across the app in one place.
- Upload your own
.palfiles or import palettes from the built-in library, organised by game and category.
Group Operations
- Group Extract
- Import multiple sprites (Pokeballs, Z-Crystals, Mega Stones) and automatically group them by silhouette (same shape = same group).
- Within each group, colors that appear across most sprites are locked to the same palette slot index, so swapping palettes in-game works more smoothly.
- Variants
- For sprites that share the same pixel art but use different palettes in-game (e.g., Potion, Super Potion, Hyper Potion), import all the recolored versions and define one as the reference.
- Produces one index-aligned palette per sprite (
potion.pal,super_potion.pal,hyper_potion.pal).
| Tool | Minimum version | Download |
|---|---|---|
| Python | 3.10+ | https://python.org |
| Node.js | 18+ | https://nodejs.org |
| Git | any | https://git-scm.com |
Linux / macOS
git clone https://github.com/Loxed/porypal.git
cd porypal
chmod +x scripts/setup.sh scripts/run.sh
./scripts/setup.shWindows (PowerShell)
git clone https://github.com/Loxed/porypal.git
cd porypal
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass
.\scripts\setup.ps1Setup installs Python dependencies, builds the frontend, and creates the required folders. It only needs to be run once.
Linux / macOS / WSL
./scripts/run.shWindows
.\venv\Scripts\Activate.ps1
python main.pyThen open http://127.0.0.1:7860 in your browser. The browser opens automatically.
WSL users: the browser won't open automatically. Run
./scripts/run.shand open http://127.0.0.1:7860 in your Windows browser manually.
python main.py --port 8080 # use a different port
python main.py --no-browser # don't open the browser automatically
git pull
./scripts/setup.shporypal/
├── docs/ # Documentation and testing notes
├── frontend/ # React + Vite web UI
├── model/ # Pure Python -- palette, image, and tileset logic
├── palettes/
│ ├── defaults/ # Read-only shipped palettes
│ └── user/ # Your palettes (managed from the UI)
├── palette_library/ # Browseable library, organised by game/category
├── presets/ # Saved tileset layout presets (JSON)
├── scripts/
│ ├── run.sh # Launch the app (Linux/macOS/WSL)
│ ├── setup.sh # One-time setup (Linux/macOS/WSL)
│ └── setup.ps1 # One-time setup (Windows)
├── server/ # FastAPI backend
│ └── api/ # One file per feature
├── tests/ # pytest test suite
├── LICENSE
├── main.py # Entry point -- starts the server
├── readme.md
└── requirements.txt
This project is licensed under the GNU General Public License -- see the LICENSE file for details.
For questions or support, reach out to prison_lox on Discord.
Example sprites used in the tileset editor come from:
- Gen 5 Characters in Gen 4 OW style 2.0 by DiegoWT and UltimoSpriter
- ALL Official Gen 4 Overworld Sprites v1.5 by VanillaSunshine







