Introduction

Gopher

GoSprite64 is your portal to building retro-fueled 2D games for the Nintendo 64, using the modern power of Go. With clean APIs, minimal setup (Linux, Mac, Windows are all supported), and a rebellious retro soul, it lets you bring your pixel dreams to life—on real N64 hardware.

The information here is targeted at homebrew development. This project just got born, expect heavy changes along the way...

What's GoSprite64?

GoSprite64 is a Go library for making 2D games that run natively on the Nintendo 64. It wraps low-level N64 quirks in a modern API inspired by modern game engines, so you can focus on your game logic -- not the hardware headaches.

Designed for developers who love Go and grew up on cartridges, GoSprite64 makes retro dev surprisingly fun and productive.

you can:

  • 🚀 A friendly API built on top of clktmr/n64 and embedded-go
  • 💾 Builds real N64 ROMs you can flash and play (yes, on real hardware!)

Why Go?

Go is a clean, fast, pragmatic and efficient language. By using Go for Nintendo 64 development, GoSprite64 opens the door for cloud developers to create retro-style games with confidence and speed.
The library bridges modern programming concepts with the raw power of a classic console.

What’s in this book?

This book introduces you to GoSprite64, guiding you through everything from setup to building full 2D games.

You'll learn how to:

  • Build and flash N64 ROMs
  • Draw and move sprites
  • Design and scroll tilemaps
  • Handle input
  • and more ...

Whether you're nostalgic for the era or just curious about console programming, this book aims to get you productive with GoSprite64 as fast as possible.

Who is this book for?

This book is for:

  • Developers interested in retro console programming
  • Go programmers curious about low-level game development
  • Hobbyists or indie devs looking to make something fun for the Nintendo 64

Some experience with Go is recommended. If you're brand new to game development or Go, consider starting with a simpler platform or tutorial first.

This book also includes step-by-step guides and real-world examples to help you build your own Nintendo 64 games using Go.

Environment setup

Typically, homebrew retro-gamedev development with C/C++ is a bit messy to setup and build. Even though Go has very easy way of handling things, we're still building actual Nintendo 64 games here. But don’t worry — we’ve automated everything. There are no Makefiles, no cmake and no crying. Also, whether you're on Windows, macOS, or Linux, the setup is exactly the same.

All you need is actually to install some modern version of Go and Mage, and you'll be ready to build games that run on real N64 hardware.


🧰 What you'll need

Before you dive in, you’ll only need two things installed:

  1. Go (any modern version will do) — Install Go

  2. Mage – a task runner we use for setup automation:

    go install github.com/magefile/mage@latest
    

🧙‍♂️ One command to rule them all

Once you have Go and Mage installed, run this magic spell:

git clone https://github.com/drpaneas/gosprite64
cd gosprite64
mage Setup

Sit back. Grab a coffee. Our Mage is taking over. ☕

He’ll:

  • 🛠 Fetch a custom version of Go built for MIPS (what the N64 uses)
  • 🔧 Build it locally
  • 📦 Install emgo, the embedded Go tool
  • 📁 Set up a clean environment in ~/toolchains/nintendo64 for Mac/Linux or %USERPROFILE%\toolchains\nintendo64 on Windows.
  • ⚙ Configure direnv to manage your previously built Go environment automatically

No clutter in .bashrc, .zshrc, or .profile. It just works.

📁 Where things live

After setup, your new Go environment will be isolated in:

  • GOROOT~/toolchains/nintendo64/go
  • GOPATH~/toolchains/nintendo64/gopath

From now on, all your N64 projects should live inside ~/toolchains/nintendo64 (or open a shell inside it). Thanks to direnv, your terminal will automatically switch to the embedded Go version whenever you cd into this folder. Leave the folder? You're back to your normal Go setup. No switching. No weird aliases. No surprises.

🧭 Platform-specific guidance

If you really want to peek behind the curtain or you're running into edge cases, we have detailed setup pages for:

But honestly? Just run mage Setup. It works.

🐧 Linux Setup

If you're here, you're probably running something like Ubuntu, Arch, Fedora, or maybe even Gentoo on a thinkpad with stickers. Either way: respects.

You’re in a great spot to build games for the Nintendo 64 using GoSprite64.

Most of the setup is automated via mage Setup, but if you want to understand or troubleshoot the magic, read on.


🧱 Prerequisites

You’ll need just a few things to get rolling:

✅ Install Go

Your distro probably has a package for it:

# Debian/Ubuntu
sudo apt install golang

# Fedora
sudo dnf install golang

# Arch
sudo pacman -S go

Or download and install it manually from go.dev.

Make sure you can use it by giving it as try, run: go version.

✅ Install Mage

go install github.com/magefile/mage@latest

