Skip to content
PORTSNATIVE.
HomeCatalog
Web GamesEmulatorsToolsNews
PORTSNATIVE.

A catalog for discovering ports and related projects. We link to official sources and do not host original game files.

ExploreCatalogMy list
InformationAbout usSuggest a portSupportDonationsLegal notice
© 2026 PortsNative
Back to catalog
Blinx 2: Masters of Time and Space
PORTSNATIVE

Blinx 2: Masters of Time and Space

NATIVE PORTPLATFORMERWINDOWSBETA

Blinx 2: Masters of Time and Space

OriginXbox

TechnologyStatic recompilation (native C/C++)

Available forWindows

View official project

About the project

Blinx 2: Masters of Time and Space es un juego de plataformas desarrollado por Artoon y publicado por Microsoft Game Studios. Fue lanzado para la Xbox el 18 de noviembre de 2004. Es secuela de Blinx: The Time Sweeper, que fue lanzada para Xbox en 2002.

Official project information

Author's original READMEOpen on GitHub ↗

BLiNX 2 static recompilation

[!TIP] The easy way: download blinx2-wizard-* for your system from the latest release, point it at your own disc image, and it builds and installs the game for you. The by-hand route is under Build the game.

BLiNX 2: Masters of Time & Space was an original Xbox game. This project turns your own copy of it into a native program for your PC or Mac: the game's x86 code is lifted to C by the xboxrecomp toolkit and compiled together with a replacement Xbox kernel, GPU (NV2A) and audio (APU) runtime. No emulator, no disc in a drive: one command builds a private, installable bundle from your disc dump.

No game data is included or distributed. You need your own copy of the game; everything built from it stays on your own machines.

BLiNX 2 recompiled: stage 1 on the Metal backend

<!-- TODO(link): releases page, once a release exists --> <!-- TODO(link): demo video -->

Contents: For players (what you need, platforms, install, options, widescreen, free camera, HUD texture pack, known issues, screenshots, help) | For developers (architecture, build from source, the toolchain, testing, environment variables, docs, contributing, legal).


For players

What you need

ItemWhy
Your own, legally obtained copy of BLiNX 2: a disc image (.iso) or the extracted folder with default.xbeThe game's code and assets come from it. This project does not provide or link to them, and refuses other titles.
A build machine: a Mac (Apple silicon), a Linux PC or a Windows PC, with about 15 GB freeThe bundle is built from your dump on your machine. A Mac can build every target; Linux and Windows build the Windows and SteamOS bundles.
uv, git and Python 3.9 or newer./blinx2 fetches everything else (CMake, Ninja, the compiler, the toolkit), each download checked against a pinned sha256; it uses git to fetch the toolchain. macOS: brew install uv; git and Python come with the Command Line Tools (xcode-select --install). Linux: curl -LsSf https://astral.sh/uv/install.sh | sh; git and Python from your distribution. Windows: winget install --id=astral-sh.uv -e (uv only), Git for Windows, and Python 3.9 or newer from python.org with the py launcher.
A controller, or the keyboardAny Xbox, PlayStation or other SDL-supported pad is player 1; the keyboard works too.

Platforms

You play onBundleGraphicsAudioInputStatus
Steam Deck (stock SteamOS), or a Linux gaming PCsteamos (the Windows build, run under Proton through umu-run)Direct3D 11 (DXVK)XAudio2 (FAudio)Controller (XInput) and keyboardPlays with sound and saves. The Deck is the regular manual test machine. Set the Steam entry's Game Resolution to Native (1280x800) so Steam does not rescale the game, then set scale = 2, or leave it at 1 and rely on FSR; aspect = "16:10" fills the Deck's screen.
Linux desktop with Protonsteamos, or the bare build under umu-runDirect3D 11 (DXVK)XAudio2 (FAudio)Controller and keyboardPlays; this is the tested Linux route (GE-Proton 11). Window resize does not reach the game there; fullscreen does.
macOS (Apple silicon)macos (.dmg)MetalSDL2 (CoreAudio)Controller (SDL GameController) and keyboardPlays with sound and saves.
Windows x86-64windows (a setup program)Direct3D 11XAudio2Controller (XInput) and keyboardBuilds and installs, but untested on native Windows: the setup program and the game have only been run under Proton.

The game runs at 30 frames per second and 4:3, as on the Xbox. Widescreen is opt-in (Hor+, see Options); at 4:3 a wide window or screen is pillarboxed, never stretched. A 60 fps mode is not planned (the stage logic steps a fixed 1/30 s, so a faster loop plays at double speed). External frame-generation tools (Lossless Scaling, lsfg-vk, AMD AFMF, NVIDIA Smooth Motion) can show it at 60; they are unsupported, see docs/frame-generation.md.

Every stage and boss has been reached in scripted runs; the title, attract mode, stage 1 and the story route to the hub are checked frame by frame against reference frames on every build, on Metal and on Direct3D 11.

