Point launcher, fused build, docs, and gitignore at the relocated Switch port tree.
9.1 KiB
Build Gen1Recomp for Nintendo Switch
Want to play a release build instead? Download the SD-ready zip and extract it at your microSD root. See switch-install.md.
This guide is for contributors who build Gen1Recomp for Switch from source.
Releases ship
gen1recomp-*-switch.zip(SD tree underswitch/gen1recomp/). Runtime target is pinned love-nx11.5-nx1. Player install and limitations: switch-install.md.
Prerequisites by OS
All packaging entrypoints are bash. On Windows, use Git Bash, MSYS2, or WSL, not cmd.exe or PowerShell (AD-008).
macOS / Linux
-
Install devkitPro pacman.
-
Install Switch tools (required for
--fused):sudo dkp-pacman -S switch-dev -
OTA launcher toolchain, native or Docker (either is fine):
bash scripts/switch/install_devkitpro_deps.sh # native # or install Docker (same pin as fused builds) -
Ensure
DEVKITPROis exported (typical macOS:/opt/devkitpro) andnacptool/elf2nroare onPATH(or under$DEVKITPRO/tools/bin).
Fused game builds can also use Docker when native nacptool/elf2nro are absent.
Native OTA launcher (included in --fused)
In-console OTA uses a separate DEVKITPRO NRO (not LÖVE). The LÖVE
self-updater (Check.lua) is disabled on NX. Source:
ports/switch/ota-launcher/. Host protocol tests (no toolchain):
make -C ports/switch/ota-launcher host-test
# or
scripts/switch/build_ota_launcher.sh # host-test first; NRO needs DEVKITPRO/Docker
--fused always builds the fused game, native OTA launcher, and dual-NRO SD
zip. The same *-switch.zip is the OTA download asset. DEVKITPRO is
required. OTA launcher: native packages or Docker. Both are supported.
Release-like build from repo root:
scripts/build_switch.sh --fetch --fused --version X.Y.Z
See ports/switch/ota-launcher/README.md and
scripts/switch/ota_launcher.manifest.
Windows (Git Bash / MSYS2 / WSL)
- Use a bash environment:
- MSYS2 with the devkitPro
packages (preferred for native
nacptool/elf2nro), or - WSL (Ubuntu/etc.) with the Linux pacman flow above, or
- Git Bash for
--fetch/--loose; for--fusedprefer MSYS2 or WSL if Docker bind-mounts from Git Bash paths misbehave.
- MSYS2 with the devkitPro
packages (preferred for native
- Install
switch-dev(or rely on Docker fallback; see below). - Do not expect
scripts/build_switch.shto run under cmd/PowerShell.
What you must install yourself
| You install | Script does not install |
|---|---|
| bash, git, zip tooling the repo already expects | (none) |
dkp-pacman + switch-dev + OTA packages or Docker |
dkp-pacman -S … |
A legal .gb ROM (to play) |
Any ROM or game data |
Mode glossary
scripts/build_switch.sh supports three modes (combinable as noted):
| Mode | What it does |
|---|---|
--fetch |
Downloads pinned love.nro + love.elf into .bazinga/love-nx/11.5-nx1/ and verifies SHA-256 against scripts/switch/love-nx-11.5-nx1.sha256. |
--loose |
Packs game.love, copies pinned love.nro → dist/switch/loose/ as gen1recomp.nro + game.love side by side. Needs the pin. |
--fused |
Builds fused game NRO, OTA launcher NRO, and dual-NRO SD zip. Requires DEVKITPRO + switch-dev. OTA launcher: native packages or Docker. GitHub Releases publish the zip only. |
Rules:
--fetchalone is fine; combine as--fetch --looseor--fetch --fused.--looseand--fusedare XOR. Pick one packaging path per run.--version X.Y.Zsets the NACP / filename version (defaults to short git SHA).
What --fetch downloads
Only the two pinned love-nx release assets (love.nro, love.elf). It does
not install:
- devkitPro /
dkp-pacman/switch-dev - Docker
- ROMs, saves, or mods
Native tools, then Docker
Fused packaging (scripts/switch/build_fused.sh):
- Prefer native
nacptool+elf2nroonPATH(or$DEVKITPRO/tools/bin). - Else fall back to Docker using:
GEN1_DKP_IMAGEif set, otherwise- the image named in
scripts/switch/dkp-docker.image(defaultdevkitpro/devkita64:latest).
If neither native tools nor Docker work, the script exits non-zero with macOS / Linux / Windows / Docker hints and a pointer to this doc.
Example commands
From the repo root:
# Download pinned love-nx only
scripts/build_switch.sh --fetch
# Loose pair for iteration (fetch + assemble)
scripts/build_switch.sh --fetch --loose
# Fused game + OTA launcher + dual-NRO SD zip for a release-like artifact
scripts/build_switch.sh --fetch --fused --version 0.2.0
Outputs land under dist/switch/ (and dist/switch/loose/ for loose mode).
The fused path also writes gen1recomp-<ver>-switch.nro (game),
gen1recomp-<ver>-launcher.nro, gen1recomp-<ver>-game.nro,
gen1recomp-<ver>-switch.nro.sha256, and gen1recomp-<ver>-switch.zip
(+ .sha256 sidecar for the zip).
Offline packaging smoke (no network, no nacptool required):
bash scripts/switch/selftest_build_switch.sh
bash scripts/switch/verify_payload.sh --self-test
CI and release
Switch packaging has three automated surfaces (same policy as AD-010):
Path-gated PR / push CI (.github/workflows/ci.yml)
When a change touches Switch packaging / Switch docs / NX runtime paths
(scripts/build_switch.sh, scripts/switch/**, docs/switch-*.md,
tests/switch_ci_workflows_test.lua, tests/switch_transfer_docs_test.lua,
the NX runtime modules src/core/NxAssetOverlay.lua, src/core/Platform.lua,
src/core/GameVersion.lua, src/import/CacheFs.lua, the NX engine suites
tests/engine/assets_version_fallback_test.lua,
tests/engine/nx_generated_guard_test.lua,
tests/engine/nx_yellow_boot_test.lua,
tests/engine/switch_diagnostics_test.lua, tests/engine/platform_nx_*,
or the Switch-related workflow YAML), CI runs:
- Offline selftest on
ubuntu-latest(forks and the main repo):scripts/switch/selftest_build_switch.sh,scripts/switch/verify_payload.sh --self-test,luajit tests/switch_ci_workflows_test.lua,luajit tests/switch_transfer_docs_test.lua, and the NX engine suites headlessly (luajit tests/engine/assets_version_fallback_test.lua,luajit tests/engine/nx_generated_guard_test.lua,luajit tests/engine/nx_yellow_boot_test.lua). - Fused NRO build only on the main repository
(
bryanthaboi/gen1recomp), on the self-hosted Mac runner (scripts/build_switch.sh --fetch --fused), and only when the workflow head is that repo (same-repo push/PR). Fork CI never runs fused. Fork PRs into the main repo also skip Switch fused (offline selftest still runs) so untrusted head code is not executed on the self-hosted Mac; iOS device build eligibility is unchanged. Fused also waits for a successful offline selftest before starting on the Mac runner. - On successful PR fused builds, a follow-up workflow posts a PR comment
linking the Actions artifact named
gen1recomp-switch-nro(comment tagswitch-build-result; see.github/workflows/switch-artifact-comment.yml).
Unrelated PRs do not burn the self-hosted Mac on Switch packaging.
Release hard-fail (.github/workflows/release.yml)
GitHub Releases always build Switch on the same self-hosted Mac runner as the
other platforms. This is a hard gate (no continue-on-error):
scripts/build_switch.sh --fetch --fused --version "<release version>"
A Switch packaging failure fails the entire release job. The release asset is
gen1recomp-<ver>-switch.zip (SD-ready); the versioned .nro stays under
dist/switch/ for the packer and for PR CI artifacts.
Runner provisioning
The self-hosted Mac runner must have DEVKITPRO installed and exported.
--fused preflight fails early with setup steps if it is missing.
One-time setup on the runner (if not already present):
# devkitPro pacman installer from https://devkitpro.org/wiki/devkitPro_pacman
sudo dkp-pacman -S switch-dev
export DEVKITPRO=/opt/devkitpro
export PATH="$DEVKITPRO/tools/bin:$PATH"
# OTA launcher: pick one
bash scripts/switch/install_devkitpro_deps.sh # native
# or ensure Docker is installed (same pin as fused builds)
CI and release still run scripts/build_switch.sh --fetch --fused. Preflight
requires DEVKITPRO and either native OTA packages or Docker. Without all of
that, the job fails with the setup steps above. Scripts never auto-run
dkp-pacman -S during CI.
Limitations / non-goals
These scripts and this guide do not:
- Push files to the console (no automated MTP / FTP / SD scripting)
- Bundle or download any Pokémon ROM
- Install
dkp-pacman/switch-devfor you - Provide
nxlink/ netloader deploy (deferred; see switch-transfer.md) - Validate Applet Mode. Use title override (hold R) for full memory
Player install steps: switch-install.md.
Manual transfer (MTP / SD / FTP, macOS / Linux / Windows):
switch-transfer.md.