RingOut README

The project's README from github.com/jackpoison-prog/RingOut. As one markdown file: README.md.

Ring Out

A native PC port of a GameCube fighting game (disc ID GRSEAF), produced by static recompilation rather than emulation: the disc's PowerPC executable is translated ahead of time into C, compiled for x86-64, and run as native code inside a Dolphin-derived runtime that provides the graphics, audio, input and hardware emulation around it.

No game data and no game code are distributed here. You supply a disc image you already own; setup extracts it and recompiles it on your machine.

This is still early. Expect rough edges: the game is playable start to finish, but features arrive before their polish does, and something that worked last release can break in the next one. Polish is planned throughout rather than saved up for a 1.0 — and bug reports genuinely help, because most of what gets fixed here was found by someone hitting it.


Status

Fully playable — boots to menu and through gameplay. Every block of the game's own executable runs as native code; the recompiler translates 535,368 instructions with 0 unknown opcodes and no interpreter fallback inside them.

What the interpreter does still cover is the PowerPC exception vectors — 0x500 (external interrupt), 0xC00 (system call), 0x800 (FP unavailable). Those handlers are written into low RAM by the OS at boot rather than living in the disc's executable, so there is no recompiled code to dispatch to and the interpreter runs them until control returns. They account for about 0.7% of executed steps, steadily, because interrupts fire for the life of the session — but only 0.2% of cycles, so there is nothing to win by recompiling them. An earlier version of this page claimed "zero interpreter fallback", which the runtime's own shutdown line has always contradicted.

Rendering is Vulkan on the GPU, with the CPU emulation and the runtime on separate cores.

Steam Deck: supported, with its own package — no toolchain needed, since the module is built on a desktop and copied over. Runs in both Desktop and Game Mode at 45–49 fps in a match. It can also build on the device: install a toolchain and SteamOS compiles its own module, needing no bundled libraries at all — tested end to end on SteamOS 3.8.25, and the way to get the full PGO win there (clang 20 cannot read the shipped profiles). See dist/RingOut-1.0-deck/BUILD-ON-THE-DECK.md.

Netplay: working. Rollback over a deterministic dual-core setup, with a lobby showing live ping and per-player game status; two peers stayed byte-identical over 6,470 frames.


Getting it

Two packages, from the Releases page:

for needs a toolchain?
RingOut-1.4-linux-x86_64.zip desktop Linux yes — compiles on your machine
RingOut-1.4-steamdeck-x86_64.zip Steam Deck / SteamOS only to build a module

The Deck package ships no module: build one on a desktop with the package below, then copy game/ and bin/gGRSEAF_recomp.so across. Add RingOut to Steam as a non-Steam game to launch it from Game Mode.

For desktop, unzip and run:

./RingOut

On first run it asks for your disc image (.iso / .gcm / .nkit.iso / .rvz), then extracts and recompiles it — several minutes, once. Every run after that starts straight away. You can also pass the image directly:

./RingOut /path/to/disc.iso     # or: ./setup.sh /path/to/disc.iso

Requirements

The release binary is built in a Debian 12 container and needs glibc 2.36, which every current distro clears — so the bundled glibc in libc-fallback/ is a fallback almost nobody takes. (This page previously said 2.44, which was the glibc of the machine the runtime used to be built on. The launcher believed the same number and sent every host between 2.36 and 2.44 down the bundled path for no reason, where the Vulkan loader then finds no driver. Both are fixed, and packaging now fails if the two disagree.)


Features

Controls

Key Action
Escape settings menu
Arrow keys navigate; Left/Right change a value or switch tab
Space confirm / activate
Alt+W toggle widescreen
Alt+Enter fullscreen
F1–F8 / Shift+F1–F8 load / save state
Shift+Escape quit

Free camera (enable in the Video tab): Shift+WASD move, Shift+Q/E down/up, Shift+arrows look, Shift+Z/C roll, Shift+1/2 speed, Shift+R reset.


Performance work

Everything below is measured on a fixed-work gameplay benchmark — the same emulated frames, driven by a frame-keyed input script, counted in retired CPU cycles rather than wall time. That harness exists because the earlier one did not measure the right thing: it ran boot and an idle menu, which carry ~0.1% of a real session's paired-single traffic, so a change could look free there and cost 3% in a match. Earlier figures in this README were taken that way and have been removed rather than restated. How the harness works, and the checks that stop a run from measuring the wrong thing, are in docs/measuring.md.

What shipped

