FAForever Forums
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Login
    1. Home
    2. Draiget
    3. Best
    The current pre-release of the client ("pioneer" in the version) is only compatible to itself. So you can only play with other testers. Please be aware!
    D Online
    • Profile
    • Following 0
    • Followers 1
    • Topics 1
    • Posts 3
    • Groups 0

    Posts

    Recent Best Controversial
    • 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.exe and 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, CopyToClipboard and GetHighlightCommand. 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 master after 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 on master are 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 master yourself and test it before you rely on it.

      Building needs Visual Studio 2022 (C++ workload), LLVM and Git:

      git clone --recursive https://github.com/Draiget/faf-re.git
      cd faf-re
      .\build.ps1 -Arch both
      

      Bug 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.

      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.

      posted in Contribution
      D
      Draiget
    • RE: SC: FA (Moho) engine sources

      @MayeulC said:

      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.

      @MayeulC said:

      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.

      @MayeulC said:

      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.

      posted in Contribution
      D
      Draiget