Age of Empires III: The Asian Dynasties, decompiled back to C++ that compiles to the original game's exact machine code, and ported to native macOS from that same source.


Captured from the game running on macOS through the static recomp, using the owner's own copy. The images are hosted here only; the repository contains no game files, assets or screenshots.













Every number below is counted from the repository's main branch. A function only counts as matched when recompiling its source reproduces the original bytes, and review checks that again before it merges.
Counted 2026-10-26 at commit main.
The game shipped as a compiled Windows program, age3y.exe. We write C++ by hand, function by
function, and compile it with the same compiler the game was built with: Microsoft Visual C++ .NET 2003 (7.1,
cl 13.10.3077), run natively on macOS. A function is matched when the compiler turns our
source into exactly the instructions in the original executable.
Analysis tools recover each function's machine code, the classes it uses and the source file it came from.
An agent writes plain C++03 that this 2003-era compiler accepts, using real names from the game's own debug strings where they exist.
A custom comparer checks the compiled result against the original, instruction for instruction.
Review recompiles every function and plants a deliberate one-token bug, which has to break the match. Only then does it merge.
The matched source is the ground truth, and the port never changes it. It works the way an emulator layer does, by replacing what the game calls instead of the game itself. The game asks for Direct3D 9, Win32 windows, DirectSound and so on; on a Mac, those calls are answered by new code that speaks Metal, SDL3 and Core Text. The same source still compiles to the original bytes for Windows.
| Layer | What it replaces | Status |
|---|---|---|
| Direct3D 9 on Metal | The game's renderer device, its resources and render states, plus shader translation for every shader model the game uses (vs/ps 1.1 to 3.0) | on main |
| Win32 on SDL3 | Windows, the message pump, input, timers, files, the registry, threads and synchronisation | on main |
| GDI text on Core Text | Fonts, glyph rasterisation, text drawing and bitmap blits for the game's UI text | on main |
| DirectSound on miniaudio | Sound buffers, 3D positional audio and the game's EQ filter | on main |
| Memory allocator | The game's Rockall heap | on main |
| 64-bit builds of game code | Layout checks that assume 32-bit pointers, so the game's own files can compile for arm64 | next |
| Bink video on FFmpeg | The ten functions the game imports from binkw32.dll, with a decoder and a blit layer behind them | on main |
| D3DX9 shader compilers | The assembler, disassembler, HLSL compiler and effect compiler the game calls through D3DX9, written in-house | in review |
| Voice streaming, network | DirectShow and sockets | planned |
Every layer has its own tests: pixel-exact rendering checks, sample-exact audio mixes and thread stress tests under sanitizers. Each also has planted-bug checks that the tests must catch.
The decompile is not finished, so the port cannot yet be built from matched source alone. The bridge fills the gap. A translator reads the x86 code of your own copy of the game on your own machine, writes it out as C, and compiles that for Apple Silicon. The result runs on the Mac platform layers above, so the original game's code is already executing on macOS while the matched source grows underneath it.
The translated C comes from your game files and stays in your build folder. It is never committed to the repository or distributed.
Each translated function is replaced by matched source as the decompile reaches it. When the decompile completes, the bridge goes away.
Metal, SDL3, Core Text and the audio layer carry over unchanged to the finished native build.
The bridge never feeds the matching build, never edits matched source, and nothing is patched or bypassed. The rules are in the design decision.
| Date | Milestone | Status | Links |
|---|---|---|---|
| 2026-10-26 | Feasibility shown: all 35,184 functions of the executable translate to C and link as one arm64 program, and nine real functions pass over 200,000 checks against a reference. | reached | #635, spike log |
| 2026-10-27 | 99.98% of functions translate (35,176 of 35,184), including SSE/SSE2 and exception-handling cleanup code. Instruction forms are tested against a hand-written reference and a CPU emulator. | reached | #659, #670, #743 |
| 2026-10-26 | Boots through the C runtime start-up: heap, locks, thread-local storage, command line, environment and locale. | reached | #688, boot 1 |
| 2026-10-26 | Runs every static initializer and enters WinMain. | reached | #710, boot 2 |
| 2026-10-26 | Opens the game's archives, parses its XML, then creates and shows the main window and paints the splash screen. | reached | #727, boot 3 |
| 2026-10-27 | Passes the game's own licence check. Its registration library runs unmodified, and Steam's own install step (the installscript.vdf that ships with a Steam copy) is applied to the port's own registry, so the game finds its registration exactly as it does on Windows. Nothing is bypassed or patched. | reached | #734, #742, #746, install log |
| 2026-10-27 | The game's licence-agreement dialog appears as a native macOS dialog with a scrolling text box. Accepting is the player's choice; no automated run accepts it. | reached | #744, #751, #750 |
| 2026-10-27 | Hardware detection: the game's own detection library runs as translated code and reads a model of the system's display and sound devices, with the display identity coming from the Metal layer. | reached | #750, detection log |
A full map of the start-up path, step by step, is in the start-up note (#766). Boot time on the bridge fell from 1.65 s to 0.50 s of CPU after a dispatch cache (#762).
| Piece | State | Links |
|---|---|---|
| Direct3D 9 on Metal | The renderer, the shader-model 1 to 3 translator and the guest-facing COM proxies are on main and linked into the bridge's build. The game has not created its device yet, so no frame is drawn through Metal. | #288, #355, #698 |
| In-house HLSL compiler | The D3DX9 shader assembler, disassembler, HLSL compiler and effect compiler are written and in review. | #765 |
| Sound and input | DirectSound 8 and DirectInput 8 proxies for the translated code are on main, tested with scripted sequences. They are not wired into the boot yet. | #760, #757 |
| Bink video | The ten binkw32.dll functions run on FFmpeg's Bink decoder with a blit layer, on main. They are not bound into the boot yet, so intro videos are still skipped. | #759 |
Bind the game's Bink imports to the video layer so the intro movies play.
Create the Direct3D device on Metal, wire in sound and input, and load the first models and menu.
A prototype that adds a Mods button to the menu through recompilation hooks, as part of a separate modded build. The authentic build never loads it. Designed in task-mods-design.
Everything here is counted from merged pull requests and the project's research logs. Items marked in review are not on main yet.
Enough matched code to link a Windows build of the game from source.
Replay recorded games and check the rebuilt game behaves exactly like the original.
The game's real data drawn on a Mac through the port layers.
A native Apple Silicon build you can play a skirmish in. A Windows x64 / Direct3D 12 build follows.
Once the game runs natively, the plan is to build on top of it without touching the faithful version. The byte-identical rebuild stays exactly as it is, and a separate modded build adds three things:
A documented, versioned modding interface that is as extensive as possible: units, civilisations, techs, UI, maps, AI, camera and scripting. Its scope is set by reference mods modelled on the kinds of mods people love for the other Age of Empires games.
Browse, install and update mods from many authors without leaving the game, signed in with an AoE3 decomp account.
The game's original online service is long gone. Our own service, running on Cloudflare Workers, will speak the game's original online protocol, which the decompile itself is recovering, so the multiplayer screens work again.
Recorded in the project's design decision on mods and online play. This comes after a playable macOS build.
Mods button prototype planned via recomp hooks.
Most of the work is done by AI agents in two teams, each sponsored by a person: briannastatic and Mylogo. They coordinate only through the git repository. An agent claims a piece of work as a git ref, so two agents can never take the same piece. It hands off with a written note of what it did and learned, and every change goes through the same automatic review. Lessons learned while matching (compiler quirks, source shapes that reproduce a tricky instruction sequence) are written down and shared, so each new agent starts where the last one left off.
Anyone can contribute. The rules are in AGENTS.md and CONTRIBUTING.md.