This guide will get you from zero to running your first SNES ROM in about 10 minutes.
| I want to make SNES games | I want to contribute to the SDK | |
|---|---|---|
| What | Download the pre-built SDK, write C code, build ROMs | Clone the repo, modify compiler/library/tools |
| Prerequisites | make, python3 + text editor | clang, cmake, git, python3 |
| Time to start | ~5 minutes | ~15 minutes |
| Go to | Path A: Game Developer | Path B: SDK Developer |
You want to write SNES games in C. The SDK is already compiled — you just need to download it, write code, and run make.
You need make (the build tool), python3 (the build's post-link checks — ROM size, bank budgets — are Python scripts) and an emulator. No compiler installation required — the SDK ships with its own cross-compiler.
macOS:
Linux (Ubuntu/Debian):
Linux (Fedora):
Windows:
luna is the SDK's emulator: it plays ROMs, runs the test harness and debugs (tutorials/debugging.md). scripts/install-luna.sh fetches the pinned release for Linux, macOS or Windows (MSYS2 / Git Bash) into testing/bin/: luna (headless: tests, state, debugging) and luna-gui (a window you play in). Any other SNES emulator works too, for a second opinion:
| Emulator | Best For | Download |
|---|---|---|
| Mesen | Debugging, accuracy | mesen.ca |
| bsnes | Cycle accuracy | GitHub releases |
| Snes9x | Performance | snes9x.com |
Download the latest release for your platform from the GitHub Releases page:
| Platform | File |
|---|---|
| Linux x86_64 | opensnes_<version>_linux_x86_64.zip |
| Linux aarch64 | opensnes_<version>_linux_arm64.zip |
| macOS arm64 | opensnes_<version>_darwin_arm64.zip |
| Windows x86_64 | opensnes_<version>_windows_x86_64.zip |
Extract the archive somewhere permanent (e.g., ~/opensnes or C:\opensnes). It holds what a project build needs: the toolchain and asset tools in bin/, the library, the build system, the starter project. The documentation you are reading is online at https://k0b3n4irb.github.io/opensnes/ and the examples come as a separate, platform-independent archive on the same releases page: opensnes-examples_<version>.zip (sources, assets, and every ROM already built under examples/bin/).
Extract the examples archive next to the SDK and pick a ROM:
Any other SNES emulator opens the .sfc as well (Mesen, bsnes, Snes9x — see the table above).
You should see "TEXT MODULE TEST" in white on a dark blue screen.
The SDK ships an opensnes CLI (in the extracted bin/ directory) that scaffolds, builds, and runs a project for you. Put it on your PATH once — from the extracted SDK directory:
Then create, build, and run your first project in three commands:
opensnes init gives you a project that builds and runs from the start. Pick a template:
Other commands (opensnes — the project tool): opensnes build, opensnes clean, and opensnes doctor (checks your toolchain, library, and emulator and tells you what is missing). Run opensnes --help for the full list.
Prefer to wire it by hand, or curious what init generates? Create a new directory anywhere on your machine:
Create two files:
Makefile:
main.c:
Build and run:
That's it — you're making SNES games.
Projects can declare automated tests that run in luna, the same cycle-accurate emulator the SDK's own test suite uses, with luna's own manifests: one test/<name>.toml per test, run by luna test. Opt-in is simply the presence of a test/*.toml (the game template ships two):
Workflow:
(Or opensnes test / opensnes test --update from the project directory.)
What a manifest can judge:
luna test --help lists everything a manifest can say. Commit test/ to your repo; rerun make test-update when you intentionally change what the game shows.
You want to modify the compiler, library, tools, or build system itself. This requires building the entire SDK from source.
You need a full C/C++ development environment.
macOS:
Linux (Ubuntu/Debian):
Linux (Fedora):
Windows:
The first build compiles the toolchain (cproc, QBE, WLA-DX) and takes a few minutes; later builds take seconds. It ends with:
See CLAUDE.md for architecture details and coding conventions.
You've built and run a ROM. Three complementary ways forward — pick by how you like to learn, or use all three:
Or explore the examples by complexity:
| Level | Examples | What You'll Learn |
|---|---|---|
| Beginner | text/print_string, text/scroll_message | Console output, text formatting |
| Intermediate | sprites/simple_sprite, input/two_players | Sprites, controller input |
| Advanced | mode7/rotate_scale, audio/snesmod_music | Mode 7, tracker music |
| Expert | games/breakout, games/likemario | Complete game structure |
| SA-1 Coprocessor | chips/sa1_hello, chips/sa1_starfield | 10.74 MHz second CPU (tutorial) |
| SuperFX (GSU) | chips/superfx_hello, chips/superfx_3d | RISC coprocessor, 3D rendering (tutorial) |
Browse all examples:
The full set of tutorials, always current, is on the docs home page — see the tutorial navigation in mainpage. The most common starting points:
| Topic | Guide |
|---|---|
| Graphics & Backgrounds | tutorials/graphics.md |
| Sprites & Animation | tutorials/sprites.md, tutorials/animation.md |
| Scrolling & Parallax | tutorials/scrolling.md |
| Collision Detection | tutorials/collision.md |
| Input Handling | tutorials/input.md |
| Audio & Music | tutorials/audio.md |
| Math & Fixed-Point | tutorials/math.md |
| DMA | tutorials/dma.md |
| HDMA Effects | tutorials/hdma.md |
| Color Math | tutorials/colormath.md |
| Hardware Windows | tutorials/window.md |
| Mosaic | tutorials/mosaic.md |
| Mode 7 | tutorials/mode7.md |
| Game States | tutorials/game_states.md |
| SRAM Saves | tutorials/sram.md |
| Far RAM (FAR objects) | tutorials/far_ram.md |
| SA-1 Coprocessor | tutorials/sa1.md |
| SuperFX (GSU) | tutorials/superfx.md |
| Debugging | tutorials/debugging.md |
Install build tools (see prerequisites for your path above).
You forgot --recursive when cloning. Fix it:
Run make from the SDK root first — the library must be compiled before examples:
Your ROM built but doesn't display anything. Common causes:
See TROUBLESHOOTING.md for more solutions.
The compiler stops, with the feature named, rather than generate wrong code for what it does not support: struct assignment, structs passed or returned by value, variadic functions and inline assembly. Pass a pointer, copy the fields, or move the code to a .asm file. 32-bit u32/s32 arithmetic is fully supported (it is slower than 16-bit, not wrong). See KNOWN_LIMITATIONS.md for the full list.
See API_INDEX.md — the SDK indexed by what you are trying to do, with the example that does it. Worth a scan before you write a helper: several already exist.