ioncodes/sly

A modern multi-system emulator and debugger written in Rust. Supports Windows, Linux, macOS, browsers and mobile phones!

Rust

139

289 commits

updated Oct 16, 2026

See the code

See what people are saying

SourceMessageScoreDate

Sly, a new and modern multi-system emulator, is now public! (r/rust)

**TLDR plz** Sly is my new multi-system emulator, releasing with support for Game Boy Advance and SNES with many, many more planned! It includes a 3D game library, a debugger, a simpler ("classic") desktop frontend and an iOS app, with Android being developed soon. The debugger also runs in your…

191

Oct 16, 2026

README

Sly

Sly is a cross-platform, multi-system emulator for players, homebrew developers and emulator developers alike. It combines a beautiful debugger with a unique take on the classic emulation experience!

Official website · Try the debugger in your browser

Sly Debugger Sly Launcher

Sly has three main desktop frontends, alongside its mobile apps:

  • Sly Launcher: A 3D game library built around box art and cartridges.
  • Sly Classic: A minimal Qt interface for browsing and playing games.
  • Sly Debugger: A beautiful debugger packed with features.

Supported platforms:

  • Windows, macOS and Linux
  • Web browsers via WebGPU (debugger only so far)
  • iOS, with Android planned

Download

Get the latest release:

  • Windows, macOS and Linux: each frontend comes as its own archive: sly-launcher, sly-classic and sly-debugger.
  • iOS: sly-ios-arm64-unsigned.ipa. It's unsigned, so you need to sideload it (for example with AltStore or SideStore).

For the newest changes, try the nightly build. It's rebuilt from the dev branch once a day and may be unstable.

Compatibility

Color means playable or work-in-progress. Click on a logo to see the respective compatibility database.

Super NintendoGame Boy AdvanceGame Boy and Game Boy ColorGame Gear
Master SystemPlayStationGameCubeWii
Sega GenesisDreamcastNintendo DSNintendo 3DS

Features

Sly Launcher

  • 3D boxes and cartridges
  • Row, column and ribbon shelf layouts
  • Flippable box art
  • Automatic artwork downloads
  • Regional packaging and models, with per-game release overrides
  • Per-game cartridge finishes
  • Gamepad navigation
  • Remappable controls
  • Save states
  • Quality presets, text size, reduced motion and integer scaling
  • Fullscreen

Sly Classic

  • Sortable game list with banners
  • Quick save slot plus ten save state slots
  • 1x to 4x scaling and fullscreen
  • Gamepad support
  • Automatic artwork downloads

Sly Debugger

  • Instruction and event stepping
  • Linear and graph disassembly
  • CPU registers and call stacks
  • CPU and memory breakpoints
  • Memory viewer
  • MMIO register inspection
  • DMA inspection
  • Tile, tilemap and background viewers
  • Sprite and palette viewers
  • Various coprocessor workspaces (for example SA-1 and Super FX)
  • Audio visualization
  • Built-in Lua editor and scripting
  • Save states
  • Cartridge info with cover art
  • Light and dark themes with various accent colors

Usage

SystemFile types
SNES.sfc, .smc
GBA.gba

How you load games depends on the frontend:

  • Sly Launcher: add your ROM folders in settings, or pass a folder on the command line.
  • Sly Classic: put your ROMs in roms/{system}/ in the working directory.
  • iOS: copy games into Sly's roms/{system}/ folders using the Files app.
  • Sly Debugger: pass the ROM path on the command line, or drag it into the window.

From the command line:

sly-launcher path/to/roms/
sly-debugger path/to/game.sfc

Artwork

Box art and covers come from art.layle.dev. This works without an account, but anonymous access has lower rate limits. For higher limits, log in at art.layle.dev/account, generate an API key and paste it into the settings of any frontend:

  • Sly Launcher: Settings -> Artwork key
  • Sly Classic: File -> Settings
  • Sly Debugger: the settings popover, under Artwork
  • iOS: Settings -> Artwork

