Contractors Showdown ExfilZone on Linux: Fixing Wine's BattlEye Launcher

Contractors Showdown ExfilZone refused to launch under Proton, and the reason turned out to be a single character: a leading backslash in a config file. I traced it, patched Wine's BattlEye launcher upstream (ValveSoftware/wine PR #331), and wrote it up on r/linux_gaming. Here's the whole chain, plus a workaround you can apply right now.

Contractors Showdown ExfilZone running on Linux after the BELauncher fix
ExfilZone on Linux after the fix.

The symptom

Wine's belauncher.exe — the shim that starts BattlEye-protected games under Proton — exited with error 2 (ERROR_FILE_NOT_FOUND). No game window, no crash dialog, nothing helpful.

Tracing it

Running with WINEDEBUG=+belauncher showed the launcher building its launch_cmd without the game's install-directory prefix — even though the trace line immediately before it had the install path in hand. CreateProcessW was being handed a path resolved against the current drive's root, which doesn't exist, hence error 2.

The root cause: a PathIsRelativeW edge case

ExfilZone's BELauncher.ini specifies its executable as a Win32 root-relative path — one starting with a backslash:

64BitExe=\Game\Binaries\Win64\Game.exe

Wine's launcher code in programs/belauncher/main.c only prepended the install directory when PathIsRelativeW(game_exeW) returned TRUE. But per the Win32 semantics (and Wine's own dlls/kernelbase/path.c implementation), PathIsRelativeW returns FALSE for any path starting with \ — root-relative paths are technically not "relative." So these paths fell straight through the guard, got no prefix, and the launch died.

On real Windows this works anyway because BattlEye's path ends up resolving against the game drive. Under Wine, the current drive assumption breaks.

The patch

The first version extended the guard: treat a leading backslash like a relative path. Review moved it to something cleaner — strip the leading backslash (a memmove over the buffer, with a safeguard that leaves UNC paths starting with \\ untouched), so game_exeW stays in a consistent state for all the downstream code, and the existing relative-path handling does the rest. Reviewers also asked for a comment noting this works around BattlEye's path handling, since a leading backslash would natively resolve to the disk root on Windows.

The PR is open upstream against ValveSoftware/wine. Once it ships in Proton's Wine, every BattlEye title that writes a root-relative 64BitExe= just works.

The workaround you can use today

Until the patch ships: open BELauncher.ini in the game's install directory and delete the leading backslash from the 64BitExe= line. That's it.

Caveat: Steam's "Verify integrity of game files" restores the original file, so you'll need to re-apply the edit after every verify pass.

FAQ

Does Contractors Showdown ExfilZone work on Linux?
Yes — either apply the BELauncher.ini workaround above, or run a Proton build that includes the belauncher patch once merged.
Why does the launcher fail with error 2?
Error 2 is ERROR_FILE_NOT_FOUND: the launcher hands CreateProcessW a root-relative path without the install-directory prefix, so it points at a file that doesn't exist.
Does this affect other BattlEye games?
Any title whose BELauncher.ini uses a leading-backslash 64BitExe= path hits the same bug — and gets fixed by the same patch.

Related