Starting a Decompilation Project from Zero: Claude Code and 51% of a 2001 GBA Game
SubscribeSign in
Starting a Decompilation Project from Zero: Claude Code and 51% of a 2001 GBA Game<br>From Klonoa's raw ROM to byte-matched C (and an easter egg nobody had found in 25 years)
Macabeus<br>Aug 17, 2026
Share
In the previous chapter, we got the data: an LLM-powered pipeline matched 74% of the benchmark functions. Now it’s time to see how it performs on a whole game.<br>After one year of studying and building tooling for matching decompilation with AI, I finally stopped postponing and started to decompile “Klonoa: Empire of Dreams” (KEoD)! It's a Game Boy Advance game that I really love and, as we’ll see, a challenging one: its functions are unusually big.<br>⚙️ What is Matching Decompilation?<br>Matching decompilation is the art of converting assembly back into C source code that, when compiled, produces byte-for-byte identical machine code. It’s popular in the retro gaming community for recreating the source code of classic games. For example, Super Mario 64 and The Legend of Zelda: Ocarina of Time have been fully match-decompiled.
At the time I’m writing this chapter, 51% of the game’s code bytes are decompiled. Many thanks to Felipe Sanches and testyourmine for helping to reach this milestone!<br>Spoiler: We’ll see how Claude Code autonomously found an easter egg that had been hidden for 25 years!<br>Setting up the project
The first step is, of course, scaffolding the project. There is no single standard for how a decomp project should be structured, although there are some tacit structures that the community usually follows. In the case of GBA, one of the most popular is the one used by pret.<br>My initial idea was to follow the same code organization as Sonic Advance 3, since I was more familiar with it, but I quickly diverged because I had set the following goals:<br>It should have no assets or assembly code from the ROM. That's the case with Snowboard Kids 2 and Animal Forest, for instance.
I want to make the setup reproducible, as a paved path that other GBA games will follow, since I want to decompile the other Klonoa GBA games. Building a foundation to replicate later is important.
And more importantly, the project organization should make it easy for an AI agent to work with.
These goals have two important implications:<br>Setup based on a script: We need to have an automated script to, given a .gba ROM, produce the .s files from it, since they aren't versioned. This implies that any change to the .s files must be made in the script that generated them, not to the .s files directly.<br>For example, renaming functions or splitting them into modules should be done in the generator script. This diverges from how pret projects work, since the assembly is committed.
As little manual work as possible: Since this project should be AI-friendly, it should be possible to easily spawn a git worktree to enable parallel work, and it should be easy to add a new matched function.
Disassembly
With those goals set, the first artifact is the assembly itself. For that, I used Luvdis. It’s a GBA disassembler designed for matching decompilation. It reads KEoD's ROM and outputs a single big .s file.<br>Since I don’t want to have any assembly source code from the original game in Git, I included Luvdis as a git submodule and a shell script to call it, ./setup.sh. Besides calling Luvdis, this script will grow to do all the transformations we’ll discuss next: compiling the compiler, refining the disassembled code, moving the .s files, etc.<br>Finding the compiler
We need to find the compiler the developers used. Since many GBA games used agbcc (a fork of GCC 2.95), that's likely the case for KEoD too.<br>It’s worth mentioning that KEoD was released just 4 months after the GBA itself, in July 2001. It ranks as the oldest GBA game that is actively being decompiled! 1<br>With this release date in mind, we can rule out two popular compilers used for GBA game development: ADS 1.2, which was released in November 2001, and Metrowerks’ CodeWarrior, which was released in April 2002.<br>Of course, the developers could have been unconventional and used a different compiler, such as ADS 1.1. In any case, I started with agbcc, and since it enabled the match for simple functions with clean C code, I stuck with it. It was a no-brainer.2<br>To compile these first simple functions, we needed to have a Makefile and a linker script working. They were written by Claude Code using a few other decomp projects as inspiration.<br>Refining the assembly code
Although Luvdis is great to start with, we still need to make many improvements to make the disassembled code ready to be decompiled. Let's talk about them.<br>Function splitting
Luvdis automatically detected 93 functions, but the game surely has way more than that. So, I used Ghidra to enrich the function list, which found ~300 new functions. After using Claude Code to find even more functions, merging the results, and cleaning up the...