The key is stored in settings.toml in Sly's data folder (for example %APPDATA%\sly on Windows), which all desktop frontends share.

Default Controls

These are Sly Launcher's defaults. All of them can be remapped in settings (gamepads are supported too).

Keys are matched by position, so the labels below are for a US QWERTY keyboard. On other layouts, press the key in the same place (for example, Z is Y on a German keyboard).

Library

ActionKey
BrowseArrow keys / WASD
PlayEnter / Space
Flip boxF
Change viewTab
Search/
Previous / next letterQ / E
Console listC
Previous / next consolePage Up / Down
SettingsF2
FullscreenF11

In game

ControlKey
D-padArrow keys
B / AZ / X
Y / X (SNES)A / S
L / RQ / W
Start / SelectEnter / Backspace
Save / load stateF5 / F8
PauseP
Back to libraryEsc
FullscreenF11

Development

Building

See the build workflow for platform dependencies, including Linux audio and windowing libraries. Run everything from the repository root.

Sly Launcher and Sly Debugger

git submodule update --init --recursive
cargo run --locked -p modern-launcher -- roms/
cargo run --locked -p debugger -- path/to/game.sfc

This should work for most of the Rust crates.

Sly Classic also needs:

  • Qt 6 (CI uses 6.11.1), including Multimedia, ShaderTools and private GUI headers
  • CMake 4.3 or newer
  • Ninja
  • A C++23 compiler
  • naga-cli 29.0.4 (cargo install naga-cli --version 29.0.4 --locked)
  • SDL3 3.2 or newer for gamepads (or configure with -DSLY_ENABLE_GAMEPAD=OFF)
qt-cmake -S frontends/desktop-qt -B build/desktop-qt -G Ninja \
  -DCMAKE_BUILD_TYPE=Release -DSLY_CARGO_PROFILE=release
cmake --build build/desktop-qt

iOS needs a Mac with Xcode 26. Open frontends/ios/Sly.xcodeproj, choose your signing team and run the Sly scheme.

Project layout

Emulated hardware lives in crates/cores/, the shared interfaces in crates/models/ and the frontends in frontends/. If you want to add a system, the GBA core is the easiest one to read. The SNES core is a good example of multiple CPUs and cartridge coprocessors.

The crates you'll touch most:

  • core-model: the Core trait every system implements for playback (frames, audio, input, save states).
  • debugger-model: DebugCore, which adds registers, disassembly, stepping, breakpoints and memory access on top of Core.
  • workspace-model: describes the debugger's workspaces and panels.
  • core-loader: detects ROMs and creates the right core. New systems get hooked up here.
  • cirsium: the debugger's UI components.

Adding a core

  1. Create a crate in crates/cores/<system>/ and add it to the workspace. Copy the setup from the GBA Cargo.toml if you want debugger support behind a debug feature.
  2. Implement core_model::Core for your machine. Only reset, step and run_frame are required. Everything else has a default, so you can add video, audio, input and save states as you go.
  3. Add the system to core_model::System and to the save-state tags in state.rs. Don't change the existing tags.
  4. Hook it up in core-loader: identity, inspect, load, and load_debug once the debugger works.
  5. Check the frontends and bindings for anything system-specific, like controls or assets.

While you're working on a new core, the runner is handy. It's a tiny SDL app that just loads a ROM and plays it, so there's much less in the way than with the other frontends. It only needs cartridge_info and frame_interval on top of the basics.

cargo run -p runner -- path/to/game.gba

Adding debugger support

Wrap your machine in a debug type that implements both Core and DebugCore, like GbaDebug or SnesDebug. Start with CPUs, registers, disassembly, memory regions and stepping. Call stacks, event stepping and scripting can come later.