Sister project. Burnout 3: Takedown is recompiled with the same toolkit and build wizard, as a fork of sp00nz's project; its README has its own platforms table and releases, so you can compare how far each game has come. Neither repository publishes game files, frames, audio or saves.

Build the game

The short route: the build wizard. From the release that carries it on, each release has a small program for Windows, macOS and Linux (Steam Deck included): download yours, point it at your disc image, pick the options, and it builds and installs the game for you. It runs the same commands as below. docs/packaging.md has the steps, the SmartScreen and Gatekeeper prompts, and where it puts things.

By hand. Get this project, then go into its folder (one line at a time, in Terminal on macOS and Linux or in PowerShell on Windows):

git clone https://github.com/apexJCL/blinx2-recomp.git
cd blinx2-recomp

Then give it your disc image, or the folder with default.xbe:

./blinx2 /path/to/your/BLiNX2.iso

In PowerShell that is .\blinx2 C:\path\to\BLiNX2.iso (blinx2 C:\path\to\BLiNX2.iso in the Command Prompt). On Windows, keep the path short (C:\b2) and run git config --global core.longpaths true once before the clone.

It checks that the disc is BLiNX 2, puts its files in game_files/ in this folder (git ignores it), fetches the toolchain, lifts the game and builds a bundle for this computer: macos on a Mac, steamos on Linux, windows on Windows. The first run takes a while (between about 20 and 40 minutes in the runs timed so far); later runs only rebuild what changed. The bundle lands in dist/. You can also copy the disc's files into game_files/ yourself and run ./blinx2 alone.

./blinx2 package windows|steamos|macos   # the same, for another target
./blinx2 doctor      # what this machine has, what it can package, and what to install first

Copy the bundle to the machine you play on (a USB stick, scp, a share) and install it there:

TargetInstallSaves, settings and logs
Steam Deck / Linux (dist/BLiNX2-<v>-steamos.tar)In Desktop Mode: tar -xf BLiNX2-<v>-steamos.tar, cd BLiNX2-<v>-steamos, ./install.sh --steam (Steam open: it adds "BLiNX2" as a non-Steam game). A stock Deck has no umu-run; the installer offers to download the pinned umu-launcher (1.4.4), or run ./install.sh --fetch-umu. The first launch downloads the Steam Linux Runtime and GE-Proton and makes the Wine prefix, which takes a few minutes. In Game Mode, set the entry's Properties > General > Game Resolution to Native (1280x800). Later versions: ./install.sh; ./install.sh rollback goes back one.~/Games/BLiNX2/{hdd,config,logs}
macOS (dist/BLiNX2-<v>.dmg)Open the .dmg and drag BLiNX2.app to Applications (replace the old one to update). The app is signed ad hoc, not notarized: on another Mac, right-click > Open once, or xattr -dr com.apple.quarantine /Applications/BLiNX2.app.~/Library/Application Support/BLiNX2/{hdd,config,logs}
Windows (dist/BLiNX2-<v>-windows/)Keep the folder together (the setup reads game_files\ beside it) and run BLiNX2-<v>-setup.exe. It installs for your user only, no administrator rights, with a Start Menu entry. SmartScreen will warn (unsigned, built on your machine): More info > Run anyway. A newer setup installs on top.%LOCALAPPDATA%\BLiNX2\{hdd,config,logs}