Change Effect
Inline the paired-single helper chain psq cost per unit of work −43%
Compile loop back-edges as native goto dispatches −66%, CPU −11.5%
Defer FPRF classification until FPSCR is observable −2.14% cycles (Deck)
-flto=auto module relink 22 min → 6
Profile-guided optimisation −10.3% desktop, −14.1% Steam Deck
Per-region profiles −12.33% for a JP module vs the US profile
On-device profile training (setup.sh --pgo) recovers the full win on any clang

The FPRF one is the shape most of these take: the FP condition register is written 3.07 billion times per run and read 15,885 times — mandatory by architecture, dead in practice — so it is now computed only where something can observe it, with frame hashes proving guest state is unchanged.

What was measured and rejected

Kept here because the negative results cost as much to establish as the wins, and each one looks plausible enough to be retried:

Idea Result
BOLT post-link layout 8.1% slower
-O2 instead of -O3 9.1% slower, despite 12.5% less code
LLVM object backend 4% slower, even removing 43% of dispatches
Leaders-only entry labels 81% of execution fell out to the interpreter
Block-local register allocation tied; no cross-iteration residency to exploit
CR / XER[CA] elision ceiling ~0.05% and ~0.2% respectively
Optical-flow frame generation needs 120Hz+; halves speed with V-Sync on, +8.3ms latency

PGO was itself in the rejected table for a long time — "does not build, SIGBUS before the first frame". That was true when it was written and is not any more. It is now the largest single win here, and the details, including the several ways it silently does nothing, are in docs/profile-guided-optimisation.md.

Frame generation is the odd one out: it works, and the shader does what it says. It is rejected on physics rather than on codegen. Presenting a synthesised midpoint costs a second present, which on a 60Hz panel means a second vblank and therefore emulation at 30 FPS; turning V-Sync off restores 60 but tears. It also adds ~8.3ms of input latency, because a midpoint cannot exist until both of its endpoints do — a poor trade in a fighting game. It would need a 120Hz+ display to have a spare refresh to live in, and every panel this project runs on is 60Hz. Kept on the framegen branch rather than deleted.

The pattern among the rest: BOLT, -O2 and the LLVM backend all bought instruction locality or fewer dispatches, and all three lost by retiring more instructions at lower IPC. PMU attribution explains why — front-end starvation is 2.4% of cycles and the back end is saturated at IPC 1.92. The workload is not inefficient, just large: 86.4 million host instructions per emulated frame.


What's next

Ordered by how much they would help, not by effort. Nothing here is promised.

1. Make it easier to get running. This is the biggest thing between the project and anyone using it. Today setup wants cmake, ninja, clang and python3 on your machine and takes several minutes before you see the game.

The compile itself cannot go away: the module is your disc's own executable translated to native code, so it is game data and cannot be distributed — that constraint is the whole design, not an oversight. What can go is everything around it:

2. Mods, further than they go now. Texture packs and texture mods work, and character skins install from the menu when their data is exactly the size of the entry they replace. Two gaps are known and neither is hidden by the UI:

Beyond closing those:

3. Whether any performance is left. The stage-by-stage figures behind this page's numbers predate the Steam Deck training its own PGO profile, which was worth 14%. If the slow stages now hold full speed, the performance work is finished and several remaining ideas die with it — which is worth knowing either way.

4. A Windows build — coming. No date yet. The scaffolding from the earlier Windows work is still in the tree, so this is a revival rather than a fresh start — but it is unbuilt and untested today, and nothing currently on the Releases page will run there.

5. Staying current with upstream. The recompiler and the Dolphin-derived runtime both have upstreams that keep moving. Most of the delta is work this fork has measured and rejected, but not all of it.


Known issues

Fixed since the last revision of this page


Building from source

cmake -S ModernGekko -B ModernGekko/build -G Ninja -DCMAKE_BUILD_TYPE=Release
ninja -C ModernGekko/build

Then build the recompiled module for your disc with dist/RingOut-1.0-dist/setup.sh, which drives dolrecomp and compiles the generated C.

Releases are assembled by script, never by zipping a working directory — those hold the extracted disc, saves and build output. Each stage is built from an allowlist and then checked: no disc-derived files, no personal data, and for the desktop package, that the prebuilt runtime can actually load a module built from the sources shipped beside it.

.github/scripts/package-deck.sh     # Steam Deck zip
.github/scripts/package-dist.sh     # desktop Linux zip
.github/scripts/regen-source.sh     # refresh the GPL source shipment

Repository layout

