A modern C++ tool that regenerates the PCConsoleTOC.bin lookup tables shipped with the
original Mass Effect 3 and the three Mass Effect Legendary Edition games.
Recomputing these is what allows file-replacement mods (DLC mods, DLC_MOD_*, etc.) to
take effect -- the games won't load files they don't see in the TOC.
The tool supports four games:
| Argument | Game |
|---|---|
ME3 |
Mass Effect 3 (original 2012 release) |
LE1 |
Mass Effect Legendary Edition — ME1 |
LE2 |
Mass Effect Legendary Edition — ME2 |
LE3 |
Mass Effect Legendary Edition — ME3 |
GitHub) Head over to Releases and download the latest release matching your platform.
GitLab) Head over to Releases and download the latest release matching your platform.
Requires a C++20 compiler (GCC 11+, Clang 13+, or MSVC 2019 16.10+) and Meson or CMake 3.20+.
meson setup _build -Ddefault_library=static
meson compile -C _buildcmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build --config ReleaseOn Linux you can also build directly without CMake:
g++ -std=c++20 -O2 -pthread \
src/main.cpp src/ini_parser.cpp src/toc_bin_file.cpp src/toc_creator.cpp \
-o me3tocfixme3tocfix <path-to-game-exe>
me3tocfix -r <ME3|LE1|LE2|LE3> (Windows/Wine only registry lookup)For example via providing the absolute path:
me3tocfix "D:\Origin Games\Mass Effect Legendary Edition\Game\ME3\Binaries\Win64\MassEffect3.exe"Or via the Windows registry:
me3tocfix -r LE3me3tocfix will write a fresh PCConsoleTOC.bin to the BioGame directory and
to every DLC subfolder (or, for LE1, only to BioGame, since LE1 folds all DLC
content into a single basegame TOC by mount priority).
- CRC table built at compile time. Original lazy-init had a non-atomic
null-check race when called from
Task.WhenAll. Now it'sconstexpr, baked into the binary, and trivially thread-safe. std::asyncinstead ofTask.WhenAll. Same fan-out parallelism for basegame + per-DLC jobs.- Prime-rounded hash-table sizes.
hash % Tdistributes badly whenTshares factors with patterns in the input — powers of 2 are pathological, and round numbers like 100 cluster too. We snap the chosenTdown to the nearest prime, which costs a few primality trials at build time and gives tighter chains for free. The C# project usesT = Ndirectly and gets lucky or unlucky depending onN's factorization. - Defensive name-length check. Each TOC entry stores its serialized length in an int16, capping name length at ~32 KiB. Real ME / LE filenames are nowhere near that, but we now reject names that would overflow the field rather than silently producing a corrupt TOC.
- 2-GiB warning. The C# version silently casts file sizes to
int, which produces a corrupt TOC for files ≥ 2 GiB. We warn loudly when this happens. - Cross-platform core, including version detection. The TOC algorithm
itself runs on Linux/macOS, which is convenient for headless build
pipelines. The C# project version's
MassEffect3.exe→ ME3 vs LE3 disambiguation relied on the Win32GetFileVersionInfoAPI, leaving non-Windows callers blind; we now parse the PE format directly to read the FileVersion resource, so detection works the same on every platform. Only the registry fallback (-rflag) remains Windows-only. - Trimmed-down INI parser. AutoTOC only ever reads one value out of a DLC
autoload.ini(theModMountpriority); we ship a minimal read-only parser instead of porting the fullDuplicatingIniand its supporting types. - Correct file write semantics. Original
DuplicatingIni.WriteToFilenever disposed/flushed itsStreamWriter, which can produce truncated INI files. We don't write INIs at all here, but the TOC writer uses RAII to guarantee proper flush + close. - Cleaner serialiser. No
MemoryStream.Seekgames — we build the TOC into astd::vector<uint8_t>and patch the hash-table slots in place once each bucket's offset is known, which makes the on-disk layout much easier to audit against the format. - Better error messages. The C# project
CreateDLCTOCswallows every exception as "may just be packed DLC". We still don't fail the whole run on one bad DLC, but we surface the actual error so genuine bugs aren't hidden. - Robust missing-directory handling.
Directory.GetFilesthrows on missing input;std::filesystem::directory_iteratorwitherror_codedoesn't, so we degrade gracefully when, say,BIOGame/Moviesdoesn't exist.
- AutoTOC from the ME3Tweaks project.
This project is not affiliated in any way with any of the above mentioned projects other than to acknowledge its source of inspiration.