Saves (hdd/), settings (config/) and logs (logs/) live outside the program files and survive every update, rollback and uninstall. docs/packaging.md has the long version: every installer option, updating, uninstalling, moving saves (the menu's Saves page) and a troubleshooting list.

Updating to a new release. Run the new release's wizard on the same build folder, or by hand git pull and then ./blinx2 in this folder. Either way the toolchain moves to the new release's pins before the build; then install the new bundle as above.

A bundle is private. It contains your copy of the game and code generated from it. Keep it on your own machines; never share, upload or publish it.

Bring your saves

Saves from a console, another install or another PC import into the save folder of the table above:

./blinx2 saves list --from PATH          # what PATH holds, and what would import
./blinx2 saves import --from PATH --dry-run
./blinx2 saves import --from PATH        # add --replace to overwrite a save already there

PATH is a folder or a zip: another install's hdd folder, a console's E: copy (from a dashboard or FTP), a UDATA folder or one title folder (4d530065), or a zip of any of those, including the menu's Saves export. Saves need no console keys: each import re-signs blinx2data.bin for this build. Close the game first; the import refuses while it runs. Before the first write it zips the saves already there to config/exports/save-backups/, beside the menu's own Saves backups, and it never overwrites a save unless you pass --replace. Add --to <data folder>/hdd when the game is installed on another machine or in another place. Disc images (xemu qcow2, raw disks, memory units) come later; copy the saves out with xemu or a FATX tool until then.

Controls

A controller is player 1. The keyboard and the mouse are merged onto player 1 while the game window has the focus. Focusing the window grabs the mouse; F9 frees the cursor and grabs it again. Change a key under [input.bindings] in config/config.toml; docs/input.md has the names, examples and the mouse settings.

Keys and mouseXbox controlKeys and mouseXbox control
W/S/A/D (or numpad 8/2/4/6)Left stick (move)Mouse, or I/K/J/LRight stick (look)
ArrowsD-padSpaceA (jump)
Left click or RRight trigger (sweep, shoot)Right click or FB (action)
EX (time control)QY
C, ZWhite, BlackLeft ShiftLeft trigger
Tab, middle clickLeft, right stick click
Enter or EscapeSTART (pause)BackspaceBACK
Left Alt (hold)walkF9free the cursor

Options

The game runs stock by default. Enhancements are opt-in. Every option and its default is in config.default.toml, which ships beside the game (in Contents/Resources in the macOS app) and is replaced by each update. Your changes go in config/config.toml in the data folder above: it holds only the keys you set, wins over the defaults, and no update touches it (the first launch writes it as a comment header, and renames a config/enhance.toml from an earlier version). Each key can also be set as an environment variable, which wins over both files; config/launch.env takes KEY=value lines for any RECOMP_* variable.

Optionconfig.toml keyEnvironment variableValues (default first)What it does
Render scalerender.scaleRECOMP_RENDER_SCALE1, 2, 3, 4Draws the 3D at a multiple of the stock 640x480. Metal and Direct3D 11; the CPU renderer ignores it.
Anisotropic filteringrender.anisoRECOMP_RENDER_ANISO0 (off), 2 to 16Sharper ground and walls seen at a slant. A small change in this game, most visible at render scale 1. Metal and Direct3D 11.
Aspectdisplay.aspectRECOMP_DISPLAY_ASPECT"4:3", "16:9", "16:10", "21:9" or another wider "W:H"Hor+ widescreen: a wider aspect shows more of the world at the sides instead of stretching it, see below. The HUD moves to the edges (the HUD mod below). Metal and Direct3D 11.
Movies in widescreendisplay.movieRECOMP_DISPLAY_MOVIE"fill", "black", "fit"With a wide aspect, how the movies fill the frame: scaled to cover it (top and bottom cropped, so the title movie fills the width), pillarboxed, or stretched to the width. Nothing at 4:3.
HUD at the edgesmods."hud.enable"RECOMP_HUD"on", "off"On by default. With a wide aspect, the radar, the time panel and the counters move out to the screen's edges, as on a 4:3 TV; menus, dialogue and the pause panel stay centred. display.hud_aspect and display.hud_margin set where the edges are. Nothing at 4:3. Also on the menu's Mods page. Metal and Direct3D 11.
Overscandisplay.overscanRECOMP_DISPLAY_OVERSCAN0 to 64Crops this many pixels of the 640-wide frame from the left and right edges (top and bottom in proportion, so it stays 4:3) and zooms the rest. BLiNX 2 needs none; ignored with a wide aspect. Metal and Direct3D 11.
Fullscreenpresent.fullscreenRECOMP_PRESENT_FULLSCREENfalse, trueOpens the window borderless fullscreen (no mode change).
Scaling filterpresent.filterRECOMP_PRESENT_FILTER"nearest", "linear", "integer"How the 4:3 frame fills the window: letterboxed nearest, letterboxed bilinear, or the largest whole multiple that fits, centred.
Frame pacingpresent.pacingRECOMP_PRESENT_PACING"sleep", "spin"sleep lets the game's frame wait sleep until the next vblank: less heat and battery on a laptop or a Deck, the same frames. spin is the console-original timing, where the wait holds a CPU core as it did on the Xbox.
Shaderpresent.shaderRECOMP_PRESENT_SHADER"none", "crt-lottes", "crt-lottes-fast", "crt-hyllian", "fsr", a .slangp pathA CRT look (shadow mask, scanlines) on the final picture, run by librashader on Metal and Direct3D 11; fsr is AMD's upscaler instead. Also on the menu's Shaders page, with the preset's settings (present.shader_params). Nothing extra to install: on Windows the bundle ships a build that needs no Visual C++ runtime or D3DX9. Without the library the game says so in its log and looks stock.
Shader profilepresent.profileRECOMP_PRESENT_PROFILE"none", a profile nameA chain of up to 8 shaders with their settings, built and saved on the menu's Shaders page (Add shader, then Save) as config/shader-profiles/<name>.toml, for example fsr then crt-lottes. When set it wins over present.shader.
Present surfacepresent.surfaceRECOMP_PRESENT_SURFACE"auto", "window", "internal"internal hands the compositor the frame at its own size to scale (gamescope's FSR on a Deck needs it, at scale = 1); window draws at the window's size. auto picks internal under the SteamOS launcher in gamescope, window elsewhere.
HUD texture packtextures.packRECOMP_TEXTURES_PACKnone, a pathYour own 4x HUD and font pack, see below. A relative path is taken from the executable's folder.
Bloomfx.glow, fx.glow_intensityRECOMP_GLOW, RECOMP_GLOW_INTENSITY"on"/"off"; 1.0 (0.0 to 2.0)Turns the game's bloom (screen glow) pass off, or scales it.
Free cameracamera.free and camera.free_*RECOMP_CAMERA_FREE and RECOMP_CAMERA_FREE_*"off", "on"F6 (or Guide+Y, or Back+R3 held 0.4 s) starts and stops a camera you fly anywhere in the stage while Blinx stands still: left stick moves, right stick or mouse looks, RT/X up, LT/Y down, White fast, Black slow. F7 hides the HUD, End stops the world, Home goes back to the game's camera. Speed, look and mouse sensitivity, the fast and slow multipliers and both inverts are on the menu's Mods page and in config.default.toml; the keys are under [input.actions]. Metal and Direct3D 11; see below.
In-game menumenu.enabledRECOMP_MENUtrue, falseOn by default. F10 (or Guide+A, an Elite's P1, or Back+L3 held 0.4 s) opens a menu over the game to change these options while it runs, rebind the host actions and turn mods on or off; Save keeps only what you changed in config/config.toml. The game keeps running behind it and sees no input.
Stats stripoverlay.statsRECOMP_OVERLAY_STATSfalse, truefps, frame time, pacing, scale and backend in the window's corner; F3 (while the menu is on) or the menu's Stats page toggles it while you play.
Window size(none)RECOMP_WINDOW_SCALE2Initial window size, 640x480 times this (the SDL window on macOS).
Frame ratefps.modeRECOMP_FPS_MODE"lock30" onlylock60 and free are reported as not available (see Platforms); for a 60 fps look, see external frame generation.
# config/config.toml, for example
[render]
scale = 2

[present]
fullscreen = true
pacing = "spin"

[fx]
glow = "off"

Render scale at 1x, 2x and 3x on the same detail of stage 1 (Metal, in a window at twice the stock size; stock behaviour and the automated checks stay at 1x):

The same detail of stage 1 rendered at 1x, 2x and 3x

Widescreen

aspect = "16:9" (or "16:10", "21:9") widens the view instead of stretching it: the game keeps its vertical field of view and draws more of the stage at the sides (Hor+). The HUD mod moves the radar, the time panel and the counters to the edges, menus and dialogue stay centred, and the movies fill the width (display.movie). The pair is the same moment of stage 1 at 4:3 and at 16:9 (Metal, render scale 2; the timers differ because they are two runs):

Stage 1 at 4:3 and at 16:9 Hor+, where the wider view shows more of the beach at both sides

[display]
aspect = "16:9"

Free camera

With camera.free = "on" (or Free camera on the menu's Mods page), F6, Guide+Y or Back+R3 held 0.4 s (Back first; for pads whose Guide the game never sees, as on the Deck) detaches the camera from Blinx and lets you fly it anywhere in the stage; End stops the world and F7 hides the HUD, for a clean shot, and Home puts the camera back on the game's.

ControlDefault
Toggle flightF6, Guide+Y, Back+R3 held 0.4 s
Toggle HUD, Freeze game, Reset cameraF7, End, Home (while flying)
Move, lookleft stick, right stick or the mouse
Rise, sinkRT or X, LT or Y
Fast, slowWhite, Black

The four keys are host actions (camera.free.toggle, .hud, .freeze, .reset under [input.actions]), rebound on the menu's Controls page or the camera's Mods page. The old camera.free_toggle, _hud_key, _freeze_key and _reset_key keys are still read.

Stage 1 from the game's camera, and the same stage from the free camera high above the cliffs with the world stopped and the HUD hidden

HUD texture pack

At render scale 2 or 3 the 3D is sharp, but the HUD, menus and font are still the game's own small textures, stretched. A HUD texture pack replaces them with versions at 4x: an xBR upscale of the HUD art, and the Latin font redrawn from PT Sans Narrow Bold, glyph by glyph in the stock layout. The Mission Objectives screen's pre-rendered text is in the pack too; the mission summary (results) text and languages other than US English are not yet, and stay stock. The pair shows the same stage 1 HUD without and with the pack, from the Metal backend at render scale 2 in a window at twice the stock size (1:1 crops; the timers differ because they are two runs).

The stage 1 HUD at render scale 2, stock and with the HUD texture pack

The pack is optional and off by default. No pack is distributed: you make your own from your own game files, and it stays on your machines like the game. On Linux and Windows install PT Sans Narrow (ParaType; a Google Fonts family) for your user first; macOS ships it. Build the game first (./blinx2 /path/to/your/BLiNX2.iso, above), then make the pack and package with it:

./blinx2 enhance hud                   # writes dist/enhance/hud/hud.pack (--font FILE for another font file)
./blinx2 package macos --hud-pack      # or windows, steamos: puts the pack in the bundle and turns it on

--hud-pack turns the pack on in the bundle's config.default.toml, so it is on after a first install and after an upgrade alike. For the stock HUD, put this in your config/config.toml:

[textures]
pack = "none"

At start the log says [ENHANCE] textures.pack=<path> (<n> entries, scale 4), and every 600 flips [metal] textures.pack: N hits so far ([d3d11] on Direct3D 11) counts the textures drawn from the pack. Metal and Direct3D 11 draw the pack; the CPU renderer ignores it, and the automated checks never use one. ./blinx2 enhance hud --help lists the options (--scale 2|4, --only PATTERN, --list).

Known issues

IssueWhereState
The game can crash in stage 5-1 after about 90 s (seen once, in a scripted run)macOSBeing investigated.
Resizing the window by hand does not reach the gameLinux/Proton (GE-Proton 11, KWin)Fullscreen and render scale work; use them instead.
Bump-environment mapping (the stage 1 ocean, the Boss 3 ripple) draws as a plain textureCPU rendererMetal and Direct3D 11 draw it.
A few boss-stage artefacts: sky wedges in Boss 1, shadow shapes in two later bossesAll backends alikeStill being checked against the original hardware; they may be the game's own.
Movies: audio-to-video drift has not been measuredAllThe game's own Sofdec decoder plays them.
Native WindowsWindowsThe build is tested under Proton only.

Fixed in current builds, and verified on the Steam Deck: the freeze on the results screen after mission 1 and after the mission 3 boss, dark ground and water on multi-core PCs, and the stage 1 wading stutter.

Quick fixes for the usual symptoms:

SymptomFix
"Files are missing", or music, voices or a movie are missing, or the game says the disc is dirtyYour game_files/ is incomplete: the game's log names each missing file on a [FILE] missing line. Import the disc again with ./blinx2 import /path/to/BLiNX2.iso --replace (import --check lists what differs first), then rebuild with ./blinx2.
No soundAudio is on by default. Check that config/launch.env does not set RECOMP_AC97_READY=0, and that SDL_AUDIODRIVER is not dummy.
The keyboard does nothingThe game window must have the focus, input.keyboard must not be false in config/config.toml, and RECOMP_KEYBOARD must not be 0.
The mouse does nothingClick in the game window or focus it to grab the cursor (input.mouse_capture), or press F9 if you freed it; input.mouse must not be false and RECOMP_MOUSE must not be 0.
Steam Deck: "umu-run is not installed"In Desktop Mode, run ./install.sh --fetch-umu from the unpacked bundle.
Steam Deck: the first launch shows only a notice for a few minutesIt is downloading the runtime and Proton; ~/Games/BLiNX2/logs/umu.log shows the progress. The notice closes when the game starts.
macOS: "the app is damaged" or cannot be openedGatekeeper: right-click > Open once, or xattr -dr com.apple.quarantine /Applications/BLiNX2.app.

Screenshots

Title screen

Stage 1 gameplay

Boss fight: the Giant Mandrake

<!-- TODO(screenshot): second boss fight or time-control effect --> <!-- TODO(screenshot): attract mode --> <!-- TODO(gif): short gameplay clip -->

Getting help

Open an issue on this repository. Say which platform and bundle version you run (the version is in the bundle's name and in logs/), what you did, and attach the newest logs/game-*.log from the data folder in the install table. Never attach your game files, a save or the bundle itself.

If the game crashes or does not start:

  1. Note what you saw: an error box (its text or a screenshot), the window closing, or nothing at all. Add your GPU, its driver version and your OS version.
  2. Attach the newest logs/game-*.log and logs/xbox_kernel.log from the data folder. The kernel log is rewritten on every launch, so copy it before starting the game again. An empty logs/ is worth saying too.
  3. Attach the system's crash record:
    • Windows: in PowerShell, run Get-WinEvent -FilterHashtable @{LogName='Application'; ProviderName='Application Error'} -MaxEvents 3 | Format-List TimeCreated,Message and paste what it prints.
    • macOS: the newest cat_recomp-*.ips in ~/Library/Logs/DiagnosticReports/.
    • Steam Deck or Linux: also logs/umu.log.
  4. If asked, run once more with extra logging: put these two lines in config/launch.env in the data folder (on Windows, check the file does not end in .txt), start the game the usual way and attach the new game-*.log and xbox_kernel.log.
    RECOMP_LOG_LEVEL=3
    RECOMP_TRACE=missing=all,flip,stub
    
    They only add log lines; delete the file afterwards.

docs/packaging.md has the details.


For developers

Architecture

game_files/default.xbe
   │  blinx2 analyze      parse the XBE, disassemble, find functions, recover ABIs   (xbr, xboxrecomp-cli)
   │  blinx2 recomp       lift x86 to C                                             (xboxrecomp tools)
   ▼
src/recomp/gen/*.c       the lifted game (generated on your machine, never committed)
   +  src/                this game's boot code, hand-written XDK replacements, pad input, save seeding
   +  xboxrecomp runtime  replacement Xbox kernel, NV2A pushbuffer executor (Metal, D3D11, CPU), APU audio
   │  blinx2 build        CMake + Ninja; llvm-mingw cross-compiles the Windows build on every host
   ▼
build/cat_recomp (macOS) or build-win/cat_recomp.exe (Windows, Proton)
   │  blinx2 package      a private bundle: macOS .dmg, Windows setup program, SteamOS tar with installer
   ▼
dist/

This repository holds the game-specific half: the boot code, hand-written replacements for a few XDK library functions, the game's environment keys, the packaging templates, the bench and golden-frame harness, and the design notes. The generic halves live in two other repositories:

RepositoryRole
apexJCL/xboxrecomp, branch blinx2/portabilityThe toolkit: lifter, host runtime (kernel, NV2A, APU), enhancements layer. A fork of sp00nznet/xboxrecomp; this project needs changes that are only in the fork.
apexJCL/xboxrecomp-clixbr, the game-agnostic command-line tool. ./blinx2 is a standard-library bootstrap that runs it at the release game.toml pins.
PathContents
src/boot code (main.c), XDK replacements (recomp_manual.c), pad input, save seeding, the glow toggle, this game's rows of the environment table (env/)
game.tomleverything the CLI knows about this game: names, paths, pipeline flags, packaging, bench, the HUD pack set, and the toolkit and CLI pins
blinx2.py, blinx2, blinx2.cmdthe bootstrap and its wrappers
packaging/the launchers, defaults (config.default.toml, launch.env.default.*) and README parts the bundles carry
config/pipeline inputs: seed functions, spin-wait sites, the download pins
scripts/this game's helpers (input scripts, xemu references, the public export, compare-bundles.py) and their tests
analysis/golden references (golden/), research notes, the pipeline's output
docs/environment variables, packaging, the README images
openspec/specs and change proposals

Build from source

The pipeline and the Windows cross-build run on macOS, Linux or Windows; the macOS build needs a Mac. Builds are tested on these:

HostOSToolchainDependenciesBackend
macOS (Apple silicon, M4)macOS 27.0Xcode Command Line Tools 27.0 (Apple clang 21.0.0), CMake 4.4 and Ninja 1.13 from the venvHomebrew sdl2 (sdl2-compat 2.32), sdl3, openssl (3.6), libepoxy; Python 3.14Metal
Linux x86-64 (Proton)Fedora 44-based, kernel 7.2llvm-mingw 20260922 (clang 23.1.2), CMake and Ninja in a Fedora 42 distroboxGE-Proton11-7 via umu-launcher 1.4.4, DXVK 3.1 (as bundled); NVIDIA GeForce RTX 2060Direct3D 11 (DXVK)
Windows x86-64not tested as a build hostllvm-mingw (fetched by setup), NSISPython from python.org, Git for WindowsDirect3D 11

No minimum versions have been established. Per host, before the first build:

  • All hosts: Python 3.9 or newer for the bootstrap (uv gives the CLI the 3.12 it needs), uv on PATH, git, about 15 GB free. uv: macOS brew install uv; Linux curl -LsSf https://astral.sh/uv/install.sh | sh; Windows winget install --id=astral-sh.uv -e.
  • macOS: the Command Line Tools (xcode-select --install); for the macos target brew install sdl2 sdl3 openssl libepoxy; for the windows target brew install makensis.
  • Linux: for the windows target, the distribution's makensis (nsis or mingw32-nsis); on an immutable system it goes in a toolbox or distrobox (blinx2 doctor prints the commands).
  • Windows: a short checkout path (C:\b2) and git config --global core.longpaths true.
./blinx2 import /path/to/BLiNX2.iso   # once: the dump into game_files/ (or copy the files there by hand)
./blinx2 setup       # once: .venv (uv sync from uv.lock), llvm-mingw, the toolkit at its pin; ends with doctor
./blinx2 analyze     # parse the XBE, find functions, classify, recover ABIs
./blinx2 recomp      # lift to C: src/recomp/gen/
./blinx2 build       # macOS: build/cat_recomp; elsewhere: build-win/cat_recomp.exe (windows|macos picks)

blinx2 sets DEVELOPER_DIR=/Library/Developer/CommandLineTools itself; set it yourself when running CMake by hand on macOS.

./blinx2 <command> --help lists the options. package builds in its own build-pkg-macos/ and build-pkg-win/ with the stock options, so your build/ and build-win/ keep whatever options you set; it refuses a Debug or non-stock build (CAT_GEN_OPT, XBOXRECOMP_ENHANCE=OFF) unless told otherwise. The optional ghidra stage (slow, cached) only improves function names; it needs Ghidra (GHIDRA_HOME) and a PyGhidra venv at .venv-ghidra. Never edit src/recomp/gen/ by hand: a function the disassembler missed goes in config/seed_functions.json, then analyze and recomp again (recomp alone misses new seeds).

Running the development build:

# macOS (Metal); RECOMP_PB_BACKEND unset is the slow CPU rasteriser
RECOMP_PB_BACKEND=metal ./build/cat_recomp

Run it from this directory: the game files are looked up in game_files/ (or wherever RECOMP_GAME_FILES points), and saves go to the toolkit's default save root unless RECOMP_HDD_DIR says otherwise. Host pads are on in every build on every host, except while an input script is set (unless RECOMP_HOST_PAD=1), so scripted and golden runs never see one (RECOMP_HOST_PAD=0 keeps them out). The keyboard and the mouse come from build/config.default.toml in every build, with or without host pads. Under Proton, run build-win/cat_recomp.exe with umu-run and RECOMP_PB_BACKEND=d3d11; host pads are on there by default.

The Python tests and the lint run from the locked dev environment (pyproject.toml, uv.lock):

uv run pytest scripts
uv run ruff check . && uv run ruff format --check .

The toolchain and its pins

game.toml pins every moving part; setup fetches them and blinx2 doctor reports what is in use and whether it is the pin.

ComponentPinned atWhereNotes
xboxrecomp-cli (xbr)tag v0.20.0, commit d047f6cgame.toml [cli]The commit locks the tag: a tag moved to another commit is refused.
xboxrecomp toolkit (fork)tag blinx2-v0.13.0, commit 40ed51d, branch blinx2/portabilitygame.toml [toolkit]Cloned into external/xboxrecomp by setup.
llvm-mingw20260922 (clang 23.1.2)game.toml [toolchain], hashes in config/setup-pins.jsonCross-compiles the Windows build on every host.
NSIS3.13game.toml [toolchain]Fetched on Windows; Homebrew or the distribution elsewhere.
umu-launcher1.4.4the CLIWhat the SteamOS installer offers to download on a stock Deck.
Python packagesuv.lockpyproject.toml, uv.lockcapstone and pefile stay on exact versions: another capstone could change gen/.

The toolkit is looked up in this order by CMake, blinx2 and blinx2 bench: $XBOXRECOMP_DIR (or -DXBOXRECOMP_DIR=...), then external/xboxrecomp, then ../xboxrecomp beside this checkout. The CLI: $XBOXRECOMP_CLI_DIR, then external/xboxrecomp-cli (only at the pin), then ../xboxrecomp-cli, otherwise a clone at the pin into external/xboxrecomp-cli. Maintainers move a pin by editing tag and commit together; blinx2 pins refresh re-pins the downloads and prints the newest releases.

Both the CLI and the toolkit fork are public and MIT licensed (the toolkit with the exceptions in its NOTICE). This project builds against the fork, not upstream; upstream-bound changes are offered to sp00nznet/xboxrecomp as pull requests.

Testing and goldens

Three scripted scenarios are compared frame by frame against reference frames (analysis/golden/golden.json, references in analysis/golden/frames/) on every integration build, on both GPU backends, at stock settings (the check fails a run whose log shows a non-stock [ENHANCE] value):

ScenarioRouteRun timeBackends
attracttitle and attract mode75 sMetal, D3D11, CPU
stage1stage 1 gameplay105 sMetal, D3D11
storythe story route to the hub100 sMetal, D3D11
./blinx2 golden run                 # Mac: the Metal build in build/, headless and silent, one scenario at a time
./blinx2 golden run --backend cpu   # the CPU rasteriser (slow; a reference path, not in the routine gates)
./blinx2 bench golden               # a Linux/Proton host over ssh: sync, build in a distrobox, run under Proton, compare

Verdicts land in bench-logs/<stamp>.../golden.txt. ./blinx2 bench --help lists the bench commands (setup, sync, build, run, tests, pacing, gc, ...) and their settings (BENCH_HOST and so on). The CPU rasteriser only has to keep building and passing one check after large merges; speed and A/B work are Metal and D3D11.

The guest runs as on the console's one CPU: RECOMP_GUEST_LOCK (on in this game) runs one guest thread at a time, released at kernel calls, on every host; on Windows and Linux the threads are also pinned to one core (RECOMP_GUEST_CPUS, =all is the A/B). The game relies on it: two of its threads add stage lights to one list without a lock, and on several cores they lost entries and left the ground and water unlit.

Environment variables

Every setting the runtime reads goes through one table, read once at startup, in three tiers: config (one variable each), trace (RECOMP_TRACE=flip,tex,..., printing only) and debug (RECOMP_DEBUG=pb_fast=0,fb_dump=/tmp/f_,..., anything that changes behaviour). The ones you meet first:

VariableValues (default first)Meaning
RECOMP_PB_BACKENDcpu, metal, d3d11, nullthe renderer
RECOMP_GAME_FILESgame_files/ in the working directorywhere the dump is
RECOMP_HDD_DIRthe toolkit's save rootthe emulated hard disk: saves, caches
RECOMP_HOST_PADunset: on, except in scripted runshost gamepads in or out (0/1)
RECOMP_KEYBOARDinput.keyboard: on in config.default.toml, off with RECOMP_CONFIG=none and in scripted runsthe keyboard as pad 1
RECOMP_MOUSEinput.mouse: as RECOMP_KEYBOARDthe mouse as pad 1 (motion is the right stick)
RECOMP_AC97_READYon (x86-64 Windows/Proton; arm64 macOS and Linux); off on native x86-64 Linuxaudio; =0 turns it off
RECOMP_INPUT_SCRIPT@attract, @stage1, @stage1-enemies, @stage1-2, @stage1-2-barricade, @story-hub, @story-load, @story-idle, a filea scripted pad for reproducible runs
RECOMP_HEADLESS0, 1no window, and silent (it sets SDL_AUDIODRIVER=dummy unless set)
RECOMP_CONFIGconfig/config.toml (over config.default.toml beside the executable), a path, nonethe player's config file; none reads no file, not even the defaults (the old name RECOMP_ENHANCE_CONFIG still works)

The full list, with defaults, source references and the trace and debug keys, is docs/env.md. New keys get a row in the table (src/env/recomp_env_game.h for this game's own) and a row in that file; fork code has no raw getenv.

Documentation

DocumentWhat it covers
docs/packaging.mdbuilding and installing the bundles on every target, settings, the HUD pack, troubleshooting, maintainers' pins
docs/input.mdplaying on keyboard and mouse: the default keys, rebinding, the mouse settings
docs/frame-generation.mdexternal frame-generation tools for a 60 fps look (unsupported): what each needs, what to expect from a 30 fps base, the settings that help
docs/env.mdevery environment variable, by tier, with defaults and where it is read
game.tomlthe manifest the CLI reads; the CLI's docs/manifest.md documents each key
analysis/golden/golden.jsonthe golden scenarios, their frames and tolerances
openspec/specs (specs/), open changes (changes/) and the archive; the deviations spec records every departure from the original hardware's behaviour
xboxrecomp-cli READMExbr: starting a new game, the commands, the bench, how a game finds the CLI
xboxrecomp READMEthe toolkit: pipeline, runtime, docs/runtime/config.md (the config.toml keys)

Contributing

The project uses OpenSpec for change tracking. Each piece of work is a change under openspec/changes/<name>/ with a proposal, a design, tasks and spec deltas; finished changes are archived under openspec/changes/archive/ and their requirements merged into openspec/specs/. Departures from the original hardware's behaviour are recorded as requirements in the deviations spec.

Rules that every change follows:

  • opt-in features default off and never change stock behaviour; the golden checks always run at stock;
  • a behaviour change on one GPU backend (Metal or Direct3D 11) is mirrored on the other, or recorded as a follow-up;
  • generated code is never hand-edited; environment variables go through the table and docs/env.md;
  • toolkit changes go to apexJCL/xboxrecomp, branch blinx2/portability; CLI changes to apexJCL/xboxrecomp-cli.

Legal

This repository contains no game data and no game code:

  • no game files, assets or saves;
  • no lifted (recompiled) game code. src/recomp/gen/ is generated on your machine by the pipeline and is never committed.

To build it you need your own legally obtained copy of BLiNX 2. BLiNX 2 and its assets belong to their respective owners; this project is not affiliated with them. A bundle made by blinx2 package contains your copy of the game and code generated from it: it is for your own machines only, and is not yours to redistribute. The same goes for a HUD texture pack made by blinx2 enhance hud: it is built from your game files.

License and credits

MIT, see LICENSE. Parts of src/main.c, src/recomp_manual.c and CMakeLists.txt started from xboxrecomp's MIT-licensed new-game templates; the license file carries that notice too.

The toolkit that the build links in statically carries LGPL-2.1 APU code extracted from xemu. If you distribute a built binary, read NOTICE first.

Built on xboxrecomp by sp00nznet. The HUD pack's Latin font is redrawn from PT Sans Narrow Bold (ParaType, OFL 1.1), which you install yourself; it is never vendored.

Read official guide
CALIFICACIÓN
—
Loading votes…
Advertisement

PROJECT FILE

Project type
NATIVE PORT
Genre
Platformer
Status
beta
Original platform
Xbox
Technology
Static recompilation (native C/C++)
Version
—
Updated
Oct 22, 2026

Target platforms 1

Windows
View on GitHub
Advertisement