Debug a mod
Work out why a mod did not load, is not doing what you expect, or crashed the game.
Check it loaded
T3SDK.log records every load attempt. Look for mod <name> loaded; if it is missing, look earlier for why:
mod <name>: no T3Mod_Init export— the DLL does not exportT3Mod_Initunder that exact name. Check thatT3SDK_EXPORT/T3SDK_CALLare on the function, and that the mod is a 32-bit DLL.mod <name>: T3Mod_Init returned N; unloading— your own code returned non-zero; T3SDK also removes any callbacks you registered before this.mod <name>: LoadLibrary failed (error N)— the DLL itself did not load. Look upNas a Windows error code; a common cause is a missing dependency, or a 64-bit DLL in this 32-bit process.
A mod's name here is its package folder name, or a loose DLL's file name.
Watch it run
- Call
api->Logfreely; see Write to the log, and read the engine's own lines. - Set
T3SDK.ini's[T3SDK] Console=1for a live window instead of tailing the file (see SDK use and settings).
A callback misbehaved
If a frame or engine log callback throws, T3SDK catches it, logs a line naming your mod, the exception code and where it happened, and switches off just that one callback; your mod's other callbacks, and the game, continue.
T3Mod_Init is not guarded this way: a crash there ends T3SDK's start-up (the log says exception 0x... during start-up; SDK left partially initialised), and mods later in the load order do not load at all. See The mod lifecycle for the exact rule; keep T3Mod_Init to registering callbacks and creating hooks, nothing that can fail unpredictably.
The game crashed
T3SDK.log gets a report for the first faults in the process: the faulting instruction and every recognisable return address on the stack, each tagged T3Main.exe+offset (game code), T3SDK+offset (the loader) or mod <name> (address) — so a fault inside your own DLL is named directly, by address. This is a report, not a safety net: T3SDK always lets the game go on to handle the fault as it would without the SDK, which usually still means it closes (see SDK use and settings).
A hook detour that reads or writes through a bad pointer crashes exactly like any other engine bug, and shows up the same way (see Hook a game function).
Attach a real debugger
A mod is an ordinary DLL loaded into T3Main.exe, so you can attach Visual Studio (or WinDbg) to the running game once it has started: Debug > Attach to Process, then pick T3Main.exe. Build with debug information (CMake's RelWithDebInfo or Debug configuration) and keep the .pdb next to your DLL — copy the loose DLL and PDB straight into System/mods/ while you work, rather than testing through a packaged .t3mod (which never includes a PDB unless you pack with --with-pdb; see Packaging). Set breakpoints in your own source once the debugger has attached.
Two things to know. Mods load at start-up, before you can attach, so T3Mod_Init has already run by then: log from it instead of breaking in it. And every level change starts a new T3Main.exe (the game restarts itself; see How the game works), so after New Game or a mission change, attach again to the new process.
Reference
- Write to the log, and read the engine's own lines, Hook a game function.
- The mod lifecycle: the full error-handling rules.
- SDK use and settings:
T3SDK.ini'sConsolekey, and the crash report format.