Skip to content

Repository files navigation

⛰️ Alchemy: the Golden Sun decompilation

In Golden Sun, lighting the four Elemental Lighthouses releases Alchemy upon the world. I’m doing the same thing to the games themselves. The Broken Seal ☀️ and The Lost Age ⚓️ are being rewritten, piece by piece, into a form people can read, change and build on.

Progress

☀️ 91.48% · ⚓️ 5.28%

The number measures executable code rebuilt from source across all six languages. It includes matching C and proven assembly; art, music, text and other data are separate. A piece only counts in a language whose verified build links that source and is identical to the original. Each language uses the English edition’s code sizes; make progress shows every language and part. Code found only in another language is outside this counter, and code absent from Japanese still leaves an English-sized obligation: both need resolving before an exact 100% claim.

FAKEMATCH marks C that needs a matching aid to reproduce the original compiler’s register choices or instruction order. Those bytes are already included in C, and the aids stay visible in the source. Removing them is the final step after both games reach 100%.

Why Alchemy?

When Camelot made Golden Sun, they wrote it as instructions a person can read and then turned those into the unreadable code that sits on the cartridge. The readable version was never released.

Alchemy works backwards. Piece by piece, it rewrites the game in readable form, and every piece is checked against the original until the two are identical. The result isn’t a guess at how Golden Sun works: it is Golden Sun, in a form people can finally read. I also try to make it look the way Camelot’s own work might have looked in 2001, down to names taken from the Japanese release: Sukureta for Kraden, Gerald for Garet.

I do this with AI, and a lot of it. The AI does the heavy lifting, and the original game is the judge.

Once a game can be read, it can be changed. That opens the door to things fans have wanted for years: Golden Sun running natively on PC, phones and modern consoles, widescreen and smoother frame rates, quality-of-life fixes, new translations, and new storylines, quests and Djinn. Alchemy doesn’t do these things itself. It lays the foundation, and then all of us get to build on it.

Alchemy is not a remake, a mod, an emulator or a download of the games. It doesn’t include the games themselves; you’ll need your own copies. For now, the best way to help is to share the project and cheer it on. It will open to outside contributions once both games are complete, and developers can find the technical details in AGENTS.md.

Build one edition

The supported build host is currently Apple Silicon macOS. Install Xcode's command-line tools (Git, Make, Clang and the macOS SDK), Rust with Cargo, and Bun for repository checks and worktrees. Setup uses the system curl and tar and needs internet access to fetch locked Rust dependencies and pinned compiler sources. Later builds run offline.

The checks below were run on macOS 27.0.1 with Xcode 27.0 and Rust 1.98.1.

git clone --recurse-submodules https://github.com/PascalPixel/alchemy.git
cd alchemy
make bootstrap
mkdir -p roms

Fresh source setup currently stops at an agbcc/old_agbcc unapproved-digest error: the host linker embeds build paths and object timestamps in both stock library compilers. Reproducible setup still needs a fix; the approval check stays in place. If you already have an approved local compiler bundle, import it with make bootstrap BUNDLE=/absolute/path/to/compilers before continuing. This path also builds the required binutils and compiler runtime.

Place your own English copy of The Broken Seal at roms/tbs-en.gba, then run:

make compare-tbs-en

This builds out/tbs-en/tbs-en.gba and checks that it is byte-identical to the supported original. A single-edition build needs only that edition's ROM; private inputs and built ROMs are ignored by Git. Use tbs or tla with ja, en, de, es, fr or it for another edition, changing both the ROM filename and the comparison target. Each input is checked before use.

After editing source, use make build-rom TARGET=tbs-en to build your changes; the comparison command is expected to fail when you intentionally change the game. make compare-editions checks all twelve editions and requires all twelve original ROMs.

Find your way around

Start in games/THE BROKEN SEAL or games/THE LOST AGE. Both use the same layout, and code they share lives in games/COMMON.

Place What you’ll find
SRC Game code grouped by system, such as battles, field scenes and menus. Editable graphics and tables live beside the code that uses them.
INCLUDE Named structures, fields and interfaces used by those systems.
TEXT One .PO file per language, with messages and their in-game control codes.
SOUND Music and sample sources, including MIDI and WAV files.
recon/tbs and recon/tla Unfinished work: disassembly, C drafts and the scaffolding that still supplies original bytes.
tools Alchemy builds and checks the games, ags encodes assets, and Psynergy reads and analyses them.
out/<edition> Generated build output, including that edition’s .gba, linker map and debugging symbols.

Japanese is the source edition. The code records real differences between languages, so check the edition branches around a change. Editing a C draft under recon does not by itself change the built game. Keep changes in the maintained source or editable asset that the build uses.

Follow the party’s coins

One small way into the source is to follow a value from game logic to the screen and save data:

  1. GAME_STATE.H names the party’s balance as gGameState.coins.
  2. Party_ApplyStatePreset in PARTY2.C updates the party and adds 300 coins. This is an addition to the existing balance, not a replacement for it.
  3. Shop_DrawMoney in DRAW_MONEY.C reads that same field and draws it in the shop’s “Your Coins” window. The Japanese branch places the number and label differently.
  4. SaveState_BuildSummaryHeader in SAVE2.C copies the balance into the save summary.

That gives a change a clear path to follow: the function that changes the value, the shared field, and the places that read it. If you change the grant, the game must run that function again; loading a save made after it ran won’t apply the new grant. A playable editing example is still being verified.

Share an edit with another ROM owner

For edits to existing tracked files under games, save a source patch before committing. The first command prints the starting commit; keep it with the patch so someone else can start from the same source:

git rev-parse HEAD
git diff --binary HEAD -- games/ > my-change.patch

Another person can set up that commit with their own ROM, copy in the patch, and run:

git apply --check my-change.patch
git apply my-change.patch
make build-rom TARGET=tbs-en

The check catches a patch that doesn’t fit their source before applying it. The patch carries your source and asset edits; their own build produces the modified game. Share the patch and starting commit, keeping ROMs and private inputs on each person’s machine. New files need to be staged before they can appear in this patch. This applies the edit; its in-game behavior still needs testing, especially if it moves or grows data.

Acknowledgements

Golden Sun, its characters, music, art and original code were created by Camelot Software Planning and published by Nintendo. Alchemy is an unofficial fan project and is not affiliated with or endorsed by either company.

Thank you to:

  • The r/GoldenSun community, for sharing Alchemy, cheering it on, and keeping the love for these games alive.
  • Tarpman and Karathan, for identifying the compiler and flags Camelot used.
  • Coaltergeist, for camelot-gcc, the compiler Alchemy first built with.
  • pret, whose decompilations set the standard Alchemy measures itself against, and whose agbcc Alchemy builds the games’ library code with.

About

The decompilation of both Golden Sun games, preserving the GBA classics as readable code and assets.

Resources

Stars

136 stars

Watchers

3 watching

Forks

Releases

Packages

Contributors

Languages