Verify you can use it: which mage.

✅ Install direnv

This allows your terminal to automatically switch Go environments when entering ~/toolchains/nintendo64.

# Debian/Ubuntu
sudo apt install direnv

# Fedora
sudo dnf install direnv

# Arch
sudo pacman -S direnv

After that, hook direnv into your shell. Edit either ~/.zshrcor ~/.bashrc and add one of the following lines:

eval "$(direnv hook zsh)"   # for ZSH
eval "$(direnv hook bash)"  # for bash

Then run either source ~/.bashrc or source ~/.zshrc respectively. After this, direnv will automatically load the N64 environment when you're inside ~/toolchains/nintendo64.

🧙‍♂️ Run the Setup

Now clone the repo and run:

git clone https://github.com/drpaneas/gosprite64
cd gosprite64
mage Setup

What happens now:

  • 🧬 A custom Go toolchain for MIPS gets cloned and compiled
  • 🛠 A GOPATH and GOROOT get set up at ~/toolchains/nintendo64/gopath and ~/toolchains/nintendo64/go respectively.
  • 🧪 emgo tool gets installed
  • ⚙ An .envrc file is created at ~/toolchains/nintendo64 so that direnv can auto-activate your dev environment

You can verify all those by going to cd ~/toolchains/nintendo64/ and witness your Go env setup changing.

Outside of the toolchain's directory:

$ cd; go env GOROOT

# Output:
/opt/homebrew/Cellar/go/1.23.3/libexec # my system uses Go 1.23
$ cd; emgo

# Output:
zsh: command not found: emgo # expected, not from my std GOBIN

Inside of the toolchain's directory:

cd ~/toolchains/nintendo64 
# Output:
direnv: loading ~/toolchains/nintendo64/.envrc
direnv: export +GOBIN +GOROOT ~GOPATH ~PATH 


go env GOROOT

# Output
/Users/pgeorgia/toolchains/nintendo64/go

emgo

# Output
Go is a tool for managing Go source code.

🪟 Windows Setup

Welcome, traveler of the Windows realms! 💻

Yes, it’s true. You can build real Nintendo 64 games using Go, and you can do it on Windows too.
Thanks to some automation magic, GoSprite64 makes this painless—even in a land of .exe, PATH, and PowerShell.

Most of the work is handled by mage Setup. But if you're curious (or things go weird), read on.


🧱 Prerequisites

Here’s what you’ll need:

✅ Install Go

Download and install the official MSI package from go.dev.

During install, make sure to check the box to add Go to your PATH.

To verify it's working:

go version

✅ Install Mage

In your terminal or PowerShell:

go install github.com/magefile/mage@latest

Make sure that Go's bin directory is in your PATH. Usually it’s at:

%USERPROFILE%\go\bin

You can add it permanently to your system environment variables or temporarily:

$env:Path += ";$env:USERPROFILE\go\bin"

✅ direnv (Yes, even on Windows!)

GoSprite64 uses direnv to manage the custom Go environment.

Go to the releases page, and download the latest direnv.windows-amd64.exe asset. Place it into C:\Users\YourName\toolchains\nintendo64.

🧙‍♂️ Run the Setup

Now clone the GoSprite64 repo and run:

git clone https://github.com/drpaneas/gosprite64
cd gosprite64
mage Setup

This will:

  • Clone and build a custom version of Go for MIPS
  • Install the emgo toolchain
  • Configure your system with a new Go environment at:
    • C:\Users\YourName\toolchains\nintendo64\go
    • C:\Users\YourName\toolchains\nintendo64\gopath
  • Download a Windows-compatible direnv.exe
  • Set up .envrc to manage everything

All without touching your default Go installation. ✨

📦 How to use it

To develop N64 games using GoSprite64, always open a terminal in:

cd %USERPROFILE%\toolchains\nintendo64

🍎 macOS Setup

If you’ve landed on this page, it means you’re using macOS 🖥️ to build legendary Nintendo 64 games with GoSprite64. Good news: macOS is great for this. Even better news? You probably don’t need to do much here.

👉 All of the setup is fully 100% automated via mage Setup. But if you want to know what's happening under the hood, read on.


🧱 Prerequisites

Here’s what you’ll need before you can start hacking around:

Brew

First, make sure you install Apple's developer resources, that is Xcode, including the Command Line tools.

xcode-select --install
xcode-select -p # to verify they are installed
/Library/Developer/CommandLineTools

You will also need to install several other packages for which we'll include instructions assuming you have installed the Homebrew package manager on your system:

First install the package manager, that is Homebrew:

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

Output:

/Library/Developer/CommandLineTools

✅ Install Go

If you don’t already have Go installed:

brew install go

Make sure you can use it by giving it as try, run: go version.