A few things to keep in mind:

  • Use the same IDs everywhere (for example gba.arm7tdmi and gba.bus). Breakpoints and views refer to them.
  • peek_memory must not change the machine's state. read_bus / write_bus go through the bus with all side effects and patch_memory edits memory directly.
  • The default manifest gives you the standard panels. Override it to add your own workspaces, like the SNES core does for its coprocessors and call ComponentManifest::validate() to check it.

Testing

cargo fmt --all --check
cargo clippy -p gba -p snes --features gba/debug,snes/debug
cargo test -p gba -p snes --features gba/debug,snes/debug

CPU tests run against the SSTs in submodules/:

cargo run --release -p testrunner -- snes
cargo run --release -p testrunner -- gba
cargo run --release -p testrunner -- spc700 --opcodes 00 --limit 100

New CPUs can be registered in testrunner.

Contributing

Contributions are welcome, whether it's a game compatibility fix, a new debugger feature or a whole new core. For bigger changes, open an issue first so we can talk about it before you sink time into it.

Sly also needs more than code! If you have design experience, help with app icons, UI and UX, box art and cartridge models or other visual assets would be very welcome. Open an issue to share your ideas or work.

For pull requests:

  • Branch off dev and open your PR against it.
  • Run cargo fmt --all and make sure the checks under Testing pass.
  • Keep hardware changes in their core and match the style of the surrounding code.
  • Explain what changed and how you tested it. If you ran the CPU tests or checked specific games, mention them.
  • Add screenshots for anything visual.
  • Don't commit ROMs, BIOS files or build output.

LLM usage

You may use LLMs to help write your code, but I strongly recommend against it. Either way, you're expected to understand every change you submit and be able to explain it yourself. Don't act as a proxy for an LLM. Issues, PR descriptions and discussions must be written by you. LLM usage must be disclosed.

License

GPL-3.0 · Third-party notices

Sly is not affiliated with Nintendo or other console manufacturers. Game titles, artwork and trademarks belong to their respective owners.

debugger
emulation
gba
snes

ioncodes/sly

A modern multi-system emulator and debugger written in Rust. Supports Windows, Linux, macOS, browsers and mobile phones!

Rust

139

289 commits

updated Oct 16, 2026

See the code

See what people are saying

SourceMessageScoreDate

Sly, a new and modern multi-system emulator, is now public! (r/rust)

**TLDR plz** Sly is my new multi-system emulator, releasing with support for Game Boy Advance and SNES with many, many more planned! It includes a 3D game library, a debugger, a simpler ("classic") desktop frontend and an iOS app, with Android being developed soon. The debugger also runs in your…

191

Oct 16, 2026

README

Sly

Sly is a cross-platform, multi-system emulator for players, homebrew developers and emulator developers alike. It combines a beautiful debugger with a unique take on the classic emulation experience!

Official website · Try the debugger in your browser

Sly Debugger Sly Launcher

Sly has three main desktop frontends, alongside its mobile apps:

  • Sly Launcher: A 3D game library built around box art and cartridges.
  • Sly Classic: A minimal Qt interface for browsing and playing games.
  • Sly Debugger: A beautiful debugger packed with features.

Supported platforms:

  • Windows, macOS and Linux
  • Web browsers via WebGPU (debugger only so far)
  • iOS, with Android planned

Download

Get the latest release:

  • Windows, macOS and Linux: each frontend comes as its own archive: sly-launcher, sly-classic and sly-debugger.
  • iOS: sly-ios-arm64-unsigned.ipa. It's unsigned, so you need to sideload it (for example with AltStore or SideStore).

For the newest changes, try the nightly build. It's rebuilt from the dev branch once a day and may be unstable.

Compatibility

Color means playable or work-in-progress. Click on a logo to see the respective compatibility database.

Super NintendoGame Boy AdvanceGame Boy and Game Boy ColorGame Gear
Master SystemPlayStationGameCubeWii
Sega GenesisDreamcastNintendo DSNintendo 3DS

Features

