SkyboundTOTK is an experimental native static recompilation project for The Legend of Zelda: Tears of the Kingdom, base game version 1.0.0. It targets Windows x64 and Linux x86_64. It is not affiliated with Nintendo. Expect graphical problems and incomplete compatibility; a successful build does not guarantee a complete playthrough.
The project's AArch64 game code is translated ahead of time into C and compiled locally into a native executable. A runtime implements the services the game expects, and the renderer translates its graphics work and shaders for WebGPU. This is a game-specific port, not a general-purpose Switch emulator. Some graphics translation still happens at runtime.
You must supply your own legally obtained, already-extracted, unmodified 1.0.0 base-game ExeFS and RomFS. No game files, generated game code, keys, firmware or saves are included in this source project. The build does not extract NSP or XCI files, and other versions or updates are not supported by the game-specific hooks.
Keep your game files, generated code, executable package and saves private. The game/, build/ and dist/ directories are Git-ignored, but check what you are publishing rather than relying on ignore rules alone. The generated standalone package contains copyrighted game-derived data and must not be shared or committed.
- Windows 10/11 x64 and a GPU and driver supported by wgpu-native. Allow at least 45 GB free in addition to the original game dump for intermediate files and the separate packaged RomFS; the build is CPU- and memory-intensive. It runs as many compiles at once as fit in 80% of your RAM at 3.5 GB each (three on a 16 GB PC); set
RX_JOBS=<n>to choose. - Python 3.10 or newer on PATH, with
lz4installed:python -m pip install lz4. - Visual Studio 2022 Build Tools with the MSVC C++ tools and Windows SDK. Use an x64 Native Tools Command Prompt so the compiler can find the Windows headers and libraries.
- Clang, clang++ and lld. The build previously used emsdk 6.0.9: install it separately and set
EMSDKto its directory (the lookup defaults toC:\emsdk), or put these LLVM tools on PATH. The build script does not download compilers or Python packages.
-
Put the extracted files in the project's
gamefolder. The paths must look like this, notgame/exefs/exefs/mainorgame/romfs/romfs/Event:SkyboundTOTK/ build.bat game/ exefs/ main main.npdm rtld sdk ... romfs/ ActorSystem/ Event/ ... -
Open an x64 Native Tools Command Prompt, change to the SkyboundTOTK directory and run
build.bat. The launcher pauses at the end so you can read any errors. -
The script checks the
mainandsdkmodule build IDs and a few RomFS directories, lifts the game code, compiles the native executable and copies the runtime and RomFS intodist/SkyboundTOTK/. The checks do not verify the entire RomFS or guarantee that a dump is complete. -
Open
dist/SkyboundTOTK/SkyboundTOTK.exeto run it. No command-line arguments are needed. Keepimage.bin,image.json,romfs/,wgpu_native.dllandSDL2.dllalongside the executable. The standalone folder can be moved as a unit and does not need the originalgame/folder to launch.
The first lift and compile can take a long time. The builder reuses a completed lift only when its recorded game and lifter inputs match. If the lift was interrupted or those inputs change, move the existing build/ directory aside before retrying. The script refuses to overwrite a nonempty dist/SkyboundTOTK/: move the existing package aside before a new build. Copy its user/ folder into the new package if you want to retain its saves and settings. Do not delete your only save backup.
The package normally creates its own user/ directory beside the executable; it does not automatically use the saves from another installation. Native renderer pipeline cache data is kept in rxcache/ beside the executable. The executable also accepts an image path and --romfs / --user overrides for advanced use, but they are not needed for normal launching.
- Python or
lz4missing: install them for the Python on PATH, then reopen the tools prompt. Runpython -m pip install lz4with that same Python. - Compiler, headers or libraries missing: open the x64 Native Tools prompt and check that the C++ tools, Windows SDK, Clang, clang++ and lld are installed and discoverable. Set
EMSDKif the LLVM tools are in a non-default emsdk directory. - Wrong module or missing RomFS: check the extracted folder layout and version. A base-game ID match is not a complete integrity check.
- Existing output or stale/incomplete lift: move the indicated package or build directory aside, preserving
user/first, then retry. An interrupted copy can also leave a nonempty package that needs to be moved aside. - "Not enough memory left" after long play: older builds kept every render pipeline used in the last 10 minutes, which reached about 14,000 pipelines and 17 GB of memory in one report (issue #10). Past 9000 pipelines, the ones unused for a minute are now released (
RX_PIPELINE_HARD_CAP=<n>andRX_PIPELINE_HARD_TTL_S=<s>change that). - First launch or new scene stutters: shader translation and pipeline compilation may happen as scenes are encountered. The native pipeline cache helps prepare previously encountered pipelines on later launches; it cannot guarantee stutter-free play.
- GPU device lost or wrong GPU: AMD cards lost the WebGPU device at startup while the GPU ASTC decoder was created (issue #1; fixed). The log now includes wgpu's own warnings and errors (
RX_WGPU_LOG=info|debug|tracefor more,offfor none).RX_ADAPTER=<part of the GPU's name>(for exampleRX_ADAPTER=Radeon) picks a GPU on a PC with two, andRX_ASTC_CPU=1decodes ASTC textures on the CPU instead of the GPU. - Crash or graphics issue: note the game version, hardware, driver, location and settings. The standalone startup test initialized the renderer and loaded the packaged RomFS, but did not verify full gameplay or graphics correctness.
Same game files and same build_game.py launcher as Windows. Run python build_game.py from the project directory. There is no build.bat step. The executable is an ELF. It links SDL3 and FFmpeg from the system and Vulkan through a patched libwgpu_native.so that you build. That shared library is not in the repository. The Windows package still uses the bundled wgpu_native.dll and SDL2.dll.
- x86_64 Linux and a Vulkan GPU and driver. Allow at least 45 GB free in addition to the original game dump. The build is CPU- and memory-intensive.
- Python 3.10 or newer on PATH, with
lz4installed:python -m pip install lz4, or the distro package. - Clang, clang++, lld, and pkg-config. The build script does not download compilers or Python packages.
- SDL3 and FFmpeg development files. The build checks these pkg-config modules:
sdl3,libavformat,libavcodec,libavutil,libswscale. - Rust 1.93 or newer, and libclang for bindgen, used only to build
libwgpu_native.so.
Arch Linux packages that satisfy the system dependencies:
sudo pacman -S clang lld pkgconf python python-lz4 sdl3 ffmpeg
On Debian and Ubuntu the pkg-config modules are the requirement. A typical set is clang, lld, pkg-config, python3, python3-lz4, libsdl3-dev, libavformat-dev, libavcodec-dev, libavutil-dev, and libswscale-dev. The SDL3 package name depends on the release.
Copy the built library to third_party/wgpu-native/lib/libwgpu_native.so before build_game.py. The headers already in third_party/wgpu-native/include/ are the matching version. The Windows DLL in that folder is the unmodified v29.0.1.1 release. The Linux library has to include both patches under third_party/wgpu-native/totk-patches/.
The native patch expects a sibling checkout named wgpu-patched. From an empty directory, with SKYBOUND set to this repository:
git clone --recurse-submodules --branch v29.0.1.1 https://github.com/gfx-rs/wgpu-native.git
git clone --branch v29.0.3 https://github.com/gfx-rs/wgpu.git wgpu-patched
git -C wgpu-native apply "$SKYBOUND/third_party/wgpu-native/totk-patches/wgpu-native-29.0.1.1.patch"
patch -d wgpu-patched -p1 < "$SKYBOUND/third_party/wgpu-native/totk-patches/wgpu-29.0.3.patch"
cargo build --release --manifest-path wgpu-native/Cargo.toml
cp wgpu-native/target/release/libwgpu_native.so "$SKYBOUND/third_party/wgpu-native/lib/"If bindgen cannot find libclang, set LIBCLANG_PATH to the directory that contains libclang.so (often /usr/lib) and rerun the cargo build. A smaller library is cargo build --release --no-default-features --features wgsl,spirv,vulkan run from wgpu-native. The playtest below used a default --release build. The totk-mimalloc cargo feature is optional.
- Put the extracted 1.0.0 ExeFS and RomFS in
game/, in the same layout as the Windows instructions. - From the project directory, run
python build_game.py. - Run
dist/SkyboundTOTK/SkyboundTOTK. Keepimage.bin,image.json,romfs/, andlibwgpu_native.sobeside the executable. It finds that library through an$ORIGINrpath. SDL3 and FFmpeg stay system libraries. The standalone folder can be moved as a unit and does not need the originalgame/folder or Wine.
Lift reuse, the nonempty dist/SkyboundTOTK/ refusal, and user/ saves work the same way as on Windows. Native pipeline cache data is rxcache/pipelines.bin beside the executable.
- SDL3 or FFmpeg missing: install the dev packages, then check
pkg-config --exists sdl3 libavformat libavcodec libavutil libswscale. - Missing
libwgpu_native.so: build it as above and copy it intothird_party/wgpu-native/lib/before runningbuild_game.py. The packaged copy has to stay next to the executable. mmap guest windowfailed: the log includeserrno. The runtime reserves a 4 GB window at a fixed address. A restrictivevm.overcommit_memorysetting can reject that reservation.- First launch or new scene stutters: same shader and pipeline compilation as on Windows. The pipeline cache helps on later launches.
- Existing output or stale lift: same rule as Windows. Move
dist/SkyboundTOTK/orbuild/aside, and keepuser/if you want the saves.
Focus the game window before using the keys. The renderer briefly reports display settings in the window title; changes are saved in user/present.txt for the next launch.
| Key | Action |
|---|---|
| F6 | Toggle experimental ultrawide / 16:10. The window must not be 16:9; see below. |
| F7 | Toggle experimental frame interpolation. |
| F8 | Toggle FSR 1 upscaling. |
| F9 | Cycle FSR sharpening. |
| F10 | Toggle aspect-preserving presentation versus stretching the image to fill the window. |
| F11 | Toggle fullscreen/windowed mode. |
FSR: The current implementation is FidelityFX Super Resolution 1, with EASU upscaling and RCAS sharpening in the presentation pass. It is enabled by default and is used when the presented frame is enlarged; otherwise the renderer uses the normal sampling path. FSR 1 is spatial upscaling, not FSR 2/3 temporal upscaling or AMD frame generation, and does not increase the game's internal render resolution. F9 cycles sharpening from sharper to softer values.
Frame interpolation: This is the project's own experimental image-based optical-flow interpolation, not AMD FSR frame generation. F7 is off by default and inserts estimated frames between real frames, normally targeting twice the displayed frame rate when the hardware can keep up. It does not make the game simulate more frames or reduce input latency; the display runs about one game frame behind. UI and fast motion can smear or distort, and long frame gaps are not interpolated.
Ultrawide: F6 attempts to adjust the camera and HUD and fill a wider window. It is off by default. A wider-than-16:9 window is needed, but a user reported that F6 stretches the image instead of providing a correctly proportioned wider view. Camera hooks are present, but their behavior in that report has not been resolved or independently verified. F10 stretching alone is not true ultrawide. F6 also works for windows narrower than 16:9, such as 16:10 (1920x1200, 2560x1600) or 4:3: the camera takes the window's shape and the HUD keeps its proportions in a 16:9 band across the middle, while full-screen menus such as the map fill the window (checked at 1920x1200: gameplay HUD, inventory and map).
Keyboard and mouse controls are experimental. WASD moves, IJKL controls the camera, Space jumps, E is action, Shift or Q is run/cancel, F attacks, Z/R are L/R, C/V are ZL/ZR, Ctrl crouches, Enter is Plus, Tab is Minus and the arrow keys are the D-pad. Click the window to capture the mouse, Esc to release it, and use - / = to adjust sensitivity. XInput and SDL-supported controllers are also handled; buttons map by physical position, Nintendo controllers included (the right face button is A). On Linux, gamepads are read through SDL3 with those same physical positions. XInput is not used. Keyboard, mouse, and F6 through F11 match the table above.
The game speaks English (US) by default. To play in another of its languages, put a language.txt next to the executable (SkyboundTOTK.exe on Windows, SkyboundTOTK on Linux) whose first line is one of ja, en-US, en-GB, fr, fr-CA, de, it, es, es-419, nl, ru, ko, zh-CN (or zh-Hans), zh-TW (or zh-Hant); the environment variable HOS_LANGUAGE does the same. Anything else falls back to English (US).
Emulator-style mod folders work: put each mod in mods\<name>\ beside the executable, with its romfs\ (files that replace or add to the game's RomFS) and/or exefs\ (.pchtxt or <build id>.ips patches). Copies laid out as mods\contents�0F2C0115B6000\<name>\ work too. A folder name starting with - or _ turns that mod off, and when two mods replace the same file, the one whose path sorts last wins. The log lists each mod and each file it serves.
- RomFS mods work as they are. The resource size table is not merged, so a mod that makes files larger needs to ship its own (most do).
- Data patches (
.rodata,.data) apply at startup. Code patches can't, because the game code is compiled ahead of time: lift withpython a64-kit/build.py lift totk --exefs <exefs> --build build --mods <mods folder>and rebuild to compile them in. - Extra code modules (
subsdk*, for example exlaunch-based mods such as UltraCam) are not loaded.
The renderer targets the WebGPU API and WGSL so the same general renderer and shader backend can be used by native wgpu and by browser WebGPU experiments rather than maintaining wholly separate graphics implementations. On Windows, wgpu-native translates this API to an available native backend, such as Vulkan or Direct3D 12. On Linux it uses wgpu-native's Vulkan backend, with an SDL3 window on Wayland or X11. Choosing WebGPU does not mean the desktop game runs inside a browser. It also has portability and validation tradeoffs, and translation, pipeline compilation and API overhead still require optimization. build.bat builds the Windows native package. python build_game.py builds the Linux native package on Linux. Browser functionality and packaging are not promised or validated by either launcher.
These are reports and investigation notes, not a complete compatibility list. Some were observed in earlier TOTKPort builds rather than independently reproduced in standalone Skybound.
| Issue | Status | Details |
|---|---|---|
| Shadows / shaders | Reported | Shadow shader problems have been reported. The standalone startup log also showed three shader-decoder assertions; their visual effect and relationship to the shadow issue are unknown. |
| Stretched terrain | Reported | Terrain can appear randomly stretched; cause and reproducibility need investigation. |
| Incorrect terrain textures | Reported | Some areas have wrong terrain textures; locations and causes need investigation. |
| Weapon and shield wheel background | Fixed | The d-pad quick menus opened over a black background; they now take the ability wheel's 1/30 s step while held (PR #11). |
| Ultrahand cannot grab | Fixed | Aimed objects stayed orange and A missed (issue #9). The game reads the object under the reticle from a GPU pass whose vertex shader stores the result, which WebGPU vertex shaders cannot do; that shader now also runs as a compute shader, and the 16-bit object-id target is kept exact. Objects turn green and A lifts them. |
| Ultrawide | Unresolved | F6 has been reported to stretch the image instead of providing a correctly proportioned wider view. The exact failure is unknown. |
| Zonai Portable Pot particles | Workaround; retest | A workaround greatly reduced disappearing-effect spikes in an earlier build, but short stray lines remained and the underlying cause is unknown. Retest in Skybound. |
| Depths gloom | Earlier fix; retest | Missing or incorrect ground gloom was reported on the path to Ganon. Earlier notes record a fix for a reproduced case; standalone Skybound and other locations need verification. |
| Fused-weapon inventory icons | Workaround; retest | Black icons were seen in earlier testing. A cache-retry workaround was recorded, but the underlying timing issue remains unexplained; retest in Skybound. |
| Browser new-game loading | Previously reported; retest | Earlier web experiments had an intermittent loading-screen hang. This is not a verified Windows-launcher issue; the root build does not package a browser release. |
| Browser interpolation judder | Earlier fix; retest | Earlier web experiments had interpolation judder; notes record a pacing fix. Browser behavior is not validated by the Windows launcher. |
| Performance and compatibility | Ongoing limitation | Frame pacing, shader warm-up and rendering vary by scene and hardware. A build and startup test are not a full-game compatibility test. |
| Linux | Early play | One x86_64 Linux build (Vulkan, SDL3, FFmpeg, NVIDIA RTX 4090) got through the opening and onto the surface after the dive. The first enemy could be fought, and tree branches could be picked up. Gamepad and audio worked. This is not a full playthrough. |
- Add support for other TOTK versions beyond the 1.0.0 base game.
- Fix all current issues and bugs.
NotRexed's original project code is offered under the MIT License. The required AArch64 lifting/runtime and renderer sources originated in NotRexed's Rexcomp-based TOTKPort; unrelated Rexcomp kits and applications are not included.
The whole repository and combined build are not MIT-only. The AArch64 kit includes GPL-licensed suyu/yuzu components and other third-party code under their own licenses. Their licenses and applicable GPL obligations still apply; see NOTICE.md and the individual license files. MIT does not grant rights to the game. Before publishing, verify that every contributor whose code is being offered under MIT has agreed, and review the applicable source and binary distribution obligations.