✅ Install Mage

go install github.com/magefile/mage@latest

Make sure you can use it which mage.

✅ Install direnv

brew install direnv

After that, hook direnv into your shell. Edit either ~/.zshrcor ~/.bashrc and add one of the following lines:

eval "$(direnv hook zsh)"   # for ZSH
eval "$(direnv hook bash)"  # for bash

Then run either source ~/.bashrc or source ~/.zshrc respectively.

🧙‍♂️ Run the Setup

Now clone the repo and run:

git clone https://github.com/drpaneas/gosprite64
cd gosprite64
mage Setup

What happens now:

  • 🧬 A custom Go toolchain for MIPS gets cloned and compiled
  • 🛠 A GOPATH and GOROOT get set up at ~/toolchains/nintendo64/gopath and ~/toolchains/nintendo64/go respectively.
  • 🧪 emgo tool gets installed
  • ⚙ An .envrc file is created at ~/toolchains/nintendo64 so that direnv can auto-activate your dev environment

You can verify all those by going to cd ~/toolchains/nintendo64/ and witness your Go env setup changing.

Outside of the toolchain's directory:

$ cd; go env GOROOT

# Output:
/opt/homebrew/Cellar/go/1.23.3/libexec # my system uses Go 1.23
$ cd; emgo

# Output:
zsh: command not found: emgo # expected, not from my std GOBIN

Inside of the toolchain's directory:

cd ~/toolchains/nintendo64 
# Output:
direnv: loading ~/toolchains/nintendo64/.envrc
direnv: export +GOBIN +GOROOT ~GOPATH ~PATH 


go env GOROOT

# Output
/Users/pgeorgia/toolchains/nintendo64/go

emgo

# Output
Go is a tool for managing Go source code.

🎮 Building Your First GoSprite64 Example

So you’ve set up your environment? Sweet.
Now it’s time to build your first actual Nintendo 64 ROM using GoSprite64 and watch Bitron come to life. ⚡

And yes; it’s as easy as running one command:

mage Test

🧙 What does mage Test do?