Sly Launcher

  • 3D boxes and cartridges
  • Row, column and ribbon shelf layouts
  • Flippable box art
  • Automatic artwork downloads
  • Regional packaging and models, with per-game release overrides
  • Per-game cartridge finishes
  • Gamepad navigation
  • Remappable controls
  • Save states
  • Quality presets, text size, reduced motion and integer scaling
  • Fullscreen

Sly Classic

  • Sortable game list with banners
  • Quick save slot plus ten save state slots
  • 1x to 4x scaling and fullscreen
  • Gamepad support
  • Automatic artwork downloads

Sly Debugger

  • Instruction and event stepping
  • Linear and graph disassembly
  • CPU registers and call stacks
  • CPU and memory breakpoints
  • Memory viewer
  • MMIO register inspection
  • DMA inspection
  • Tile, tilemap and background viewers
  • Sprite and palette viewers
  • Various coprocessor workspaces (for example SA-1 and Super FX)
  • Audio visualization
  • Built-in Lua editor and scripting
  • Save states
  • Cartridge info with cover art
  • Light and dark themes with various accent colors

Usage

SystemFile types
SNES.sfc, .smc
GBA.gba

How you load games depends on the frontend:

  • Sly Launcher: add your ROM folders in settings, or pass a folder on the command line.
  • Sly Classic: put your ROMs in roms/{system}/ in the working directory.
  • iOS: copy games into Sly's roms/{system}/ folders using the Files app.
  • Sly Debugger: pass the ROM path on the command line, or drag it into the window.

From the command line:

sly-launcher path/to/roms/
sly-debugger path/to/game.sfc

Artwork

Box art and covers come from art.layle.dev. This works without an account, but anonymous access has lower rate limits. For higher limits, log in at art.layle.dev/account, generate an API key and paste it into the settings of any frontend:

  • Sly Launcher: Settings -> Artwork key
  • Sly Classic: File -> Settings
  • Sly Debugger: the settings popover, under Artwork
  • iOS: Settings -> Artwork

The key is stored in settings.toml in Sly's data folder (for example %APPDATA%\sly on Windows), which all desktop frontends share.

Default Controls

These are Sly Launcher's defaults. All of them can be remapped in settings (gamepads are supported too).

Keys are matched by position, so the labels below are for a US QWERTY keyboard. On other layouts, press the key in the same place (for example, Z is Y on a German keyboard).

Library

ActionKey
BrowseArrow keys / WASD
PlayEnter / Space
Flip boxF
Change viewTab
Search/
Previous / next letterQ / E
Console listC
Previous / next consolePage Up / Down
SettingsF2
FullscreenF11

In game

ControlKey
D-padArrow keys
B / AZ / X
Y / X (SNES)A / S
L / RQ / W
Start / SelectEnter / Backspace
Save / load stateF5 / F8
PauseP
Back to libraryEsc
FullscreenF11

Development

Building

See the build workflow for platform dependencies, including Linux audio and windowing libraries. Run everything from the repository root.

Sly Launcher and Sly Debugger

git submodule update --init --recursive
cargo run --locked -p modern-launcher -- roms/
cargo run --locked -p debugger -- path/to/game.sfc

This should work for most of the Rust crates.

Sly Classic also needs:

  • Qt 6 (CI uses 6.11.1), including Multimedia, ShaderTools and private GUI headers
  • CMake 4.3 or newer
  • Ninja
  • A C++23 compiler
  • naga-cli 29.0.4 (cargo install naga-cli --version 29.0.4 --locked)
  • SDL3 3.2 or newer for gamepads (or configure with -DSLY_ENABLE_GAMEPAD=OFF)
qt-cmake -S frontends/desktop-qt -B build/desktop-qt -G Ninja \
  -DCMAKE_BUILD_TYPE=Release -DSLY_CARGO_PROFILE=release
cmake --build build/desktop-qt

