SC: FA (Moho) engine sources
-
Hi everyone,
For the past 13 months I've been rebuilding the source code of the Forged Alliance engine, the retail binary
ForgedAlliance.exe. That part of the work is now finished. Every engine function the game uses exists again as readable C++20, and that code builds into a game that plays exactly like retail.- Repository: https://github.com/Draiget/faf-re
- Releases: https://github.com/Draiget/faf-re/releases
Why this matters for FAF
Until now, the only way to fix or extend the engine was the way the FA-Binary-Patches team has worked for years: patching an executable that nobody had source for. The patcher adds a new section to
ForgedAlliance.exeand compiles the patch code into it, in C++ and assembly. Small assembly hooks then overwrite instructions at fixed addresses in the original code and jump into that new code. Each hook has to fit in place of the instructions it replaces and keep the registers and calling conventions the 2007 compiler used. Game functions are called by raw address. Before any of that, the code around the patch point has to be worked out from disassembly. The patches that exist today took a great deal of skill and patience.With the source recovered, that changes:
- All engine logic is visible. You read the function instead of its disassembly: sim, AI, pathfinding, networking, rendering, UI, Lua bindings.
- A patch is a normal code change. Edit C++, rebuild, and you get a reviewable diff on GitHub, one commit per change.
- Real debugging. You get symbols (
.pdb), breakpoints, and you can step through sim code. - No more hook constraints. There are no hooks to fit in place of existing instructions, no registers to match by hand, and no raw addresses. You can change a function's body, its signature or a class layout directly, and add new classes, containers, Lua functions and even whole renderers.
- One codebase, two targets. The same source builds for x86 and x64.
To show this works, the FA-Binary-Patches sim and UI fixes up to FAF 3840 have already been ported as plain C++. Examples: aim lead (#143), target point at the collision centre (#145/#157), projectile impact below height 0 (#154), refuel undocking (#169), shield repair efficiency (#175), icon scales (#147), minimap range rings (#158), particle pools (#165), free camera focus (#170), and the UI draw functions,
CopyToClipboardandGetHighlightCommand. Sim changes are gated on the game version, so older replays still play back correctly.What it took
- About 13 months, from the first commit in September 2025 to today, and 3,800+ commits. It took a lot of time and paid AI compute.
- 40,617 engine functions recovered from the binary. Many more symbols in the exe were never hand-written: they are template instances and glue that the 2007 compiler generated. Those are rebuilt as the single source line that produced them, so the function count understates how much is covered.
- Every step was checked against retail: replays from the FAF vault must match every checksum the players recorded.
- The libraries are built from source at the exact versions the game used: Wild Magic 3.8, wxWidgets 2.4.2, Boost 1.34.1, zlib 1.2.3. Movies (
.sfd) are played through FFmpeg instead of the proprietary CRI runtime.
What works today
- The full game: main menu, cinematics, skirmish, save/load, replays.
- Multiplayer with retail: retail, our x86 build and our x64 build played one game together for 21 minutes of heavy AI fighting without a desync. Retail and our x64 played 30 minutes without a desync, both with and without sim worker threads.
- Replay parity: 75 vault replays (1โ12 players, stock and community maps, games against the built-in AI and M28AI) are checksum-identical to retail so far, with more to come for verification.
- x64 build: the 32-bit address space limit is gone - x86 runs out of memory at about 60,000 units, while x64 was still running at 90,000.
- Renderers: Direct3D 9 and 10 as shipped, plus new Direct3D 11, Direct3D 12 and Vulkan backends.
- Fixed along the way: sound breaking after 24.8 days of Windows uptime.
- Clean build: CMake with clang-cl and a static runtime, so no Visual C++ runtime DLLs are needed.
Performance
These are five FAF vault replays, played one at a time. Retail ran on D3D9; ours ran x64 with default settings, 8 sim workers and D3D12. Every run matched every checksum.
Replay Players Game length Retail x64 Faster by 26919967 12 46 min 1675 s 1125 s 33 % 26928802 8 39 min 1123 s 855 s 24 % 26935800 12 41 min 1244 s 1032 s 17 % 26997072 10 23 min 180 s 151 s 16 % 26923388 2 45 min 189 s 181 s 4 % The bigger the battle, the bigger the gain. In the heaviest stretches of the large games we are 23โ38 % faster. The speed comes from:
- moving sim work onto worker threads (recon blips, coordinate updates, sync packets, the Lua garbage collector, which went from 35.9 s to 9.3 s per game);
- not redoing work whose result is already known;
- moving strategic icons, culling and fog of war off the main thread.
All of this is exact. A step only runs in parallel when the result is provably the same as running it serially, and every speed-up has a switch that brings back the original code.
Hardening: one player can no longer break the game for everyone
The network-facing code has been hardened against corrupt and hostile data. One player sending malformed data can no longer:
- crash the lobby, stall it, or split its state between players;
- end a running game for everyone else.
The network transport survives garbage traffic, Lua data sent between players is checked before use, and damaged replays and saved games are refused with a reason instead of crashing. Automated tests cover these cases.
Note: this hardening landed in
masterafter the latest release. It will be in the next one.Work in progress: pick a release, or build and test
The engine restoration is done, but development continues on
master: performance, renderers, more FAF patches. Changes onmasterare not always fully tested. You have two options:- Use a release from https://github.com/Draiget/faf-re/releases. These are the tested builds.
- Build
masteryourself and test it before you rely on it.
Building needs clang, LLVM and Git:
git clone --recursive https://github.com/Draiget/faf-re.git cd faf-re .\build.ps1 -Arch bothBug reports, replays that desync, and pull requests are all welcome on GitHub. The PR template includes a replay check, so sim changes are verified against retail before they are merged.
Roadmap
All items in progress, ideas or fixes could be tracked on my dev blog page - https://draiget.dev/projects/faf-re/, scroll to roadmap section at the bottom.
Thanks
This would not exist without years of engine study by the FAF community.
Thanks to the FA-Binary-Patches contributors, whose patches kept the engine alive for years and showed what it needed: 4z0t, Garanas, Hdt80bro, KionX, Sheikah45, RutreD, Strogoo, lL1l1, K-ETFreeman, Mozd-122 and zhanghm18GIT. Thanks also to KionX and 4z0t for the patchers that made binary patching possible at all. The ported fixes in this rebuild are their work, now written as plain C++.
Special thanks to 4z0t and lL1l1, who have already contributed directly to this repository, and to Hdt80bro for a great deal of engine research.
Support
This rebuild took a lot of time and paid AI compute. If it is useful to you, donations in ETH are welcome:
0x8f614802906dF231b8fbC9a6f11C6728D2A13DDF -
It's my honor to see such a good post. Thank you all for your efforts and dedication.
-
Thank you very much for this quality work, and the pulic open source release!
I have been watching that other rewrite, but the source code isn't public yet. It is also true that LLMs have made decompilation efforts much more tractable than in the past, and we are seeing these projects proliferate, so in my opinion it is a good thing to make an early release to avoid duplicating effort.This looks feature-complete, though. Which brings me to my main question: I have a bit of trouble understanding how much of a 100% faithful reimplementation this is. Given that your compiler is VS 2022, and looking at the libraries used, this does not look like a byte-compatible decompilation (where even the final binary checksum would match). Admittedly, this would be a very high bar to achieve.
And I see that you have included a few fixes already, so:
- how do you decide on what to keep close to the original vs what to change?
- Do you have a roadmap or guidelines for what kind of changes would be accepted?
- lua engine modernization
- network stack modernization
- platform ports (Linux, mac, gcc/clang)
- UI improvements: multiple viewports/windows, shortcuts, menu/artwork changes, etc
- Gameplay interaction changes: unit orders, etc (I quite like PA's drag-circle to build metal extractors, for instance)
There is probably room for multiple similar projects, though, and if you go for a more faithful approach while the other project is more open to changes, that is perfectly fine by me too

We will probably see multiple forks and total conversion, with source code access, I imagine that you have fully anticipated this! -
this does not look like a byte-compatible decompilation (where even the final binary checksum would match)
It won't be byte-to-byte for current binary, not possible, because compilers are different (I'm using clang, not MSVC) and I already did performance optimizations on top. Goal and idea of the project is to have byte-to-byte replay and simulation parity, including visuals - which is fully achieved today for whatever I did tested myself.
how do you decide on what to keep close to the original vs what to change?
Everything is kept to original, nothing changed for sim or rendering that changes visual look from the original. I did changed things in terms of performance, which again - looks identical to original, but now works with modern DX12 and Vulkan (shader/data-driven rendering). If something are not behaving as original to me means a bug that I didn't found yet and I'm happy to fix it when such one reported.
Do you have a roadmap or guidelines for what kind of changes would be accepted?
If you mean to the repo - I will accept changes that fixes bugs that doesn't affect simulation or any other PRs that fixes things I did missed to repeat original game behavior. Since that was AI-assisted there could be hallucinations during decompilation effort for sure. If you mean roadmap of this repo being part of FAF build - that's community and devs to decide, I can only keep simulation parity with original.
About my personal roadmap, there are features planned from my side to create tournament server-side simulation mode that wouldn't change any of the current simulation logic, only as additional flag\compiler definition so everyone can still play regular p2p games.
Testing Linux build also one of the TODOs, since compiler are clang it's possible but will require x87 math adjustments for the platform. -
So, you can update that .exe, and we can run it in MM as a custom option?
-
@draiget Thanks a lot for your work, and Iโm really glad to use this new release. I have two small requests:
- Iโve submitted several PRs to the original FAF binary patches besides the particle pool limit one, including tracks/treads related fixes and memory optimizations. They may also be useful for your project.
- Iโve noticed some visual differences compared to standard FAF. For example, ship wake trails appear much fainter than they are on the official FAF engine.
-
Awesome work!
-
@zhanghm18 thank you for reporting visual bug, I did found it now and will fix. Also glad that this decomp project helped to create more useful binary patches, I'm porting merged ones to my repo as well. Happy to fix all visual differences if there any more

-
If I understand this correctly, with my limited knowledge of FAF dev, this is a pretty huge deal right?
What amazing work. Big props. -
K Katharsas referenced this topic
-
Thank you for your answers.
Goal and idea of the project is to have byte-to-byte replay and simulation parity, including visuals - which is fully achieved today for whatever I did tested myself.
I did see several mentions of MSVC in the repository readme, so I was a bit worried there, but it is good that the project can already be compiled with clang.
Everything is kept to original, nothing changed for sim or rendering that changes visual look from the original.
Gotcha. It should be possible to put test assets in the original, take a screen capture, and replay with the test assets in the CI to catch visual bugs, like what emulators do, if you really want to ensure 1:1 fidelity.
If you mean to the repo - I will accept changes that fixes bugs that doesn't affect simulation or any other PRs that fixes things I did missed to repeat original game behavior.
I really meant your repository. There are so many improvements I could think of, more or less user-visible. I listed some, but less-visible improvements could include multi-monitor improvements, steam input integration to make it easier to play on Steam Deck, Discord/Steam rich presence integration, better integration with FAF (integrated lobby, control it via IPC to avoid restarting the game, etc).
Testing Linux build also one of the TODOs, since compiler are clang it's possible but will require x87 math adjustments for the platform.
Yeaaah... I imagine that the game relies on system libraries? Probably not on the windows ucrt "universal c runtime" otherwise we would have seen desyncs on wine, but x87 definitely need some focus. It should be possible to load windows libraries (extracted from MSVC redist) with a small shim (or compiler options) to adjust the calling convention. That would not be my prefered approach though, as it makes it more complicated to support non-x86 platforms (arm) with native code. The other option is to link another controlled FP library, which behaves the same across platforms. This would break replays (the old library can still be embedded to read them on Windows, but new replays would be generated with the new one, unless additional trickery is performed). But you probably thought about all this already.
Something else came to my mind: It should even be possible to compile this to webassembly, and, with a few changes, have a replay player in the browser. The hard part is that assets are copyrighted and distributed with the game, but at least event (commander destruction, experimental unit built, game stats) can be extracted, and maybe a strategic view/minimap provided with custom assets? I am fairly new to FAF (not to supcom, but these decomp projects attracted me to FAF), but I imagine that the community would value that?
-
Something else came to my mind: It should even be possible to compile this to webassembly, and, with a few changes, have a replay player in the browser. The hard part is that assets are copyrighted and distributed with the game, but at least event (commander destruction, experimental unit built, game stats) can be extracted, and maybe a strategic view/minimap provided with custom assets? I am fairly new to FAF (not to supcom, but these decomp projects attracted me to FAF), but I imagine that the community would value that?
Some lightweight and fast replay tool would be much appreciated. I imagine that issues with copyright can be solved by simply not using any of the actual assets. A replayviewer with just strategic icons, for example, would already be very powerful.
-
This is really cool work! I wanted to see what could be possible with this, so I experimented a little bit

Since I was mapping in the past and fixed water to a single level was quite a frustrating limitation, I made it so it's possible to create water height at different levels / regions.

I now have a small proof of concept with polygon-shaped lakes at different elevations. Ships, submarines, torpedoes and naval factories seem to work in my tests. I also tried AI games and a short two-PC LAN game without a desync, although thereโs still a lot more testing to do.
Video: https://www.youtube.com/watch?v=UmmmxQOOND8
Code: https://github.com/Tokyto/faf-re/tree/regional-water
Editor + Explanation: https://github.com/Tokyto/faf-re/tree/regional-water/regional-water-demoAlso had to make a small tool that allows you to make water / lakes regional for said map (saves as EXAMPLEMAP.v0001.scmap.regionalwater alongside the actual map):

A few technical details:
- The engine loads polygon regions and their water heights from the mapโs sidecar file.
- Water height queries use the local region at a given position. This needed changes in several places, including unit movement, projectile collisions, building placement and some AI queries.
- The renderer creates separate water surfaces for the regions. So far Iโve tested this with D3D9.
- In my tests, ships could navigate along the shores, submarines could dive, torpedoes and torpedo bombers worked, and AI built a naval factory and ships. Transports could also unload units in the raised water.
- The LAN test was done with the same modified engine and map files on both PCs. Itโs a promising start, but definitely not proof that longer multiplayer games are desync-free.
This is an experimental demo, not a finished FAF feature. Big thanks to Draiget and everyone who worked on reconstructing the engine โ I hope this shows some of the interesting possibilities and encourages more experiments!
Feel free to use my vibe coding as you see fit

-
This would really speed up my work with
https://forum.faforever.com/topic/7746/unit-logger-mod?_=1793094473252
I currently have a 169 GB postgres database of unit information through time every few ticks of thousands of replays and the game result. I am sure some interesting strategy and balance information could be extracted from this. Currently it is run on a Linux machine through wine but it does have issues with black-screens and removing the graphics entirely would make it much smoother and faster.
Hello! It looks like you're interested in this conversation, but you don't have an account yet.
Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.
With your input, this post could be even better ๐
Register Login