suyu v0.0.11
v0.0.11 makes Export Game something a player can use end to end: pick a game, get a
package you can double-click or launch from Steam, with your controllers, settings and
shader cache carried over. It also brings Apple Silicon Macs back, adds a RetroArch
(libretro) core, and makes pre-compiled (static) games much faster: Mario Kart 8
Deluxe's race goes from about 24 to about 56 fps on Windows and to about 60 on macOS
and Linux, with identical results.
Before you upgrade: re-export your old builds.
Every static or Hybrid game build made with v0.0.10 or earlier must be exported
again. This release refuses older builds on purpose instead of running them
incorrectly. Re-exporting also picks up the speed-ups and the fixes below (real update
version, shader cache, firmware, controllers).
Which CPU mode should I use?
- suyu Dynarmic JIT (Baseline): the normal emulator, and now the default. It is the
most compatible and runs Mario Kart 8 Deluxe at 60 fps (see
Performance). - suyu Hybrid JIT + AOT (experimental): runs pre-compiled code and falls back to the
JIT for anything the pre-compiled code doesn't cover. Performance varies by game;
compare it with the Dynarmic JIT export. - suyu static AOT (Experimental): pre-compiled code only, with no JIT fallback. It now
runs Mario Kart 8 Deluxe close to the JIT's speed, but it is tested on that one game;
treat other games as experimental.
Downloads
| File | What it is |
|---|---|
suyu-windows-x86_64.zip
| Windows 10/11 x64: suyu and suyu-cmd |
suyu-linux-x86_64.tar.gz
| Linux x64: suyu and suyu-cmd (uses your distribution's Qt, FFmpeg and SDL) |
suyu-macos-arm64.zip
| macOS on Apple Silicon: suyu.app, with suyu-cmd inside it
|
suyu-android-arm64.apk
| Android, 64-bit ARM |
suyu-libretro-windows-x86_64.zip
| RetroArch core for Windows |
suyu-libretro-linux-x86_64.tar.gz
| RetroArch core for Linux |
suyu-libretro-macos-arm64.zip
| RetroArch core for macOS: put suyu_libretro.dylib and the suyu_libretro_libs folder in RetroArch's cores folder together
|
suyu-libretro-android-arm64.zip
| RetroArch core for Android (development build) |
suyu-v0.0.11-source.tar.gz
| The complete source these files were built from, submodules included |
- macOS: the app is not notarized by Apple. The first time, right-click
suyu.app
and choose Open, or runxattr -dr com.apple.quarantine suyu.app. - Android: install the APK directly. Android asks you to allow installs from the
app you open it with. The APK is signed with the public test key from the source
code (see Known limitations). If another suyu APK is already installed, uninstall it
first.
Highlights
Faster pre-compiled games
- Static and Hybrid exports run much faster. On Windows, Mario Kart 8 Deluxe's race goes
from about 24 to about 56 fps; on macOS and Linux it runs at about 60 fps, using
about half the CPU it did. Game behaviour is unchanged: every speed-up is checked to
give bit-identical results. - On Windows, Build exports compile the game's code with Clang when it is installed
(winget install LLVM.LLVM, or Visual Studio's "C++ Clang tools for Windows"). Clang
alone makes the game about 45% faster than Microsoft's compiler, and the export takes
about 10 minutes instead of 22. Without Clang the export still works with Microsoft's
compiler. - Re-export a game to get this.
Helping more games run pre-compiled
- Playing a Hybrid export now records any code the pre-compiled part couldn't run and
had to hand to the JIT: code loaded later, or instructions not supported yet. It is
kept in the package and in your installed suyu, and grows with every session. - The export dialog shows what's known for the selected game, for example "no
untranslated code in 5 Hybrid runs" (static AOT should work) or "7 instruction types
still need Hybrid". - A new export of the same game version includes any recorded addresses it can
translate. - Import / Export coverage file lets players pool this per game. The file holds
only module IDs, code offsets and counts: no game code and no personal paths.
Export Game (Windows)
- The CPU backend list now starts with suyu Dynarmic JIT (Baseline), which is selected
by default. Build is the default format on Windows. Linux and macOS targets still
produce Source only. - An Update row shows which game update the export will use, and a "From:" line
shows where it comes from. - Install Update File… installs a game update (.nsp) after checking that it belongs
to the selected game. If no update is installed, exporting asks whether to install
one or export without it. - A game file with a bundled update, while updates are turned off for that game, is
stopped before the export starts instead of failing at the end. - The default output folder is
exportsinside the source folder when suyu runs from
a source checkout (Git ignores it). Otherwise it is your Downloads folder. - The progress bar follows the real work. The status line shows, for example,
"Compiling 312/940 files (main)" or "Copying game data: X of Y MB". - Packages copy your suyu settings (graphics, CPU, audio, system, applets). Debug and
unsafe settings, folder paths, input devices and personal data are left out. With
Include custom game configuration ticked, the game's own settings are added on
top. - Include transferable shader cache now works. Before, the cache went to the wrong
folder, the JIT package had its disk cache turned off, and the dialog could untick
the save, shader and config boxes before you saw it, so a package started with an
empty cache and a new profile. On the JIT package this
removed a 5-second freeze at race start. - Packages report the update's real version. Older packages showed "Ver. 1.0.0";
re-export them to fix it. - An exported game's title bar shows FPS, frame time, "Building N shaders" and
the CPU backend, so you can tell when a stutter is a shader being built. While it
prepares its shader cache at start-up it shows "Building shaders N/M" instead of
looking frozen. - The F12 controls panel has a Resolution Scale choice. It is saved in the package
and takes effect the next time the game starts. - A shader cache whose last entry is damaged (for example after a crash) now keeps
every good entry instead of being thrown away. - Exporting the same game again is reliable. Old generated code is reused only when
the game code matches, leftover modules are removed, and an old version number no
longer carries over. - Mismatched game data (base game data paired with update code, and similar mixes)
is refused up front instead of producing a broken build. - A Source export on Windows is labelled as C source code, and a Build export
only reports success when the launcher actually compiled.
Keys and firmware in exported games
- Exports never contain keys or firmware. An exported game reads them from your
installed suyu:%APPDATA%\suyu\keysand%APPDATA%\suyu\nandon Windows, or the
user\folder of a portable suyu. A custom NAND folder set in suyu is honoured. - If
prod.keysis missing, the game shows a dialog with the exact folder and the
buttons Install keys in suyu (when the suyu that made the export is found),
Open folder and Quit. Copyingprod.keysinto that folder works just as well. - If firmware is missing, the game warns and offers Continue anyway. Mii screens
and some menus may fail without firmware. - Exported games now read the installed firmware. This fixes an empty "Select a Mii"
screen in Mario Kart 8 Deluxe.
Controllers in exported games
- The first gamepad becomes Player 1. More pads become Players 2–8 in the order they
connect, as Pro Controllers. - Unplugging a pad disconnects that player. Plugging it back in returns it to the same
slot (Players 2–8; an empty Player 1 goes to the next pad that connects). - Player 1 is never left empty: if all pads leave, the keyboard goes back to Player 1.
- Devices that aren't gamepads are ignored. Left and right Joy-Con halves combine
into one player automatically. The F12 controls panel has Combine Joy-Cons into
one player and Split Joy-Cons into two players buttons. - The Home button works on gamepads.
- Choosing Use keyboard or Rebind in the F12 controls panel turns automatic
assignment off for that package. - Tested live with two pads (PowerA and Xbox Series X) at 60 fps in the JIT export.
Steam
- Add to Steam library when the export finishes adds a non-Steam shortcut that
runs the export's own program. It is named after the game and backend, for example
"Mario Kart 8 Deluxe (suyu Dynarmic JIT)", "(suyu Hybrid JIT + AOT)" or
"(suyu static AOT)". - …and replace an existing shortcut removes only suyu's own shortcut for that game.
- Steam artwork (cover, banner, hero, logo, icon) is made from the game's icon. The
optional …and fetch cover art from Wikipedia uses Wikipedia cover art instead;
it sends the game's title to Wikipedia. - Your other Steam shortcuts are kept byte for byte. If suyu can't fully read Steam's
shortcut file, it leaves the file untouched. - Restart Steam to see changes. Steam shows no description for non-Steam games; that
is a Steam limitation.
Discord
- While a game runs, Discord shows you as playing suyu. The activity names the game and
uses its cover as the image. This works from the suyu launcher and from exported
Windows games. - The cover comes from Wikipedia, which receives the game's title. In the launcher,
the suyu logo shows until the cover is found. Turning off Show Current Game in your
Discord Status (Configure → Web) stops both the status and the lookup. - Exported games have a new option, Show this game in Discord (cover art from
Wikipedia), on by default. The cover is looked up once, while exporting; the game
itself doesn't go online for it. To turn Discord off for an exported game later, set
enabled=0in thediscord.ininext to its program. - In a NetPlay room, the room's name replaces the game's name. No address, password or
join link is shared.
macOS (Apple Silicon)
- Apple Silicon Macs work again (community PR #1 by @mmkzer0, thank you). Rendering
goes through MoltenVK and Metal. - Fixed long stalls (0 fps for 10–40 seconds). The Mac JIT went from a 1.2 fps average
to 56.6 fps, and RetroArch on Mac now reaches the race at about 59 fps. - Fixed a crash when the game ends (0 crashes in 9 runs, against 1 in 3 before).
- Fixed a crash at renderer startup, a Metal window-surface lookup failure, and GPU
cleanup after an error. - Fixed several MoltenVK visual problems: copies between images with mismatched
block formats, and output fixups that touched unbound attachments. - Emulator threads use macOS priority classes (QoS), and the game window comes to the
front when a game starts.
RetroArch / libretro core (new)
- A Vulkan libretro core for Windows, Linux and macOS. It supports base game plus
update loading with identity checks, TAS playback and core options. - A "Game X.X FPS · N ms" readout is on by default (core option Show Game
Performance). While shaders are being built, the shader count replaces the frame
time. Trust it over RetroArch's own counter, which also counts repeated frames. - Starting from a fresh RetroArch profile works: keys are picked up before boot, and
bad or incomplete game files are rejected with a clear error instead of crashing.
Android
- The Android app (APK) and an ARM64 libretro core build, with the stall fix
above compiled in. The libretro core is an opt-in development build, separate from
the app. - It has only been run in the Android emulator, which has no GPU and shows about
4–8 game fps. That is not a real-device result.
Everyday usability
- View → Resolution Scale changes the internal resolution without opening
Settings. A game's own resolution setting still wins, and the app tells you when
that happens. - The status bar shows which CPU backend is actually running and counts JIT fallbacks,
or shows "NO JIT". - The branch name no longer appears in the window title.
Graphics fixes (all platforms)
- A shader pipeline that fails to build now skips that one draw instead of freezing
the game. - Shader resources are declared the way stricter drivers expect, which fixes shader
validation failures. - Texture storage support is checked against the format actually chosen. An empty
texture slot is treated as "nothing bound" instead of causing a format error.
Other fixes
- Shutdown: the GPU thread now finishes and stops before GPU services close. This
fixed the Mac crash above. - Windows: fixed memory corruption when a game closes. The renderer was destroyed after
the GPU channels it still pointed at, and its last flush wrote into freed memory; it
surfaced as an intermittent crash on exit. Caught with page heap at the exact write,
then verified: 0 corruptions in 7 runs with the fix, while the old build still stops. - Fixed a rare crash when a game thread ends, mostly seen while closing a game: the
emulated kernel released a finished thread while holding the scheduler lock, so a
lock it then needed could be "taken" without being owned. The thread is now released
after that lock is dropped. 0 crashes in 8 debug-heap runs, against about 2 in 11. - Adding, repairing and removing Steam shortcuts uses safe all-or-nothing writes.
- An exported game that fails to load its game now exits after showing the error,
instead of carrying on with nothing loaded.
Performance
Mario Kart 8 Deluxe v4.0.0, game fps during a race (the game runs at up to 60), 3 runs
per figure unless noted. Measured 2026-09-22 to 2026-09-24.
| Dynarmic JIT | Strict static, v0.0.10 code | Strict static, v0.0.11 | |
|---|---|---|---|
| Windows x64 (Ryzen 9 9950X3D, Radeon RX 9070 XT) | 60 | 23.7 | 56.1 (median 59) ¹ |
| macOS Apple Silicon | 59–60 | 53.7 | 59.9 ² |
| Linux x64 (RTX 3090) ³ | 60 | 39.4 | 59.8 |
¹ A real Build export with default settings and Clang installed. Hybrid with Clang
reached 51 fps in one run, before the other speed-ups.
² Reaches the 60 fps cap; the CPU it uses dropped 44%.
³ Static starts several seconds later than the JIT, so its race was measured with the
TAS input delayed to match. CPU use dropped 50%.
Where the speed comes from (Windows, each step added to the previous one):
| Step | Race fps |
|---|---|
| Microsoft's compiler (v0.0.10 code) | 23.7 |
| Clang instead | 34.6 |
| Fast guest-memory access | 36.0 |
| Code checked once per change instead of on every block | 40.2 |
| Exact native floating point | 56.3 (all three together; 53.1 without the code check) |
Every step keeps results bit-identical, and each can be switched off (see
For developers). Exports also now compile with full optimisation
(/O2, -O2).
Shader cache on the Windows JIT package: 55.7 → 58.8 average fps, the 5-second freeze
at race start removed, and the worst frames down from 66 ms to 26 ms.
Known limitations
- Portable settings, the keys/firmware startup check and automatic controller
assignment apply to Windows packages. Linux and macOS exports are Source only and
have no bundled runtime. - Steam shortcuts go to the first Steam account found on the computer.
- Re-exporting renames an existing Steam shortcut in place (for example to the new
"(suyu Dynarmic JIT)" style names). Steam keys artwork and play time by a shortcut's
name, so those start fresh for the renamed entry. - A game that isn't in your suyu library is named in Steam after its file name.
- Joy-Con auto-assign and Combine/Split are covered by automated tests but haven't been
tried with real Joy-Cons yet. - Very occasionally a game crashes during start-up (about 1 in 30 test launches, while
system services start); launching it again works. Closing suyu while the Export Game
dialog is open can also crash it. Both predate this release. - Static exports are tested on Mario Kart 8 Deluxe only. They start several seconds
later than the JIT (about 8 s on Linux). - On Windows the full static speed needs Clang (LLVM). With only Microsoft's compiler
the export still works but runs slower; that combination wasn't benchmarked with this
release's speed-ups. - Android has not been tested on a real device, so its real performance is unknown.
- The Android APK is signed with the public test key that ships in the source code, not
a private release key. Only install it from this release page: anyone can sign an
APK with that key. If a later release moves to a private key, updating will need an
uninstall first, which removes the app's data, so back up saves before then. - In the Android emulator, black margins around the picture come from the emulator's
camera-cutout setting, not from suyu. - On macOS RetroArch and Android, RetroArch's FPS counter reads higher than the game's
real frame rate; use the core's own readout. - Static mode is per-title. Smash Ultimate in strict-static mode still hits uncovered
code. - Discord: Join buttons and achievements are not supported. The NetPlay room name in
Discord has not been tried in a live room yet. Exported games appear under their
package name, for example "Mario Kart 8 Deluxe - Dynarmic JIT". - Downloads never include games, generated game code, keys, firmware or saves.
The downloads include the Dynarmic JIT. A build without it is made from source with
-DSUYU_NO_JIT=ON; separate no-JIT downloads are no longer published.
For developers
Static recompiler: ABI 6 (new default)
-
Exports now produce ABI 6: ABI 5 plus three negotiated features. An image reports
its feature bits, and a host refuses any bit it doesn't implement, so an older suyu
can't load a newer export by accident.- FM1, fast guest memory (bit 0): loads and stores read suyu's page table
directly. Unmapped, special, GPU-tracked and page-crossing accesses fall back to the
unchanged ABI 5 helper. - GG1, generation code guard (bit 1): a block's instruction words are checked once
per code change instead of on every entry. The host moves the generation on every
path that can change code: instruction-cache invalidation, map/unmap/protect, page
table swaps, stores and host writes to watched code pages. Modules it can't prove
stable (writable, aliased, device-mapped, raw pointers handed out) keep per-entry
checking. - FPX1, exact native FP (bit 2): native host floating point is kept only when it
provably matches the AArch64 result and flags; everything else uses the exact
soft-float. The host enforces the FP mode it needs.
- FM1, fast guest memory (bit 0): loads and stores read suyu's page table
-
Switches:
SUYU_AOT_FASTMEM=0,SUYU_AOT_GUARD_GEN=0orSUYU_AOT_FPX=0leave a
feature out of an export (SUYU_AOT_FASTMEM=0gives ABI 5, byte-identical to before).
SUYU_RECOMP_FASTMEM=0,SUYU_RECOMP_GUARD_GEN=0andSUYU_RECOMP_FPX=0turn one
off at run time. -
Validation: byte-identity golden hashes with each feature off, new smoke-test modes
for every fallback and hook, a differential memory fuzz, and an FP harness matched
against Apple M-series hardware, including all 2^32 inputs of the unary operations. -
Exactness fixes (all ABI versions): vector FRECPS/FRSQRTS were computed unfused;
scalar FMAX/FMIN/FMAXNM/FMINNM returned the wrong signed zero; scalar FSQRT of a
negative gave the wrong NaN sign on x86; FCMP/FCCMP, the FCMxx compares, integer↔FP
conversions and scalar FRINT didn't set FPSR; vector FCVTMS/FCVTMU were decoded as
FCVTZS/FCVTZU. -
Windows exports and clang-cl: the generated modules build as their own project
with clang-cl (found viaSUYU_CLANG_CL, LLVM's default path, Visual Studio's bundled
Clang, then PATH), and are linked intosuyu-cmd-staticwith MSVC's linker.
SUYU_RECOMP_COMPILER=msvcforces the old path; any clang-cl failure falls back to
it. The compiler used is recorded in the log, README andaot_manifest.json. -
Coverage gaps: Hybrid and strict runs merge
user\log\recomp_gaps.json(lookup
misses as module build ID + offset, modules that ran without an image,
unimplemented opcodes, run counts; schema-versioned) and the installed suyu's
recomp\gaps\<TITLEID>.json. The exporter passes recorded offsets as extra
discovery roots only for an exact build-ID match, logs mismatches, and records the
count inaot_manifest.json; with no gaps the output is byte-identical. In practice
the emitter already indexes nearly all of.text, so most recorded gaps will be
late-loaded modules and unimplemented opcodes, which re-export cannot fix.
Static recompiler: ABI 5
- ABI 5 validates generated image revision, instruction coverage and memory guards
more strictly. ABI 4 images are rejected at build time, by the CMake header check,
and again at runtime, byrecomp_image_abi(). - Correctness over speed: ABI 5 deliberately reverts two experimental
speed-ups from the iOS branch.- Per-entry code verification is restored. The shared generation-counter guard
(check-once code guard) has been removed, and theguard_generationslot is kept
for layout only. Hosts must set it to null. - The native AArch64 host-FP fast path is removed. It didn't raise guest FPSR
flags, and its results depended on the ambient host FPCR. - FP conversions now use integer significands with exact FZ, rounding and sticky
FPSR behaviour. Recovering that speed without losing correctness is future
work.
- Per-entry code verification is restored. The shared generation-counter guard
- Relocation policy
rtld-only: relocations are pre-applied to rtld only, which
matches Dynarmic's behaviour. Fixes deferrednn::roNRO imports never binding
(0/909 fighter slots bound in Smash). The rejected alternatives remain available
behindSUYU_RECOMP_RELA_POLICY. - Correctness fixes:
- Guarded guest reads are safe across page boundaries.
- Page-crossing accesses no longer take the host-pointer fast path.
- The exclusive reservation is cleared when a core switches guest threads.
- Undefined weak symbols resolve to zero.
- Exclusive state is cleared per thread.
- Shifted-register encodings that are undefined for
sf==0 && imm6>=32are
refused and counted as uncovered. - Word-level normalisation and sticky flag scans.
- Fixed-point conversion and FPSR behaviour have synthetic regression coverage.
- Stricter loading: known base RomFS / updated ExeFS and standalone NCA code/data
mismatches are rejected. Two non-base views from an installed update still need
title-specific verification before a package can be called playable. - Page-crossing code guard: a block that crosses a page boundary is now checked
with onememcmpper page instead of a host callback per instruction word, and the
host's instruction-read callback checks page validity once per word, not per byte.
The same words are still compared, and any mismatch or unmapped page still stops at
the exact word. On Linux x64 this cut MK8D's boot pause from 7.7 to 5.8 seconds.
Re-export to get it. - Hybrid's frequent JIT fallbacks for one vector instruction are deliberate and help
its performance. - Generated C no longer inherits the host's
-Werror. - Keys and window naming for static exports now work on non-Windows hosts.
- Env-gated diagnostics (inert unless set): targeted PC sampling, handover
cutoffs, a guest-thread dump with arbiter keys, and a kernel lock trace.
Core
- arm64 exclusive monitor: guest spin loops could saturate Dynarmic's global
exclusive-monitor lock and starve other cores (0 fps for 10–40 s). The fix is
enabled for arm64 GCC/Clang builds only (macOS, Linux arm64, Android); x64 is
unchanged. - Shutdown order: the GPU thread is drained and joined before GPU services close.
macOS: 0/9 exit crashes, against 1/3 before. - Renderer destruction order:
GPU::Impl::~Implnow destroys the renderer before
channels/scheduler. Otherwise~RasterizerVulkan→Scheduler::Finish→
InvalidateStateORs into a freed channel's Maxwell3D dirty flags (Windows 0xC0000374
at a later free). Found with per-process full page heap. - Kernel thread release:
KThread::FinishTerminationnow callsClose()after its
KScopedSchedulerLockscope. AKLightLockwait nested inside the scheduler lock never
blocks for host threads, soFinalize()(TLS unmap under the page-table lock,
UnregisterThreadunderm_list_lock) could "acquire" a contended lock without owning
it, corrupting the lock tag and ending inKThread::EndWaiton a stale wait queue. - Exported games read the installed firmware. Without it, the MK8D Mii thread was
killed in strict static mode. - The application process is released before the kernel is torn down, which fixes
a shutdown-ordering crash. - The fastmem arena is placed elsewhere when the low address window can't hold it.
This is needed on 16 KiB-page hosts such as Apple Silicon. - The frontend can override the reported application version, and the override is
saved in settings. - Explicit base/update content selection goes through a read-only provider and
rejects a second, unrelated launch path. - Logging is rate-bounded per call site, so one repeating message can't flood the
log.
Frontend and packages
suyu -install-keysandsuyu -install-firmwareopen Tools → Install Decryption
Keys / Install Firmware once the window is up. An exported game that is missing
either starts suyu this way.- Exported packages look for
prod.keysorprod.keys_autogeneratedin the installed
suyu'skeysfolder, and for firmware in the package's own NAND first, then the
installed one (including a customnand_directory). - Controller auto-assignment is stored per package under
[Controls]as
auto_assign_controllersandauto_assigned_pads. - Steam shortcut edits preserve other entries byte for byte and leave
shortcuts.vdfuntouched when it can't be fully read. - Discord Rich Presence (
USE_DISCORD_PRESENCE) is now on by default for desktop
builds, andsuyu-cmdpublishes it too.suyu-cmdreadsdiscord.ini
(enabled,cover_url) from its own folder and makes no network requests; without
the file it publishes the title with the suyu logo. The Wikipedia lookup is shared
with the Steam artwork step. Seedocs/discord-integration.md.
libretro
- Repeated frames are marked as repeats.
- The Show Game Performance core option (on by default) applies immediately.
- The core reports suyu's real version and commit to RetroArch instead of "0.04".
- The black margins seen in the Android emulator came from an emulator camera-cutout
setting, not the core.
Tooling and measurement
suyu-cmd -t/--tasreplays a TAS script headlessly.SUYU_CMD_PERF_SAMPLE=1logsgame_fps,system_fps,frametime_msandspeed
once per second, as a series. Stalls show up as gaps instead of disappearing into
an average.SUYU_CMD_CAPTURE_DIR,..._FIRST_SECand..._INTERVAL_SECtake periodic
screenshots. Bounded capture runs stay off the active desktop.- The video core attributes frame stalls to where the wall-clock time actually goes.
scripts/mk8d-tas/adds a source-only 6,001-frame TAS for MK8D v4.0.0. It covers
menus, then Mushroom Cup, then the opening of Mario Kart Stadium.- iOS research: a separate static-AOT diagnostic host lives under
research/ios.
It ran signed no-JIT gameplay frames on an iPhone 16 Pro Max. It's research
only and isn't a release target. The ~2× iPhone speed-ups tried there are not
in ABI 5; see above.
Build and release
- The build no longer requires the Qt Svg component. The macOS MoltenVK
configuration is fixed. - CoreTiming tests no longer depend on the order they run in.
suyu-v0.0.11-source.tar.gzincludes all 37 submodules. The source archives
exclude opaque prebuilt binaries, developer caches and generated proof outputs.- The source archive carries
GIT-COMMIT,GIT-TAG,GIT-REFSPECandGIT-RELEASE,
so a build from it reports v0.0.11 instead of "1.0.0".
What was tested
- Windows: GUI, CLI and libretro builds. Export regression fixtures. Nine libretro
lifecycle modes, plus TAS and core-options smoke tests. MK8D v4.0.0 JIT, Hybrid and
static exports measured in a race (table above), and two-pad controller assignment
in the JIT export. A default-settings Build export through the GUI (clang-cl, ABI 6)
raced 3 times at 55.6–56.6 fps. - Linux: GUI, CLI and libretro builds. CTest 71/71, focused recompiler tests 24/24.
MK8D JIT at 60 fps; strict static ABI 5 at 39.4 and ABI 6 at 59.8 fps, 3 runs each on
the same delayed TAS input. - ABI 6, all three platforms: every race run finished the TAS with zero critical
errors and zero JIT fallbacks, the generation guard kept all modules on its fast path,
and FPX1 was negotiated. - macOS ARM64: GUI, CLI and libretro builds. CTest 55 passed, with 16 expected
fastmem skips on 16 KiB pages. Focused tests 24/24. JIT, static and RetroArch reached
the race. - Android: the ARM64 debug APK built and its debug signature verified; release
signing was not tested. The opt-in libretro core built and showed on-track movement
in a software emulator (low fps, not a real-device benchmark). - Strict-static MK8D v4.0.0: the TAS replay reached a rendered, controllable race
segment with zero JIT fallbacks and zero critical errors. This is a per-title test,
not a compatibility guarantee. - Discord (Windows): Discord showed suyu as the current game from the launcher and
from an exported game's program, and cleared it when the game closed. The cover
lookup found MK8D's cover, and the switch indiscord.initurned Discord off. - Not established: firmware applet CPU-backend attribution.
Full changelog: v0.0.10...v0.0.11