5 Guide Developer Setup
bryanthaboi edited this page 2026-10-21 17:34:48 -04:00

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

  1. 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.
  2. Optionally run the Gen 1 setup script below, which builds Red, Blue or Yellow data into the source tree and is what scripts/run.sh expects.
  3. Add POKEPORT_DEV=1 only when you are developing a mod.
  4. Run scripts/test.sh --quick before 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.