FlandersMod docsInspect it yourselfOverviewArchitectureDecompilation notesIssues

Decompilation notes and limits

Tools

What the output is

Per binary, under decomp/native/<binary>/:

Limits you need to know (these are process issues, not bugs in the mod)

  1. Both binaries are stripped. No symbols, no PDB. Every function is FUN_<addr> and there are no C++ class/method names. Call graphs read as FUN_x(FUN_y(...)). To get names, xrefs and renaming, import the binary into the Ghidra GUI.

  2. This is pseudo-C, not source. The decompiler reconstructs control flow and types; it invents variable names, can get calling conventions or struct layouts wrong, and undefined4/uRam… casts are guesses. Treat it as a readable disassembly, not ground truth.

  3. One DLL function did not decompile: FUN_66175b90 (31,444 bytes — the largest in the DLL). The decompiler timed out on it even at 150 s. It's marked false in functions.csv and appears as a /* decompile failed: timeout */ stub. Open it in the GUI if you need it. (1,266 of 1,267 DLL functions succeeded; the server was 623/623.)

  4. The CRT dominates. Most functions are the statically-linked MinGW C runtime and libstdc++ (std::, random_device, __cxa_…, overflow/length_error machinery). The mod's own code is the subset that references FlandersMP/SHAR strings — that's what strings_by_function.txt is for.

  5. Strings are loaded by address, so grepping for a literal inside global/*.c often misses it (you'll see a bare hex constant instead). Grep strings_by_function.txt or strings.txt to map address↔string, then jump to the function.

  6. Switch tables showed up as fake namespaces (switchD_…). I removed those stub files; the real jump logic is inline in the owning function.

  7. No dynamic analysis. Everything is inferred from static code. Anything about runtime behaviour (what actually gets sent on the wire, whether a bound is hit in practice) is an inference and is tagged accordingly in issues.md.