Developer setup
Running from a source checkout, the optional developer data build, the test suites, and cache management. Players using the packaged app need none of this; see Start Playing.
Choose your route
Use the packaged app if you only want to play or install mods. Use this page when you have a source checkout and want to run tests, rebuild imported data, or package a development build. You need Python 3 for setup and data tools, LÖVE 11.x to run the game, and a legally obtained ROM for importing game data. Keep the ROM outside version control.
Run the commands below from the engine repository root: the folder containing
tools/, src/, and scripts/. If you are following a guide from a wiki
checkout, change directory to the engine checkout first. The setup script
prints its next command; keep that terminal location for the rest of the
workflow.
First run
- Run
love .from the engine root. The launcher imports any of the eleven games (Red to Emerald) from your ROM into a per-version cache, exactly as the packaged app does. - Optionally run the Gen 1 setup script below, which builds Red, Blue or
Yellow data into the source tree and is what
scripts/run.shexpects. - Add
POKEPORT_DEV=1only when you are developing a mod. - Run
scripts/test.sh --quickbefore a longer test run.
If setup reports that it cannot find Python, LÖVE, or the ROM, fix that
requirement and run the same command again. The script creates .venv/ and
generated data under the checkout; these are working files, not mod content.
Source checkout
Requires LÖVE 11.x. For the Gen 1 source-tree build, place a legally
obtained US Red, Blue or Yellow ROM in the project folder and double-click
Play-Mac.command or Play-Windows.bat, or run:
scripts/setup.sh --rom "/path/to/Pokemon Red.gb"
scripts/run.sh
Windows PowerShell:
powershell -ExecutionPolicy Bypass -File scripts\setup.ps1 -Rom C:\path\red.gb
powershell -ExecutionPolicy Bypass -File scripts\run.ps1
The setup scripts also accept ROM_PATH. With no argument, they use the
first .gb or .gbc file in the project root. Gen 2 and Gen 3 have no
setup-script path; import them in the launcher, or headless with
tools/reimport.sh <version> [--identity NAME] [--rom PATH]. After setup:
love .
Controls: arrow keys or WASD move; Z, Enter, or Space is A; X or Backspace is B; Escape opens START. F1 saves and F2 loads on every generation; F10 toggles the mod manager on Gen 1. Controllers are supported.
Dev mode
Run with POKEPORT_DEV=1 for the mod-development loop: F5 hot-reloads
mod content and the backtick opens the dev console (both Gen 1 only), and
undeclared engine requires from mods log attributed warnings
(Getting Started). --game=<id> (or POKEPORT_GAME) boots one
game directly, and POKEPORT_VERSION=<id> picks the game for scripted and
headless runs; POKEPORT_IDENTITY=<name> points the run at a separate
save directory so tests never touch your real saves.
Developer data build
The in-app importer is all a player needs. For Gen 1 development and parity checks there is an optional Python build that produces the data modules and PNGs in the source tree:
python3 -m pip install pillow
python3 tools/build_data.py --rom "/path/to/Pokemon Red.gb" --clean
Requirements: Python 3.10+ and Pillow. It accepts Red, Blue and Yellow
only (--version auto|red|blue|yellow). The packaged app does not use
this path.
Test suites
scripts/test.sh is the unified entry point: it runs every tier this
checkout can run and exits non-zero if any fails. Tiers that need only
the committed fixture dataset (tests/fixture_data/) run anywhere,
including a ROM-less CI box; the content tier asserts real game facts
and is skipped automatically until the ROM has been imported.
scripts/test.sh # every tier this checkout can run
scripts/test.sh --quick # fast parallel smoke run (tests/quick.list)
scripts/test.sh --standard # every tier except the slow content tier
scripts/test.sh --list # show the selected tiers without running them
scripts/lint.sh --gate # luacheck, the codes CI blocks on
Tests that need an imported game read it from POKEPORT_TEST_CACHES (one
identity holding a cache per version) or skip when none exists.
Single tiers (LUA=luajit is the default interpreter; the engine targets LuaJIT / Lua 5.1 semantics):
luajit tests/run_engine.lua # engine invariants + parity gates (ROM-free)
luajit tests/run_modkit.lua # mod SDK (ROM-free)
luajit tests/run_tests.lua # content behavior; needs data/generated/
luajit tests/run_gen2.lua # Gen 2 suites
luajit tests/run_save_editor_tests.lua # save editor logic/panel tests
luajit tests/run_save_compat.lua # save conversion and compatibility
luajit tests/run_link_tests.lua # link play loopback lockstep; needs data/generated/
for t in tests/game3_*.lua; do luajit "$t" >/dev/null 2>&1 || echo FAIL "$t"; done # Gen 3
The content suite must end with ALL TESTS PASSED, the link suite with
ALL LINK TESTS PASSED.
Deleting generated files (macOS)
Use this only when you are intentionally rebuilding a cache. Close the game
first and confirm the paths before running these commands: rm -rf permanently
removes the generated files at those locations. It does not restore a missing
ROM, so keep the original ROM available for the next launch.
Each imported game keeps its own cache under the LÖVE save directory, in
a folder named for its version id (red/ through emerald/). Gen 1 and
Gen 2 folders hold data/generated/ and assets/generated/, Gen 3 folders
hold data/, and each has a rom-cache.complete marker once imported.
rm -rf data/generated assets/generated
cd "$HOME/Library/Application Support/LOVE/pokemon-love2d"
rm -rf red blue yellow gold silver crystal firered leafgreen ruby sapphire \
emerald data/generated assets/generated rom-cache.complete
(The last three paths cover a pre-multi-game install's flat cache.) The next launch re-imports from the ROM. On Linux and Windows the cache lives under the LÖVE save directory listed in Save Editor.
Packaging builds
scripts/build.sh [mac|win|linux|android|ios|all] packs game.love
(engine, data, the save editor, and the ROM manifests; never
*/generated/) and fuses it onto each platform's LÖVE 11.5 binary, writing
distributables into dist/ (dist/mac/gen1recomp-macos.zip,
dist/win/gen1recomp-win64.zip,
dist/linux/gen1recomp-linux-x86_64.AppImage, the Android APK under
dist/android/, the iOS app under dist/ios/). --version X.Y.Z stamps
the release version, --game-love PATH fuses a payload prebuilt by
scripts/pack_love.sh, and --release / --ipa apply to iOS; signing and
notarization flags are documented in the script header. Other targets have
their own scripts beside it: build_windows.ps1, build_flatpak.sh,
build_linux_arm64.sh, build_switch.sh, build_ps4.sh and
build_xbox_uwp.sh.
After a build, inspect dist/ for the platform artifact named above. One
Windows-specific asset: gen1tls.dll, the native TLS dialer that
gives mods love.system.tlsOpen/tls* for wss:// connections. CI
builds it (native/tls_dial/) and build.sh bundles it into the
Windows zip from dist/native/win-x64/gen1tls.dll (or GEN1TLS_DLL).
A local Windows package without it still runs; the build warns and
wss:// stays unavailable.
Layout
tools/ ROM decoder, save editor, modkit, verification tools
data/generated/ generated Lua game data (gitignored)
data/scripts/ hand-ported map behavior
assets/generated generated graphics and compact audio cache (gitignored)
src/ hand-written LÖVE engine
scripts/ setup, run, and packaging helpers
mobile/ Android and iOS build trees
tests/ headless behavior and parity suites
docs/ architecture, behavior notes, and platform docs
mods/ native mods (examples in mods/examples/)
docs/architecture.md covers runtime details. Gen 2 code sits in the
gen2/ subfolders of src/battle, src/world, src/ui and in
src/core/gen2; Gen 3 in src/core/game3, src/battle/game3,
src/world/game3, src/ui/game3 and the GBA importer src/import/gba.
Check and recover
The first launcher run should import the game you chose; after the
optional setup script .venv/ and source-tree data exist too. Then scripts/test.sh --quick should finish with its normal test summary and a zero exit status. If
setup or a test fails, keep the printed error, fix the named prerequisite or
test fixture, and rerun the same command from the engine root; delete generated
cache directories only when intentionally rebuilding them.
Start here
Playing
Tutorials
- Choose a tutorial
- 01 Sprite and Text Tweak
- 02 Balance Patch
- 03 New Species
- 04 New Item and Ball
- 05 New Move
- 06 NPC and Dialogue
- 07 New Map
- 08 Quest
- 09 Custom Music
- 10 New Mechanic
- 11 Custom UI Screen
- 12 Mini Total Conversion
Creative guides
Concepts
Recipes and reference
Author and developer tools
Home · Start Playing · Glossary · Troubleshooting · Repository · Community
Game data is imported locally from a supported ROM supplied by the player. Shared mods contain original work or transform recipes, never extracted game content. Check each guide's target game before using its examples.