Libultraship (LUS) is a library designed to facilitate PC ports of Nintendo 64 games. It is not a recompilation tool; rather, it allows developers to build a game’s original source code (derived from decompilation) on modern hardware by providing a header-compatible wrapper around modern reimplementations of N64 SDK functions.
In essence, LUS acts as “compile-time WINE” for the N64.
LUS supports the following platforms and rendering backends:
| Platform | Rendering Backends |
|---|---|
| Windows | OpenGL, Direct3D 11 |
| macOS | OpenGL, Metal |
| Linux | OpenGL |
| iOS | OpenGL, Metal |
| Android | OpenGL ES |
| OpenBSD | OpenGL |
The initial goal is not a playable game, but simply a functional executable that links against LUS.
libultraship is added as a submodule.#include <ultra64.h>) in the source code with LUS includes:
#include <libultraship/libultraship.h>
osCreateThread for rumble, as LUS manages threads differently than the N64 CPU)..exe or binary).Once the executable exists, the game will likely crash immediately or behave erratically.
GBI_UCODE CMake option: F3DEX_GBI_2 (default), F3DEX_GBI, and F3DLP_GBI. Set this to match your game’s microcode.You have two options for handling game assets (textures, models, etc.):
.o2r): ZIP-based archive format, the modern default. No additional CMake options needed..otr): MPQ-based archive format (legacy). Requires enabling INCLUDE_MPQ_SUPPORT in CMake.Audio is generally the last step. It requires significant effort to hook into LUS’s audio system once the rest of the game is stable.
LUS only exposes PC audio drivers — it does not interface with N64 audio. The available audio backends are:
Your port is responsible for implementing the game’s audio pipeline and routing its output through one of these drivers.
Key CMake options that porters should be aware of:
| Option | Default | Description |
|---|---|---|
GBI_UCODE |
F3DEX_GBI_2 |
Graphics microcode variant (F3DEX_GBI_2, F3DEX_GBI, F3DLP_GBI) |
INCLUDE_MPQ_SUPPORT |
OFF |
Enable OTR/MPQ archive support (via StormLib) |
NON_PORTABLE |
OFF |
Build a non-portable version |
DISABLE_DLL_LOADER |
OFF |
Disable dynamic library/script loading |
LUS_BUILD_TESTS |
OFF |
Build unit tests |
LUS uses a “bridge” pattern to connect N64 SDK function calls to modern implementations. Bridge modules exist for audio, graphics, controllers, resources, events, scripting, console variables, crash handling, and window management. When porting, you interact with these bridges through the standard N64 SDK API — LUS routes calls to the appropriate modern backend automatically.
The bridge implementations live in src/libultraship/bridge/.
Understanding the LUS codebase is helpful for debugging and contribution:
| Directory | Description |
|---|---|
src/libultraship/ |
Contains N64-specific code including the libultra reimplementation (libultra/), bridge layers to modern backends (bridge/), controller support, window management, and logging. |
src/ship/ |
Platform-agnostic code: resource/archive management, audio backends (SDL, CoreAudio, WASAPI), controller abstractions, configuration, scripting/DLL loading, security/keystore, and utility functions. |
src/fast/ |
The Fast3D Renderer. Interprets N64 display lists as commands for modern GPUs. Supports OpenGL, Direct3D 11, and Metal backends. |
include/ |
Public headers mirroring the src/ structure. The main entry point is libultraship/libultraship.h. |