iOS needs a Mac with Xcode 26. Open frontends/ios/Sly.xcodeproj, choose your signing team and run the Sly scheme.

Project layout

Emulated hardware lives in crates/cores/, the shared interfaces in crates/models/ and the frontends in frontends/. If you want to add a system, the GBA core is the easiest one to read. The SNES core is a good example of multiple CPUs and cartridge coprocessors.

The crates you'll touch most:

  • core-model: the Core trait every system implements for playback (frames, audio, input, save states).
  • debugger-model: DebugCore, which adds registers, disassembly, stepping, breakpoints and memory access on top of Core.
  • workspace-model: describes the debugger's workspaces and panels.
  • core-loader: detects ROMs and creates the right core. New systems get hooked up here.
  • cirsium: the debugger's UI components.

Adding a core

  1. Create a crate in crates/cores/<system>/ and add it to the workspace. Copy the setup from the GBA Cargo.toml if you want debugger support behind a debug feature.
  2. Implement core_model::Core for your machine. Only reset, step and run_frame are required. Everything else has a default, so you can add video, audio, input and save states as you go.
  3. Add the system to core_model::System and to the save-state tags in state.rs. Don't change the existing tags.
  4. Hook it up in core-loader: identity, inspect, load, and load_debug once the debugger works.
  5. Check the frontends and bindings for anything system-specific, like controls or assets.

While you're working on a new core, the runner is handy. It's a tiny SDL app that just loads a ROM and plays it, so there's much less in the way than with the other frontends. It only needs cartridge_info and frame_interval on top of the basics.

cargo run -p runner -- path/to/game.gba

Adding debugger support

Wrap your machine in a debug type that implements both Core and DebugCore, like GbaDebug or SnesDebug. Start with CPUs, registers, disassembly, memory regions and stepping. Call stacks, event stepping and scripting can come later.

A few things to keep in mind:

  • Use the same IDs everywhere (for example gba.arm7tdmi and gba.bus). Breakpoints and views refer to them.
  • peek_memory must not change the machine's state. read_bus / write_bus go through the bus with all side effects and patch_memory edits memory directly.
  • The default manifest gives you the standard panels. Override it to add your own workspaces, like the SNES core does for its coprocessors and call ComponentManifest::validate() to check it.

Testing

cargo fmt --all --check
cargo clippy -p gba -p snes --features gba/debug,snes/debug
cargo test -p gba -p snes --features gba/debug,snes/debug

CPU tests run against the SSTs in submodules/:

cargo run --release -p testrunner -- snes
cargo run --release -p testrunner -- gba
cargo run --release -p testrunner -- spc700 --opcodes 00 --limit 100

New CPUs can be registered in testrunner.

Contributing

Contributions are welcome, whether it's a game compatibility fix, a new debugger feature or a whole new core. For bigger changes, open an issue first so we can talk about it before you sink time into it.

Sly also needs more than code! If you have design experience, help with app icons, UI and UX, box art and cartridge models or other visual assets would be very welcome. Open an issue to share your ideas or work.

For pull requests:

  • Branch off dev and open your PR against it.
  • Run cargo fmt --all and make sure the checks under Testing pass.
  • Keep hardware changes in their core and match the style of the surrounding code.
  • Explain what changed and how you tested it. If you ran the CPU tests or checked specific games, mention them.
  • Add screenshots for anything visual.
  • Don't commit ROMs, BIOS files or build output.

LLM usage

You may use LLMs to help write your code, but I strongly recommend against it. Either way, you're expected to understand every change you submit and be able to explain it yourself. Don't act as a proxy for an LLM. Issues, PR descriptions and discussions must be written by you. LLM usage must be disclosed.

License

GPL-3.0 · Third-party notices

Sly is not affiliated with Nintendo or other console manufacturers. Game titles, artwork and trademarks belong to their respective owners.

debugger
emulation
gba
snes

Significant stargazers

LLeny

14 followers · starred Oct 2026