With wine-mono from the master branch I get this:
[00000028:] EXCEPTION handling: System.InvalidProgramException: Invalid IL code in ^].^Z:^A (): IL_0019: callvirt 0x0a000fda
Looks like obfuscated code, that'll be a pain to track down.
The failing code looks like this
IL_0000: br.s IL_0012
IL_0002: ldnull
IL_0003: ldftn class [mscorlib]System.Reflection.Assembly '\u001d.\u001a'::'\u0001'(object, class [mscorlib]System.ResolveEventArgs)
IL_0009: newobj instance void [mscorlib]System.ResolveEventHandler::.ctor(object, native int)
IL_000e: br.s IL_0019
IL_0010: leave.s IL_0023
IL_0012: call class [mscorlib]System.AppDomain [mscorlib]System.AppDomain::get_CurrentDomain()
IL_0017: br.s IL_0002
IL_0019: callvirt instance void [mscorlib]System.AppDomain::add_AssemblyResolve(class [mscorlib]System.ResolveEventHandler)
My guess: Mono processes the code sequentially to figure out the stack types, but in fact the objects aren't pushed in the order they're written. It fails because the call signature doesn't match what it thinks is supposed to be in the stack.
I am running the game without obfuscation on my SteamDeck.
Here is the full error log.
steam-17677587930077462528.log
My issue is this.
Unhandled exception: unimplemented function d3dx9_36.dll.D3DXGatherFragments called in 32-bit code (0x7b011197).
D3DX fragment linker was removed in later builds of DX9 releases. Will look into it. If anyone has any suggestions, please let me know.
The game uses the November 2007 SDK which is D3DX9_35
I should note, I did get this working when I first got my Deck.
https://community.projecttorque.racing/threads/steam-deck-support-it-works.1618/#post-9316
I used ProtonTricks to install the following
This stopped working a couple of weeks after I posted that topic on our forum.
Opening the dump files from the Steam Deck and it looks to be an issue with Fragment Linker.

If one force installs d3dx9_36 via ProtonTricks, it no longer crashes when loading.
But that game does not fully load up.

It is getting stuck on loading the game.

At this point, I would guess this is a .NET 3.5 issue stopping the game fully loading.
More Proton debugs from the game.
Fresh install of the latest OS and running Proton 7.0-5
Stock Proton settings other than "DXVK_LOG_LEVEL": "full",
DXVK.log
"PROTON_USE_WINED3D": "1",
WINED3D.log
Looks to be a Wine level issue. Will report back.
So I tested an old .exe today and it worked when I included the d3dx9_36.dll and d3dx9_31.dll files in the game directory.
When running without these files, I got the "unimplemented function d3dx9_36.dll.D3DXGatherFragments" error.
I have not been able to get the current build to load the .DLLs before today so did not upload them to the deck and we don't include them with the release (as advised) as Steam handles the DX9 install.
Here is the Proton log from the old version that runs.
steam-16801495106560458752.log
I have just tried 2 new builds and both worked when the DLLs were included in the game directory.
Even managed to get the March 2010 SDK working and that I believe is the last SDK we can run before stuff got properly removed.