Path What it is
ModernGekko/ the runtime fork — chassis, settings overlay, StaticRecomp core
ModernGekko/vendor/dolphin/ the vendored Dolphin tree the runtime is built from
DolRecomp/ the static recompiler fork (PowerPC → C)
dist/RingOut-1.0-dist/ the desktop redistributable: launcher, setup.sh, module build recipe
dist/RingOut-1.0-deck/ the Steam Deck package scaffolding
dist/shared/gc-art.py extracts the game's banner and icon on the player's machine
.github/scripts/ packaging, the privacy scan, the GPL source shipment, benchmarks
.github/deck-notes/ the toolchain notes kept on the test Deck's desktop
docs/measuring.md how performance is measured, and the checks that keep it honest
docs/profile-guided-optimisation.md PGO: what it is worth, and how it silently does nothing
work/mg_userdir/GameSettings/ the cheat lists this project authored (US, JP)

Everything is vendored as plain files — clone and build, no submodule init needed.


Credits

Almost none of the heavy lifting here is original. This is a thin layer on other people's work:

RingOut (jackpoison-prog/RingOut)

Searching Database…

Что это?RingOut — нативный ПК-порт файтинга для GameCube (дисковый ID GRSEAF), созданный статической рекомпиляцией, а не эмуляцией: оригинальный исполняемый файл PowerPC заранее переведён в C, скомпилирован под x86-64 и выполняется как нативный код внутри рантайма на базе Dolphin, который вокруг него эмулирует графику, звук, ввод и железо.
Это, по сути, эмулятор или нечто иное?Это не традиционный эмулятор — каждый блок собственного исполняемого файла игры (535 368 инструкций) заранее перекомпилирован в настоящий нативный код, без единого неизвестного опкода и без запасного интерпретатора внутри. Через интерпретатор по-прежнему работают только векторы исключений ОС — около 0.2% циклов.
Как его запустить?Скачайте со страницы Releases пакет для десктопного Linux или для Steam Deck, распакуйте и запустите. При первом запуске он попросит ваш образ диска GameCube (.iso/.gcm/.nkit.iso/.rvz), затем извлечёт и перекомпилирует его — это занимает несколько минут и происходит только один раз.
Что нужно, кроме моего собственного диска с игрой?Нужен образ диска GameCube, которым вы уже владеете, плюс cmake, ninja, python3 и clang (или gcc) на машине для компиляции рекомпилированного кода, а также рабочий драйвер Vulkan. setup.sh определит ваш дистрибутив и подскажет точную команду установки, если чего-то не хватает.
Она реально проходится от начала до конца или ещё сырая?Игра полностью проходима от начала до конца: загружается через меню и в геймплей, но проект сам называет себя ранним: фичи иногда появляются до полировки, и то, что работало в одном релизе, может сломаться в следующем.
Можно запустить и на Steam Deck, и на десктопном Linux?Да. Для Steam Deck есть отдельный пакет, не требующий тулчейна (модуль собирается заранее на десктопе и просто копируется), он работает и в Desktop, и в Game Mode, выдавая 45–49 fps в матче; при желании модуль можно собрать и прямо на устройстве, если установить тулчейн.
В загрузку входит сама игра?Нет. Ни код игры, ни её данные с этим проектом не распространяются; вы должны предоставить образ диска игры, которой уже владеете, а установщик извлечёт и перекомпилирует его на вашей же машине.
Работает ли сетевая игра и как она синхронизируется?Да, два игрока могут соединиться напрямую (LAN, VPN или проброшенный порт), в лобби видны живой пинг и статус. Синхронизация основана на задержке (delay-based), а не на rollback: оба узла применяют одинаковые вводы на одном и том же кадре, буфер ввода настраивается (1–20 кадров, по умолчанию 5), и этот детерминизм проверен на побайтовую идентичность на протяжении 6 470 кадров.
Можно ставить моды и HD-паки текстур?Да. Положите HD-пакет текстур в userdata/Load/Textures/GRS/ или скачанный архив мода в userdata/Load/Mods/ — он автоматически распакуется и появится во вкладке MODS в игре; скины персонажей записываются прямо в данные игры.
Какая работа по производительности сюда вложена?Проект собрал собственный точный до цикла бенчмарк и выпустил реальные выигрыши вроде профиль-ориентированной оптимизации (-10.3% на десктопе, -14.1% на Steam Deck) и инлайна цепочки helper-функций paired-single (-43%), при этом задокументировав и отвергнутые идеи — например, post-link-раскладку BOLT и генерацию кадров, — потому что на практике они показали себя хуже.
Size
87.7 MB
Stars
162
Age
1mo
Commits · 90 Days