Byte-accurate decompilation of the League of Legends v4.17 macOS client.
  • C 44%
  • C++ 36.7%
  • Ruby 9.6%
  • Objective-C 5.1%
  • SWIG 1.6%
  • Other 2.9%
Find a file
2026-07-06 04:16:53 +00:00
.claude
.codex/skills
.git-hooks-config
.githooks
build Implement DrawMinimapIconFast 2026-07-06 04:13:45 +00:00
docs Update progress page 2026-07-06 04:16:53 +00:00
notes Implement DrawMinimapIconFast 2026-07-06 04:13:45 +00:00
orig
src Implement DrawMinimapIconFast 2026-07-06 04:13:45 +00:00
tools Match basic attack lookup 2026-07-05 09:03:56 +00:00
.gitattributes
.gitignore
.next-config.example.json
AGENTS.md
CLAUDE.md
configure.py
Dockerfile
Makefile
README.md
requirements.txt

League of Legends Mac Client Decompilation

A byte-matching decompilation of the League of Legends Mac game client (Patch 4.17, Season 4, ~2013).

View Progress

Project chat: Matrix room, or DM @riotzed:matrix.org.

What Is This

The goal is to reconstruct the first-party Riot game code from source so it recompiles to a byte-perfect match against the original Mach-O i386 binary. Every decompiled function is verified instruction-by-instruction against the original using objdiff.

The ~14 MB binary is roughly half Riot code and half statically-linked third-party middleware — Scaleform/GFx (~31%), CryptoPP (~6%), Wwise audio (~4%), plus FreeType, Lua, boost, and tinyxml. The project does not decompile that middleware: it reuses those functions unmodified from the original binary via the static-bake / hybrid-link path (see docs/hybrid-link.md). So the realistic from-source target is the Riot code plus the incidental STL the compiler emits from it — about 46% of the binary, not 100%.

What is decompiled from source:

  • Riot game code + incidental STL — ~46% of the binary, the part with repo sources under src/Game/ and src/UnityFiles/. This is the work.

What is reused unmodified (not decompiled):

  • Third-party middleware — ~44% of the binary, baked in from the original.
  • Compiler-generated glue and orig-internal helpers, likewise baked in.

The public progress headline is a percentage over a curated first-party subset, not over the whole binary. For exactly what each number measures — the whole- binary figure (~20%), the must_write figure (~20%), and the headline first-party figure (~39%) — and the full Riot-vs-third-party breakdown, see docs/metrics.md.

The binary ships with a full DWARF dSYM — function names, parameter types, struct layouts, source file paths, and line numbers. The project skeleton was generated directly from this debug info.

Game Version 4.17.0.244 (September 2014)
Compiler Clang 3.3 (i686-apple-darwin10)

Building

Prerequisites: Python 3, pip install -r requirements.txt

make                    # Compile all source files
make report             # Generate match report
make progress           # Report + update progress page
make doctor             # Diagnose a broken build environment

Or use the bundled Docker image (avoids host-toolchain setup; verified on Linux x86_64, expected to work on Intel macOS and WSL2, untested on Apple Silicon):

docker build -t lol-decomp .
docker run --rm --user "$(id -u):$(id -g)" \
    -v "$PWD:/workspace" -w /workspace lol-decomp make

The --user flag makes build outputs owned by your host user instead of root. On SELinux hosts (Fedora/RHEL), append :Z to the volume mount (-v "$PWD:/workspace:Z"). On Windows, run from WSL or Git Bash.

Contributing

Pick any unmatched function from the progress page and write C++ that compiles to a byte-perfect match. See docs/ for compiler flags, codegen tips, and tooling details.

You can contribute through the forge, or send a git format-patch over Matrix to @riotzed:matrix.org.

Acknowledgments

  • objdiff by encounter — instruction-level diff tool
  • decomp.dev — inspiration for the progress treemap