github suyu-emu/suyu-main v0.0.11
suyu v0.0.11

latest releases: v0.1.4, v14.1.0, v14.0.1...
one month ago

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 run xattr -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 exports inside 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\keys and %APPDATA%\suyu\nand on Windows, or the
    user\ folder of a portable suyu. A custom NAND folder set in suyu is honoured.
  • If prod.keys is 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. Copying prod.keys into 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=0 in the discord.ini next 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.
  • Switches: SUYU_AOT_FASTMEM=0, SUYU_AOT_GUARD_GEN=0 or SUYU_AOT_FPX=0 leave a
    feature out of an export (SUYU_AOT_FASTMEM=0 gives ABI 5, byte-identical to before).
    SUYU_RECOMP_FASTMEM=0, SUYU_RECOMP_GUARD_GEN=0 and SUYU_RECOMP_FPX=0 turn 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 via SUYU_CLANG_CL, LLVM's default path, Visual Studio's bundled
    Clang, then PATH), and are linked into suyu-cmd-static with MSVC's linker.
    SUYU_RECOMP_COMPILER=msvc forces the old path; any clang-cl failure falls back to
    it. The compiler used is recorded in the log, README and aot_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 in aot_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, by recomp_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 the guard_generation slot 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.
  • Relocation policy rtld-only: relocations are pre-applied to rtld only, which
    matches Dynarmic's behaviour. Fixes deferred nn::ro NRO imports never binding
    (0/909 fighter slots bound in Smash). The rejected alternatives remain available
    behind SUYU_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>=32 are
      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 one memcmp per 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::~Impl now destroys the renderer before
    channels/scheduler. Otherwise ~RasterizerVulkan → Scheduler::Finish →
    InvalidateState ORs 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::FinishTermination now calls Close() after its
    KScopedSchedulerLock scope. A KLightLock wait nested inside the scheduler lock never
    blocks for host threads, so Finalize() (TLS unmap under the page-table lock,
    UnregisterThread under m_list_lock) could "acquire" a contended lock without owning
    it, corrupting the lock tag and ending in KThread::EndWait on 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-keys and suyu -install-firmware open 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.keys or prod.keys_autogenerated in the installed
    suyu's keys folder, and for firmware in the package's own NAND first, then the
    installed one (including a custom nand_directory).
  • Controller auto-assignment is stored per package under [Controls] as
    auto_assign_controllers and auto_assigned_pads.
  • Steam shortcut edits preserve other entries byte for byte and leave
    shortcuts.vdf untouched when it can't be fully read.
  • Discord Rich Presence (USE_DISCORD_PRESENCE) is now on by default for desktop
    builds, and suyu-cmd publishes it too. suyu-cmd reads discord.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. See docs/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 / --tas replays a TAS script headlessly.
  • SUYU_CMD_PERF_SAMPLE=1 logs game_fps, system_fps, frametime_ms and speed
    once per second, as a series. Stalls show up as gaps instead of disappearing into
    an average.
  • SUYU_CMD_CAPTURE_DIR, ..._FIRST_SEC and ..._INTERVAL_SEC take 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.gz includes 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-REFSPEC and GIT-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 in discord.ini turned Discord off.
  • Not established: firmware applet CPU-backend attribution.

Full changelog: v0.0.10...v0.0.11

Don't miss a new suyu-main release

NewReleases is sending notifications on new releases.