As for how the obfuscated version use to run, IDK. We have made some changes and updates to the obfuscation so I will roll back and check to see what might be causing us issues.
Rolled back to an earlier version and it does not run.
Looks like users will need to force install .NET 3.5 to get it working as Mono does not run the obfuscated code.
Is anyone able to advise on how to force .NET 3.5 over mono or a way to install it that is easy for the end user?
ProtonTricks does not want to install 3.5 (at least since May 2022) as it comes up with the "2.0 is not installed" error.
This is what I got in the error log after trying to install .NET 3.5 through protontricks using the latest GE:
[12/15/24,15:59:41] WapUI: [2] DepCheck indicates XPSEPSC x64 Installer is not installed.
[12/15/24,19:57:14] WapUI: [2] DepCheck indicates XPSEPSC x64 Installer is not installed.
[12/15/24,23:44:53] WapUI: [2] DepCheck indicates XPSEPSC x64 Installer is not installed.
I think I need to run it in Compatibility mode.
The game does work if you install Proton GE
Currently adding Steam SDK support along with controller and Deck detection for better useability on the Deck and other handhelds. So hopefully we can work out a native fix and get this game running without tinkering.
It actually plays really well even at low TDP settings.
Proton log: steam-1112400.log
Custom game scripts: user_settings.py ProjectTorque.exe.config.txt
Project Torque crashes shortly after launch with a Mono SGEN garbage collector assertion failure. The game is built for .NET Framework 3.5 but Proton's Wine-Mono attempts to run it under .NET 4.8, causing a critical stack validation failure in the stop-the-world GC.
Fatal Crash:
* Assertion at /builds/mono/wine-mono/wine-mono-10.4.1/mono/mono/metadata/sgen-stw.c:73,
condition `info->client_info.stack_start >= info->client_info.info.stack_start_limit &&
info->client_info.stack_start < info->client_info.info.stack_end' not met
.NET Version Mismatch:
fixme:mscoree:parse_supported_runtime sku=L".NETFramework,Version=v4.8" not implemented
Note: Game targets .NET 3.5, but Wine-Mono defaults to 4.8 regardless of ProjectTorque.exe.config settings.
Steam Deck Hardware:
None successful. Tested:
PROTON_NO_FSYNC=1PROTON_NO_ESYNC=1PROTON_USE_WINED3D=1WINEDLLOVERRIDES=mf=n;mfplat=n;mfplay=nProjectTorque.exe.config with <supportedRuntime version="v2.0.50727"/>MONO_GC_PARAMS=gc=boehm (not supported - Wine-Mono is SGEN-only)Full Proton log attached as steam-1112400.log.
Key excerpts:
======================
Proton: 1769167055 proton-10.0-4
SteamGameId: 1112400
Command: ['/home/deck/.local/share/Steam/steamapps/common/Project Torque/ProjectTorque.exe']
Options: {'noesync', 'wined3d', 'forcelgadd', 'nofsync'}
depot: 3.0.20251216.191774
pressure-vessel: 0.20251210.0 scout
scripts: 0.20251210.0
sniper: 3.0.20251216.191774
Kernel: Linux 6.11.11-valve27-1-neptune-611-g60ef8556a811 #1 SMP PREEMPT_DYNAMIC Thu, 08 Jan 2026 10:09:09 +0000 x86_64
Game Information:
Root Cause:
The Mono SGEN garbage collector's stop-the-world phase (sgen-stw.c) fails stack bounds validation during garbage collection. This appears to be triggered by the game's threading pattern combined with the .NET version mismatch.
The game runs successfully for multiple GC cycles (12-15 seconds) before hitting the assert, suggesting specific threading conditions trigger the bug.
Fix Wine-Mono to respect .NET version requests - Should honor <supportedRuntime version="v2.0.50727"/> for .NET 3.5 applications
Backport SGEN stack validation fixes - If upstream Wine has addressed this, consider backporting
Consider alternative for .NET 3.5 games - Allow using native .NET via winetricks more seamlessly
https://protondb.com/app/1112400
--
Tagging: @wine-mono maintainers
From the log, with lines trimmed that I don't think are relevant:
10383.990:0128:012c:fixme:mscoree:corruntimehost_SwitchOutLogicalThreadState stub 00B7A370
10383.990:0128:012c:fixme:mscoree:corruntimehost_CreateLogicalThreadState stub 00B7A370
* Assertion at /builds/mono/wine-mono/wine-mono-10.4.1/mono/mono/metadata/sgen-stw.c:73, condition `info->client_info.stack_start >= info->client_info.info.stack_start_limit && info->client_info.stack_start < info->client_info.info.stack_end' not met
Looking up CreateLogicalThreadState, it seems this has to do with fibers. I don't know a lot about those, but it makes sense to me that switching to a fiber would put the thread stack pointer out of the range where the GC expects to find it. I would guess that we need to implement those methods, but I don't know the proper way to forward that information to Mono, if there even is one.
I'm surprised stopping the world is still necessary with SGEN. I'd thought the point of cooperative GC was to remove the need for such things.
A cursory search suggests that Mono is not currently able to handle fibers.
OK, looking a little bit more carefully, SGEN and cooperative suspend removes the need for stopping threads in random places. Instead, threads are only stopped in managed code and some parts of the runtime. But it seems that SGEN still examines stack pointers and wants to know about stack ranges. So what's likely happening here is that Project Torque is calling into the runtime from a fiber, the runtime sees while attempting GC things that its current stack pointer is not in the expected range, and it asserts.
MSDN doesn't really explain those unimplemented methods at all, but I'm guessing what's expected is:
I guess that a "logical thread state" roughly corresponds to Mono's SgenThreadInfo structure. And, because of cooperative suspend, we don't have to worry as much about stopping threads at weird times. So this may not be as hard as I initially thought. But there are still a lot of unknowns as I'm not very familiar with fibers or SGEN internals, and it'll have to be done in two steps (adding an API for this to Framework Mono that works on Windows, then using it to implement the logical thread state APIs in Wine).
This might be a good starter project for someone who wants to learn about the Mono GC. But since it only affects this one game, to my knowledge, and is moderately difficult, I don't see myself working on it in the near future.
Replying to https://github.com/ValveSoftware/Proton/issues/3359#issuecomment-3865046597
There was a commented out "#ifndef USE_THREAD_INSTEADOF_FIBER"
Looks to have fixed it on a fresh install on my Steam Deck.
Thank you @madewokherd !
Testing obfuscation build next.
proton 10.0x1 2026-02proton 10.0-4x1 2026-02proton 7.0-5x1 2022-12PROTON_NO_ESYNC=1`x1 2026-02PROTON_NO_FSYNC=1`x1 2026-02PROTON_USE_WINED3D=1`x1 2026-02WINEDLLOVERRIDES=mf=n;mfplat=n;mfplay=n`x1 2026-02DXVK_LOG_LEVELx1 2022-12PROTON_USE_WINED3Dx1 2022-12d3dx9_36.dllx2 2022-12d3dx9_31.dllx1 2022-12
Compatibility Report
System Information
I confirm:
steam-1112400.log
Symptoms
The game does not launch and instead crashes before anything else happens.
Reproduction