Here's what happens under the hood:

  1. Clones the GoSprite64 source repo (if it's not already cloned)
  2. Navigates to examples/clearscreen
  3. Initializes a Go module with emgo mod init
  4. Replaces the Go module import path with your local GoSprite64 path
  5. Runs emgo mod tidy to fetch dependencies
  6. Builds the example with emgo build
  7. Confirms a .z64 ROM file was created

If everything works, you’ll see something like:

Build succeeded! Generated .z64 file(s): [/Users/drpaneas/toolchains/nintendo64/gopath/src/gosprite64/examples/clearscreen/clearscreen.z64]

Please load the .z64 file into the Ares emulator.

Boom 💥! You've got yourself a playable N64 ROM!

So if you go to cd ~/toolchains/nintendo64/gopath/src/gosprite64 you will find our repo again, cloned over there. Actually we do not need the whole repo, just the examples folder would do, but this makes our life easier in case you want to contribute to the project later.

Why? Because every example is using a replace directory, where instead of using the GoSprite repo from GitHub, it uses the one locally at your toolchain. In other words, the example Clearscreen: ~/toolchains/nintendo64/gopath/src/gosprite64/examples/clearscreen uses ~/toolchains/nintendo64/gopath/src/gosprite64. That means you can easily make any changes to GoSprite64 and test them locally.

🛠 Want to tinker?

Crack open the main.go inside the example and start playing around:

cd ~/toolchains/nintendo64/gopath/src/gosprite64/examples/clearscreen
nvim main.go  # or your favorite editor
package main

import (
        "image/color"

        gospr64 "github.com/drpaneas/gosprite64"
)

var Azure = color.RGBA{0xf0, 0xff, 0xff, 0xff} // rgb(240, 255, 255)

type Game struct {
}

func (g *Game) Update() error {
        return nil
}

func (g *Game) Draw(screen *gospr64.Screen) {
        screen.Clear(Azure)
}

func main() {
        // Initialize the game
        game := &Game{}

        // Run the game
        if err := gospr64.Run(game); err != nil {
                panic(err)
        }

}

Then make sure you have a build.cfg file next to it:

⚙️ build.cfg — The Memory Blueprint

In every GoSprite64 project, you’ll need a file named build.cfg sitting next to your main.go.

Why? Because this file tells the toolchain how to lay out memory for your N64 ROM.
Think of it as the blueprint for where code and data live in the final game binary.

Without it, your build may fail—or worse, the ROM may not boot at all on real hardware.

🧠 What’s inside build.cfg?

Here’s an example:

GOTARGET = n64
GOMEM = 0x00000000:4M
GOTEXT = 0x00000400:4M
GOSTRIPFN = 0
GOOUT = z64

Note: Most emulators emulate the Expansion Pak by default, but real hardware will need the actual RAM module installed.

If you do have an Expansion Pak with your Nintendo64, you can make sure of aditional 8M memory, required for larger assets. To use 8MB:

GOMEM = 0x00000000:8M
GOTEXT = 0x00000400:8M

📁 Where does build.cfg go?

It must be in the same folder as your main.go and where you run emgo build.

your-project/
├── build.cfg
├── main.go
└── ...

Then rebuild:

emgo build

Your updated .z64 file will be ready for action in seconds.

🕹️ Running Your Game in an Emulator

Once you've built your .z64 file using GoSprite64, the next step is to run it!
If you don’t own a flashcart (yet), no worries—modern N64 emulators work great for testing.

This page walks you through:

  • Which emulator we recommend
  • How to set it up
  • How to load and run your ROM
  • Common issues and tips

Ares Emulator Screenshot

Ares is a modern, accurate, and actively maintained multi-system emulator that includes solid support for the Nintendo 64. It’s fast, cross-platform, and runs .z64 files generated by GoSprite64 with ease.

📦 Download Ares

Available for Windows, macOS, and Linux.

Once downloaded, unzip or install it like any other app.


🚀 Running Your ROM

After you’ve built a GoSprite64 ROM (e.g. clearscreen.z64), launch Ares and follow these steps:

  1. Open Ares
  2. Click System > Nintendo 64
  3. Click File > Load
  4. Browse to your .z64 file and select it

That’s it! The emulator will boot your game instantly.
If the screen stays black or glitches out, don’t panic — just check the Troubleshooting section below.


📁 Where is my .z64 file?

If you've run mage Test, the output file will be located inside:

~/toolchains/nintendo64/gopath/src/gosprite64/examples/clearscreen/

Or wherever your current GoSprite64 project lives.

You can move this file somewhere easier to access or keep a “ROMs” folder for testing different builds.

Expansion Pak simulation

In case you want to simulate a Nintendo64 without the additional 4M of memory, you can configure Ares to do so:

Ares Expansion Pak

Enabling it you will effectively use 8M of memory, meaning you would have to configure you build.cfg in your project accordingly:

GOTARGET = n64
GOMEM = 0x00000000:8M
GOTEXT = 0x00000400:8M
GOSTRIPFN = 0
GOOUT = z64

🔌 Loading Your Game on Real Hardware

You’ve built your .z64 file using GoSprite64. You’ve tested it in the emulator.
Now it’s time for the real deal—running your game on an actual Nintendo 64 using SummerCart64 (aka SC64).

Whether you’re writing directly to the SD card or using the official sc64deployer tool via USB, we’ve got you covered.


🗂 Option 1: Copy to SD Card

The simplest way to test your game is to copy the ROM directly to the SD card used by the SummerCart64.

📥 Steps

  1. Build your ROM:

    emgo build
    

    This will give you a .z64 file (e.g., clearscreen.z64).

  2. Insert the SD card into your computer.

  3. Copy the .z64 file onto it:

    cp clearscreen.z64 /Volumes/SC64/  # macOS
    cp clearscreen.z64 /run/media/yourname/SC64/  # Linux
    
  4. Safely eject the SD card and put it back into your SC64.

  5. Power on your N64. Your game should appear in the menu.

That’s it! You’re running Go code on a real N64.

🔌 Option 2: Upload via USB (sc64deployer)

If you’ve connected the SC64 via USB, you can upload ROMs directly using sc64deployer, the official SC64 control tool.

📦 Install sc64deployer

Clone the repo and build it:

./sc64deployer upload clearscreen.z64

Example output:

Uploading ROM [clearscreen.z64]... done
Save type set to [None]
Boot mode set to [Bootloader -> ROM]

⚠ Important: Power Cycle, Don’t Reset

After uploading:

DO NOT press reset on your N64.

Instead: Power OFF the N64. Wait a moment. Power it back ON.

This ensures the ROM is correctly loaded and avoids leaving the SC64 in a weird state. Using the reset button can cause crashes or corrupted memory states.

Debugging

🧪 Need to Debug or Inspect?

sc64deployer can do more than just uploads. Run --help for advanced features:

./sc64deployer --help

For example:

  • List connected devices:
./sc64deployer list
  • Check SC64 firmware version:
./sc64deployer firmware
  • Reset state (when needed, not for launching a game):
./sc64deployer reset
  • See print statements to your terminal (you have to start Ares from command-line)
./sc64deployer debug
[Debug]: Started

No matter which method you use, make sure to power cycle, not reset, after loading a ROM.

There’s nothing like seeing your code run on real hardware, on a real CRT, on a real N64. Built with Go.