SwitchWaker is an unofficial native port of a 2002 GameCube adventure game (disc ID GZLE01, USA,
revision 0, the reference; and GZLP01, Europe, revision 0, with its five languages) to the Mac,
Linux and the Switch (homebrew). The game is compiled from its decompilation
(the game/ folder) and drawn with Aurora;
there is no CPU emulation.
SwitchWaker would not exist without these projects. The hard part, understanding the game, is their work; this repository adds the layer that runs it on new hardware.
- zeldaret/tww: the community decompilation of the game.
The careful, byte-for-byte matching work of its contributors produced almost all of the code in
game/. Without it there is nothing to port. - snrubrm/tww: a personal fork of zeldaret/tww that completes
the functions still missing, with AI-assisted decompilation (in its author's words).
game/was imported from it; units that zeldaret has since matched are taken from zeldaret again. - encounter/aurora: the GameCube SDK reimplemented over WebGPU (Dawn), which draws the game and reads the controllers on every platform, the Switch included (with encounter's Dawn fork for it).
- Dusklight (TwilitRealm): the native port of a sibling game on Aurora; the model for this project's SDK layer, and CC0 helper code.
- BetterWW (WideBoner) and wwrando (LagoLunatic; with brainfubar, MelonSpeedruns and JarheadHME): the options menu's "Calidad de vida" (quality of life) options are derived from their patches (docs/QOL_PLAN.md).
- Dolphin: its DSP HLE plays the game's audio (
native/dsp_hle/, GPL). - elliotttate/Wind-Waker-Recomp and RecompCore: the static recompilation this work started from, and the DSP adapter.
- devkitPro, libnx and deko3d with uam (whose shader compiler comes from Mesa): the Switch toolchain and its GPU API.
- nx-hbloader, hacBrewPack and hactool: the HOME-menu forwarder.
If you enjoy this port, the decompilation projects above are where the credit belongs. Every component and its license: THIRD_PARTY.md.
Be aware of this before you use or build on this repository:
- This project's own code was written with AI. Nearly all of the code outside
game/(the SDK layer, the run harness, the Switch platform layer, patches, tools and scripts), the documentation and the commit messages were written by an AI coding agent, Anthropic's Claude through Claude Code. The human authors chose what to build, set the priorities, reviewed the code line by line, played and tested it on the Mac and on a real Switch, reported the bugs and decided what went in. Commits written with the agent say so in aCo-Authored-By: Claudeline. - Part of the decompilation is AI-assisted too: the functions snrubrm/tww completed (see
above). The rest of
game/is zeldaret's human work. If you want only human-written decompilation, use zeldaret/tww. - How it is checked: human review of the code, line by line, plus builds on every platform, a regression suite of boot milestones and smoke tests, automated sweeps over every stage, room, actor, event, item and boss (also under AddressSanitizer), and play on hardware (native/README.md). Bugs can still slip through; reports are welcome.
- Your own legally obtained copy of the disc:
GZLE01(USA) orGZLP01(Europe) revision 0, as an uncompressed.iso. The build generates what it needs from it. The version is fixed at build time: the European disc needs the European build (below). - This repository contains no game assets, executables or data. The binaries you build contain code generated from your disc: they are for your own use only; do not share them.
- No release binaries are provided for now, precisely because they carry headers generated from the disc compiled in.
Requirements: Xcode command line tools, brew install cmake ninja python (Python 3.10 or newer)
and the network the first time.
git clone https://github.com/centollOS/SwitchWaker switchwaker && cd switchwaker
export COS_DISC=/path/to/GZLE01.iso # every script and the game read the disc from here
native/tools/fetch_recompcore.sh # ref/recompcore: Dolphin's DSP HLE (audio)
native/tools/gen_assets.sh # build/native-mac/assets/GZLE01: headers from your disc
cmake -S native -B build/native-mac -G Ninja
ninja -C build/native-mac switchwaker # build/native-mac/switchwaker
build/native-mac/switchwaker # a 960x720 windowDetails, run options and tests: native/README.md. Full regression:
native/tools/regress.sh.
The European disc (GZLP01) is a separate build directory with -DCOS_VERSION=3
(docs/PAL_DISC_PLAN.md); its language follows the system's (English, German,
French, Spanish or Italian), COS_GAME_LANGUAGE=en|de|fr|es|it or the options menu fixes one:
export COS_DISC=/path/to/GZLP01.iso
native/tools/gen_assets.sh --version GZLP01 # build/native-mac/assets/GZLP01
cmake -S native -B build/native-mac-eur -G Ninja -DCOS_VERSION=3 \
-DCOS_ASSETS_DIR=$PWD/build/native-mac/assets/GZLP01
ninja -C build/native-mac-eur switchwaker
COS_BUILD_DIR=build/native-mac-eur native/tools/regress.sh # the tools take the build directoryRequirements: clang (GCC is untested), CMake 3.28 or newer, Ninja, Python 3.10 or newer, git, and the development headers SDL 3 needs for its video and audio backends; at run time a Vulkan driver (any GPU's, or Mesa's). On Debian 13 / Ubuntu 24.04:
sudo apt install clang lld cmake ninja-build pkg-config python3 git zlib1g-dev \
libx11-dev libxext-dev libxrandr-dev libxcursor-dev libxfixes-dev libxi-dev libxss-dev \
libxtst-dev libxkbcommon-dev libwayland-dev wayland-protocols libdecor-0-dev \
libegl-dev libgl-dev libgles-dev libvulkan-dev libdrm-dev libgbm-dev \
libasound2-dev libpulse-dev libpipewire-0.3-dev libudev-dev libdbus-1-dev libibus-1.0-dev \
mesa-vulkan-driversThen, as on the Mac but in build/native-linux:
git clone https://github.com/centollOS/SwitchWaker switchwaker && cd switchwaker
export COS_DISC=/path/to/GZLE01.iso
native/tools/fetch_recompcore.sh
native/tools/gen_assets.sh --out "$PWD/build/native-linux/assets/GZLE01" # absolute: the script works in build/decomp
CC=clang CXX=clang++ cmake -S native -B build/native-linux -G Ninja
ninja -C build/native-linux switchwaker # build/native-linux/switchwaker
build/native-linux/switchwakerAurora draws with Vulkan, then OpenGL ES, then nothing (null) if neither works; COS_BACKEND=opengl
(or vulkan, opengles, null) asks for one first. Dawn and nod come as Aurora's prebuilt
packages, SDL 3 is built from source. The regression runs with
COS_BUILD_DIR=build/native-linux native/tools/regress.sh (the link census and the duplicate
symbol census are Mac-only and skipped). Headless (no display, no GPU, e.g. in a container):
COS_ALLOW_CPU_ADAPTER=1 xvfb-run -a native/tools/run.sh title uses Mesa's software Vulkan.
Fullscreen (Linux and the Mac): COS_FULLSCREEN=1 starts fullscreen, and F11 or Alt+Enter
switches between fullscreen and the window while the game runs.
scripts/docker/build.sh builds the Linux binary and/or the Switch NRO entirely in containers, on
Linux, macOS, or Windows (in a WSL 2 shell, with Docker Desktop's WSL integration or Podman). The
host needs only bash, git and Docker or Podman; the disc is bind-mounted read-only and never
copied into an image.
scripts/docker/build.sh linux --disc /path/to/GZLE01.iso # build/native-linux/switchwaker
scripts/docker/build.sh switch --disc /path/to/GZLE01.iso # build/switch-native/switchwaker.nro
scripts/docker/build.sh switch --disc /path/to/GZLP01.iso # build/switch-native-eur/switchwaker-eur.nro
scripts/docker/build.sh all --disc /path/to/GZLE01.iso --test # both, plus headless checksThe Linux binary is built for the container's architecture, which is the host's (x86_64 on a PC,
aarch64 on Apple silicon); --platform linux/amd64 builds the other one under emulation. The disc
decides the version (GZLP01: build/native-linux-eur, build/switch-native-eur). The asset
headers are generated once into build/assets/GZLE01 (build/assets/GZLP01). Downloads stay between runs in the
repository's ignored build/ and ref/ folders (Aurora and its packages in
build/native-linux/_deps, the decompilation and its tools in build/decomp-docker, RecompCore in
ref/recompcore, Dawn's sources in build/switch-native/_deps)
and in the engine's image cache; the first Switch build takes an hour or more, later ones minutes.
scripts/docker/build.sh --help lists every option. On Windows, keep the clone inside the WSL file
system (for example ~/switchwaker), not under /mnt/c: builds there are much slower.
There is no native Windows build yet; it is low priority. Windows users can build the Linux binary (and run it under WSLg) or the Switch NRO with Docker, as above. What a native port would need, and an estimate: docs/WINDOWS.md.
.github/workflows/ci.yml checks what can be checked without a disc: scripts lint, Aurora, the SDK
layer and the run harness built and unit-tested on Linux x86_64 and aarch64, and the Switch build
images cached. It runs only when started by hand (Actions tab, "Run workflow"), to keep the
private repository's Actions minutes. The game itself builds without the disc in the runtime-assets
mode (docs/RUNTIME_ASSETS.md: gen_assets.sh --stubs, -DCOS_RUNTIME_ASSETS=ON;
the data arrays are read from the player's disc at start-up), which the CI job also builds; the default
build still compiles the headers generated from your disc.
Players do not need to build: the release downloads hold the NRO (built without the disc) and its
caches, one download per disc: SwitchWaker-<version>-switch.zip (USA, switchwaker.nro) and
SwitchWaker-<version>-switch-eur.zip (Europe), both installing switch/switchwaker/switchwaker.nro
(one version per SD card); players add their own disc (INSTALL.md). To build it yourself,
scripts/switch/make_sd.sh --disc /path/to/GZLE01.iso checks the disc, builds the NRO in containers and
lays out build/sd/switch/ (NRO, caches, a copy of the disc) for the SD card.
On top of the above: Docker Desktop or Podman. scripts/switch/build_native.sh produces
build/switch-native/switchwaker.nro (the deko3d renderer; Dawn, Aurora and the shader cache are built in
a devkitPro container; --runtime-assets builds it without the disc; --eur builds
build/switch-native-eur/switchwaker-eur.nro, the European version).
Full guide: docs/SWITCH_BUILD.md.
For development there is a debug server: from the computer, over the local network, you can deploy a new build and restart the game without touching the console, follow the log as it is written, take screenshots, press buttons and warp. It is off by default: players never need it and the game opens no network port unless it is turned on in the options menu (Depuración > "Servidor de depuración", at the next start). It has no password, so use it only on your own network.
echo <console ip> > build/switch_host.txt # once; the log prints the address
scripts/switch/build_native.sh && scripts/switch/switchwaker_debug.py deploy # upload, check, restart
scripts/switch/switchwaker_debug.py log # the log, live
scripts/switch/switchwaker_debug.py shot # PNG of the next frame
scripts/switch/switchwaker_debug.py press A # also hold, release, stick, warpdeploy restarts the game, so start it from the HOME-screen icon (forwarder). deploy --eur uploads the
European NRO as switchwaker.nro too; deploy refuses to replace the running game with the other region's
build unless --force. Every command and the
protocol: docs/DEBUG_SERVER.md. It is the same server as SwitchWakerHD's.
- A Switch running custom firmware (Atmosphère) with the Homebrew Menu.
- The release download for your disc (
SwitchWaker-<version>-switch.zipfor USA:switchwaker.nro,initial_pipeline_cache.db,initial_dksh_cache.bin;SwitchWaker-<version>-switch-eur.zipfor Europe: the Europeanswitchwaker.nroand the same two caches), or the same files from your own build (build/switch-native/, orbuild/switch-native-eur/whoseswitchwaker-eur.nrogoes on the card asswitchwaker.nro). - Your disc as an uncompressed
.iso(not RVZ, GCZ, CISO or NKit), renamed toGZLE01.iso(USA) orGZLP01.iso(Europe). - About 1.6 GB free on the SD card (the disc is 1.4 GB; the shader caches grow to a few dozen MB).
The SD card must end up like this (folder and file names exactly as shown):
sdmc:/switch/switchwaker/
├── switchwaker.nro the game, the USA or the European version (one per card)
├── GZLE01.iso your disc (GZLP01.iso: the European one)
├── initial_pipeline_cache.db the list of graphics pipelines the game uses
├── initial_dksh_cache.bin their shaders, compiled for the Switch's GPU
└── native/ created by the game: logs, saves, settings, caches
Either way works:
- By hand: put the SD card in the computer (or mount it over USB with hekate's
Tools → USB Tools → SD Card or similar) and copy the four files into
switch/switchwaker/. - Over USB (MTP), from the repository:
scripts/switch/push.sh --disc /path/to/GZLE01.isoonce (named after the disc's ID), thenscripts/switch/push.sh native(the NRO and its caches;native-eurfor the European build, pushed asswitchwaker.nro) after every build. Every file is read back and checked. Needsbrew install libmtpand USB file transfer enabled on the console (DBI, haze or similar). Details: docs/SWITCH_BUILD.md.
Without initial_dksh_cache.bin the game still runs, but every shader is then compiled on the console
the first time it is needed (its draws skipped meanwhile), and the first hours show missing effects.
- Open the Homebrew Menu in title mode: hold R while starting any installed game, then pick SwitchWaker (SwitchWaker EUR: the European version). Opened from the album (applet mode) the game has far too little memory and will not run properly.
- Or install the HOME-screen icon (forwarder), which always starts it in title mode:
build it with
scripts/switch/build_forwarder.shand installswitchwaker_forwarder.nspwith DBI (switch/forwarder/INSTALL.md). It startsswitchwaker.nro, whichever version it is.
The Switch renderer is deko3d (since phase 6 of docs/DEKO3D_MIGRATION_PLAN.md):
the compiled shaders of every bundled pipeline come next to the NRO in initial_dksh_cache.bin, so
there is no shader preparation: the game starts in seconds, the first time too. A shader the file
lacks (a new effect, a mod) is compiled once in the background and kept in
native/user/cache/dksh_local.bin; its draw is skipped for a moment meanwhile.
The previous renderer, OpenGL ES on Mesa (switchwaker_gl.nro, "SwitchWaker (GL)"), was removed on
2026-10-09; INSTALL.md, "Updating", lists the files it left on the SD card.
- Saves (the memory card):
sdmc:/switch/switchwaker/native/user/USA/Card A. Back up this folder. - Settings from the options menu:
native/user/settings.ini. - To update, replace
switchwaker.nro,initial_pipeline_cache.dbandinitial_dksh_cache.bin. Saves, settings and caches stay. - Logs, if something goes wrong:
native/logs/, one file per session named by its date and time (switchwaker_<date>_<time>.log); the newest is this run. Only the 10 most recent sessions are kept. - If you used this port's earlier SD folder (
sdmc:/switch/centollos/), rename it toswitchwakerand renamecentollos.nrotoswitchwaker.nro; the old path is no longer read.
- In-game options menu: Minus (−) on the Switch, F1 (or L+R+Z) on the Mac and Linux. Saved to
native/user/settings.ini. - Language: the options menu and the shader loading screen are in Spanish or English, following the
console's language (on the Mac and Linux,
LANG);COS_LANG=esorCOS_LANG=enforces one. COS_*variables (environment on the Mac and Linux; on the Switch the options menu, and for developer variables the[dev]section ofnative/user/settings.ini): switch/native/settings-dev.example.ini and native/README.md.- HD textures (optional, a Dolphin-format pack you supply): docs/HD_TEXTURES.md.
- 16:9 widescreen: docs/WIDESCREEN.md.
Boots and plays on the Mac and the Switch, with sound, controllers, memory-card saves and an options menu. Played by hand mostly on the opening island and a few other areas; automated sweeps run on the Mac over every stage and room, every actor, particle effect, model and screen, every event of every stage, every item through its item-get demo, saves loaded back, every enemy fought and every boss room, also under AddressSanitizer (native/README.md, "Sweeps"). The Switch does not yet hold a stable 30 fps everywhere. The Linux build boots to the same milestones and passes the regression in a container with software Vulkan (aarch64); it has not been played on a Linux desktop with a GPU yet. Known issues: docs/NATIVE_PORT_PLAN.md, "Known bugs".
- The project's own code: MIT (LICENSE).
game/(the decompilation): CC0-1.0 (game/LICENSE).native/dsp_hle/(audio, over Dolphin's DSP HLE): GPL-2.0-or-later (native/dsp_hle/LICENSE). Every build links it today, so the resulting binaries are GPL.- Other components: THIRD_PARTY.md. Contributing: CONTRIBUTING.md.
Independent project, not affiliated with or endorsed by any video game company. Trademarks mentioned or alluded to belong to their respective owners. No game content is included or distributed.
Pulpparty, depende3000, and the SwitchWaker contributors, with an AI coding agent (see "How it was made: AI use"). Thanks to everyone behind the projects in "Standing on the shoulders of others".