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)的原生 PC 移植版,采用静态重编译而非模拟:原始 PowerPC 可执行文件被提前翻译成 C,针对 x86-64 编译后作为原生代码运行,外围由一个衍生自 Dolphin 的运行时处理图形、音频、输入和硬件模拟。
它本质上是个模拟器,还是别的东西?它不是传统模拟器——游戏自身可执行文件的每个代码块(535,368 条指令)都被提前重编译为真正的原生代码,未知操作码为 0,其内部没有解释器回退。只有操作系统异常向量——约占周期数的 0.2%——仍通过解释器运行。
怎么让它跑起来?从 Releases 页面下载桌面 Linux 或 Steam Deck 包,解压后运行。首次启动时会要求提供你的 GameCube 光盘镜像(.iso/.gcm/.nkit.iso/.rvz),然后提取并重编译,需要几分钟且只发生一次。
除了自己的游戏光盘,我还需要什么?你需要一份自己拥有的 GameCube 光盘镜像,机器上还要有 cmake、ninja、python3 和 clang(或 gcc)来编译重编译生成的代码,以及可用的 Vulkan 驱动。如果缺少什么,setup.sh 会检测你的发行版并告诉你确切的安装命令。
它能从头玩到尾,还是仍然很粗糙?它可以完整地从开头玩到结尾,能从菜单启动进入游戏,但项目自称仍处于早期:功能有时在打磨完成前就已上线,上一个版本正常的东西到下一个版本可能就坏了。
除了桌面 Linux,我能在 Steam Deck 上运行它吗?可以。Steam Deck 有专属的包,无需工具链(模块在桌面端预构建后直接拷贝过去),在桌面模式和游戏模式下比赛中都能以 45–49 fps 运行;如果你安装了工具链,它也可以直接在设备上构建自己的模块。
下载包里包含游戏本体吗?不包含。本项目不分发任何游戏代码或数据;你必须提供自己拥有的游戏光盘镜像,由 setup 在你自己的机器上提取并重编译。
联机对战能用吗,是怎么同步的?可以,两名玩家可以直接连接(局域网、VPN 或端口转发),大厅会显示实时延迟和状态。它基于延迟而非回滚:双方在同一帧执行相同的输入,输入缓冲可调(1-20 帧,默认 5 帧),这种确定性已在 6,470 帧上验证为字节级一致。
我能安装 mod 和高清材质包吗?可以。把高清材质包放进 userdata/Load/Textures/GRS/,或把下载的 mod 压缩包放进 userdata/Load/Mods/,它会自动解包并显示在游戏内的 MODS 标签页中;角色皮肤会直接写入游戏数据。
这个项目做了哪些性能优化工作?项目构建了专用的周期精确基准测试,并交付了实实在在的优化成果,例如剖析引导优化(桌面端 -10.3%,Steam Deck -14.1%)和内联 paired-single 辅助函数链(-43%),同时记录了尝试过但被否决的想法,比如 BOLT 链接后布局和帧生成,因为它们实测表现更差。
Size
87.7 MB
Stars
164
Age
1mo
Commits · 90 Days