Root cause found (at least on my system): kernel ntsync. Workaround: PROTON_NO_NTSYNC=1
Same symptom as @igormcsouza with AC Black Flag Resynced (appid 3751950) and also AC Shadows: pressing Play sometimes does nothing, launcher_log.txt stops at Using CEF with native rendering and never reaches Login Type: ticket, platform: Steam. The failure is random per launch — parsing my launcher_log.txt history gave 7 successes out of 36 launches (~19%) since install.
System: CachyOS, kernel 7.1.3-2-cachyos (has /dev/ntsync), Proton Experimental buildid 24009459, Mesa/RADV, Wayland session.
What I found while the launcher was stalled:
upc.exe process tree is alive (~50 threads incl. CrBrowserMain, plus UplayWebCore.exe CEF helpers). No crash, no error — and no network connections ever opened, so it hangs before even requesting the Steam auth ticket.UplayWebCore.exe) spawn and exit within ~1 second, repeatedly, until CEF gives up; meanwhile the Ubisoft startup threads freeze at the exact moment of CEF init. The CEF browser thread keeps pumping (Chromium's HangWatcher is visibly sampling thread contexts in the Proton log), so it's an in-process deadlock/lost-handshake, not a kernel-level hang.wchan ntsync_char_ioctl — Proton Experimental silently prefers the kernel ntsync device over fsync when /dev/ntsync exists (WINEFSYNC=1 in the env is ignored in that case; wineserver prints ntsync: up and running.).upc.exe self-terminates the moment winedbg attaches (anti-debug), so no backtraces that way. SIGSTOP/SIGCONT on the stalled process does not un-stick it.Workaround that fixed it: launch options
PROTON_NO_NTSYNC=1 %command%
Result: 10/10 successful launches (vs the 19% baseline; ~1e-5 probability of that being luck). Same fix works for AC Shadows.
Things I ruled out with A/B launches, in case they're suggested here: deleting the launcher's cache/http2 (still stalls after full wipe — the random success rate just makes it look like a fix), PROTON_ENABLE_WAYLAND/HDR launch options (stalls with and without), Proton/Steam/kernel updates (none in the failure window).
@igormcsouza — your gdb-attach "nudge" workaround fits this picture: attaching perturbs the ntsync wait timing rather than fixing anything. If your kernel has /dev/ntsync, could you check whether PROTON_NO_NTSYNC=1 also fixes it for you? That would confirm this is an ntsync race in CEF's subprocess handshake rather than something game-specific.
I tested PROTON_NO_NTSYNC=1 idea from @bertonha but unfortunately it cannot apply to my system (my kernel doesn't supports it), I hit the same symptom on fsync and esync, so the race is probably not ntsync-specific tho.
My setup with kernel 6.17.0-oem (no /dev/ntsync.. the flag is a no-op here, Proton logs fsync: up and running) and Proton Experimental
But thanks to this great debugging effort from @bertonha I was able to narrow down even more the issues for me and here is what I found while debugging my stalls:
gdb -batch -p <pid> -ex 'handle SIGUSR1 nostop noprint pass' -ex 'handle SIGQUIT nostop noprint pass' -ex 'handle SIGSYS nostop noprint pass' -ex continue. 100% launch success since. Happy to share the updated and more precise version.TL;DR: PROTON_NO_NTSYNC=1 untestable here (no ntsync), but the same race reproduces on fsync and esync.. so the root cause is likely in the CEF/launcher subprocess handshake itself, with the sync backend only affecting how often the window is hit.
I can confirm the same issue on my system.
System:
Without the GDB workaround, Ubisoft Connect launches, but the game never reaches a playable state.
The helper script was able to start the game process, but on my system that alone was not sufficient. ACBlackFlag.exe remained running in the background (sleeping) without creating a game window.
What consistently works for me is attaching GDB directly to the running ACBlackFlag.exe process after it has started:
gdb -q -batch -p <PID_OF_ACBlackFlag.exe> \
-ex 'set pagination off' \
-ex 'detach' \
-ex 'quit'
As soon as I detach from the actual game process, the game immediately continues and the window appears.
So in my case, the GDB nudge is required not only for the Proton/Ubisoft launcher process but also for the actual ACBlackFlag.exe process.
I can confirm the same issue on my system.
System:
Three issues in acbf_resync_nudge.sh prevented it from working on my system:
GAME_PATTERN never matched the real game processThe original pattern '^S:.*ACBlackFlag\.exe' was written for ps output (where S: is the process state), but find_pid uses pgrep -af which outputs PID COMMAND. The ^ anchored to the PID number, so nothing ever matched. Additionally, bare ACBlackFlag.exe matched the outer shell wrapper (/bin/sh -c ... steam-launch-wrapper ... ACBlackFlag.exe) and the Wine steam.exe shim, both of which have lower PIDs than the real game process.
Fix: Changed to 'Z:.*ACBlackFlag\.exe' to match the actual Wine process path (e.g. Z:\...\ACBlackFlag.exe), and added an exclude parameter to find_pid to filter out the shim.
nudge() used -ex continue instead of -ex detachThe nohup gdb ... -ex continue & approach keeps GDB attached and tracing, which doesn't produce the stop/resume cycle needed to unblock the futex deadlock. What actually works is attach-then-detach: GDB attach stops all threads, then detach resumes them, forcing every thread to re-check its wait condition.
Fix: Changed to gdb -batch -p "$pid" -ex 'detach' -ex 'quit' (synchronous, no backgrounding needed).
LAUNCHER_PATTERN missed UbisoftConnect.exeOn my system the launcher binary is UbisoftConnect.exe, not UbisoftGameLauncher.exe.
Fix: Added alternation to cover both names.
I add the updated script in case it helps you. The game launches normally with the script now
Good news! Thanks to the comment from Hodor at ProtonDB I got a much better workaround which is to set sudo sysctl kernel.split_lock_mitigate=0 before starting the game!
I see some distributions already comes with this enabled and that explains why people are getting the game running out of the box.. and why for others only disabling ntsync would suffice..
I hope this can help people that are striving to run the game using the nudge ... And it actually narrows down even more the issue!
I'm used to set this guy to 0 when running NFS Heat.. but would love to have a proper fix for Assassin's Creed Black Flag Resynced.. :D So you can finally just play and go!
AC: Black Flag Resynced - In-game HDR setting automatically reverts to OFF on SteamOS / Proton (Steam Machine 512GB)
Issue transferred from https://github.com/ValveSoftware/Proton/issues/9970.
@geeksonhugs posted on 2026-07-13T20:05:42:
Assassin's Creed: Black Flag Resynced (AppId: 3751950)
Steam Machine 512GB (2026)
Custom Steam Machine console configuration (Connected to a 4K Living Room TV).
Default selected stable Proton build, also tested on Proton Experimental & Proton Hotfix.
Assassin's Creed: Black Flag Resynced
The native in-game HDR toggle refuses to stick. When toggling HDR to "On" in the video settings and hitting apply, the screen blanks out momentarily for a display handshake, but immediately returns with the setting reverted to "Off."
Note: The SteamOS Quick Access Menu (QAM) "Enable HDR" toggle works perfectly, triggering the expected system-level tonemapping pop, but the game engine itself fails to recognize native HDR availability.
In all scenarios, the behavior remains identical: the display blanks out and immediately reverts the native HDR toggle back to off.
IDK if this is the most appropriate place to talk about this. The HDR is working, but in a strange way.
Before I add this configs PROTON_ENABLE_WAYLAND=1 PROTON_ENABLE_HDR=1 %command% when I enabled the HDR the colors were completed washed (as I already experience in other games with HDR problems). After adding, it worked but, the color still a little bit washed out (less but still visible). I'm using last Bazzite version, RTX 4090 and I9 CPU.
More info:
I tried many proton versions, inclusing GE protons.
Game has been running great with 100+ FPS on my 5800X and 9070XT.
I have run into some crashes though. The amdgpu driver crashes and resets the GPU:
Jul 17 00:24:45 n0va kernel: amdgpu 0000:09:00.0: [gfxhub] page fault (src_id:0 ring:24 vmid:5 pasid:391)
Jul 17 00:24:45 n0va kernel: amdgpu 0000:09:00.0: Process ACBlackFlag.exe pid 123758 thread vkd3d_queue pid 124326
Jul 17 00:24:45 n0va kernel: amdgpu 0000:09:00.0: in page starting at address 0x0000000000000000 from client 10
Jul 17 00:24:45 n0va kernel: amdgpu 0000:09:00.0: GCVM_L2_PROTECTION_FAULT_STATUS:0x00501031
Jul 17 00:24:45 n0va kernel: amdgpu 0000:09:00.0: Faulty UTCL2 client ID: TCP (0x8)
Jul 17 00:24:45 n0va kernel: amdgpu 0000:09:00.0: MORE_FAULTS: 0x1
Jul 17 00:24:45 n0va kernel: amdgpu 0000:09:00.0: WALKER_ERROR: 0x0
Jul 17 00:24:45 n0va kernel: amdgpu 0000:09:00.0: PERMISSION_FAULTS: 0x3
Jul 17 00:24:45 n0va kernel: amdgpu 0000:09:00.0: MAPPING_ERROR: 0x0
Jul 17 00:24:45 n0va kernel: amdgpu 0000:09:00.0: RW: 0x0
Jul 17 00:24:45 n0va kernel: amdgpu 0000:09:00.0: [gfxhub] page fault (src_id:0 ring:24 vmid:5 pasid:391)
Jul 17 00:24:45 n0va kernel: amdgpu 0000:09:00.0: Process ACBlackFlag.exe pid 123758 thread vkd3d_queue pid 123886
Jul 17 00:24:45 n0va kernel: amdgpu 0000:09:00.0: in page starting at address 0x000000000100d000 from client 10
Jul 17 00:24:47 n0va kernel: amdgpu 0000:09:00.0: Dumping IP State
Jul 17 00:24:47 n0va kernel: amdgpu 0000:09:00.0: Dumping IP State Completed
Jul 17 00:24:47 n0va kernel: amdgpu 0000:09:00.0: [drm] AMDGPU device coredump file has been created
Jul 17 00:24:47 n0va kernel: amdgpu 0000:09:00.0: [drm] Check your /sys/class/drm/card1/device/devcoredump/data
Jul 17 00:24:47 n0va kernel: amdgpu 0000:09:00.0: ring gfx_0.0.0 timeout, signaled seq=23536171, emitted seq=23536173
Jul 17 00:24:47 n0va kernel: amdgpu 0000:09:00.0: Process ACBlackFlag.exe pid 123758 thread vkd3d_queue pid 124326
Jul 17 00:24:47 n0va kernel: amdgpu 0000:09:00.0: Starting gfx_0.0.0 ring reset
Jul 17 00:24:49 n0va kernel: amdgpu 0000:09:00.0: Ring gfx_0.0.0 reset failed
Jul 17 00:24:49 n0va kernel: amdgpu 0000:09:00.0: GPU reset begin!. Source: 1
Jul 17 00:24:49 n0va kernel: amdgpu 0000:09:00.0: [drm] *ERROR* Failed to initialize parser -125!
Jul 17 00:24:51 n0va kernel: amdgpu 0000:09:00.0: MES(1) failed to respond to msg=REMOVE_QUEUE
Jul 17 00:24:51 n0va kernel: amdgpu 0000:09:00.0: failed to unmap legacy queue
Jul 17 00:24:52 n0va kernel: [drm:gfx_v12_0_hw_fini [amdgpu]] *ERROR* failed to halt cp gfx
Jul 17 00:24:52 n0va kernel: amdgpu 0000:09:00.0: MODE1 reset
Jul 17 00:24:52 n0va kernel: amdgpu 0000:09:00.0: GPU mode1 reset
Jul 17 00:24:52 n0va kernel: amdgpu 0000:09:00.0: GPU smu mode1 reset
Jul 17 00:24:53 n0va kernel: amdgpu 0000:09:00.0: GPU reset succeeded, trying to resume
Jul 17 00:24:53 n0va kernel: amdgpu 0000:09:00.0: [drm] PCIE GART of 512M enabled (table at 0x0000008000000000).
Jul 17 00:24:53 n0va kernel: amdgpu 0000:09:00.0: VRAM is lost due to GPU reset!
Jul 17 00:24:53 n0va kernel: amdgpu 0000:09:00.0: PSP is resuming...
Jul 17 00:24:53 n0va kernel: amdgpu 0000:09:00.0: RAP: optional rap ta ucode is not available
Jul 17 00:24:53 n0va kernel: amdgpu 0000:09:00.0: SECUREDISPLAY: optional securedisplay ta ucode is not available
Jul 17 00:24:53 n0va kernel: amdgpu 0000:09:00.0: SMU is resuming...
Jul 17 00:24:53 n0va kernel: amdgpu 0000:09:00.0: SMU is resumed successfully!
Jul 17 00:24:53 n0va kernel: amdgpu 0000:09:00.0: program CP_MES_CNTL : 0x4000000
Jul 17 00:24:53 n0va kernel: amdgpu 0000:09:00.0: program CP_MES_CNTL : 0xc000000
Jul 17 00:24:53 n0va kernel: amdgpu 0000:09:00.0: [drm] DMUB hardware initialized: version=0x0A000C00
Jul 17 00:24:53 n0va kernel: amdgpu 0000:09:00.0: ring gfx_0.0.0 uses VM inv eng 0 on hub 0
Jul 17 00:24:53 n0va kernel: amdgpu 0000:09:00.0: ring comp_1.0.0 uses VM inv eng 1 on hub 0
Jul 17 00:24:53 n0va kernel: amdgpu 0000:09:00.0: ring comp_1.1.0 uses VM inv eng 4 on hub 0
Jul 17 00:24:53 n0va kernel: amdgpu 0000:09:00.0: ring comp_1.0.1 uses VM inv eng 7 on hub 0
Jul 17 00:24:53 n0va kernel: amdgpu 0000:09:00.0: ring comp_1.1.1 uses VM inv eng 8 on hub 0
Jul 17 00:24:53 n0va kernel: amdgpu 0000:09:00.0: ring sdma0 uses VM inv eng 9 on hub 0
Jul 17 00:24:53 n0va kernel: amdgpu 0000:09:00.0: ring sdma1 uses VM inv eng 10 on hub 0
Jul 17 00:24:53 n0va kernel: amdgpu 0000:09:00.0: ring vcn_unified_0 uses VM inv eng 0 on hub 8
Jul 17 00:24:53 n0va kernel: amdgpu 0000:09:00.0: ring jpeg_dec uses VM inv eng 1 on hub 8
Jul 17 00:24:53 n0va kernel: amdgpu 0000:09:00.0: GPU reset(1) succeeded!
Jul 17 00:24:53 n0va kernel: amdgpu 0000:09:00.0: [drm] device wedged, but no recovery needed
Jul 17 00:24:54 n0va systemd-coredump[163269]: Process 8210 (Xorg) of user 1000 terminated abnormally with signal 6/ABRT, processing...
Jul 17 00:24:54 n0va systemd[1]: Created slice Slice /system/systemd-coredump.
Jul 17 00:24:54 n0va systemd[1]: Started Process Core Dump (PID 163269/UID 0).
Jul 17 00:24:54 n0va systemd-coredump[163270]: [🡕] Process 8210 (Xorg) of user 1000 dumped core.
Replying to https://github.com/ValveSoftware/Proton/issues/9958#issuecomment-4936716638
Can confirm PROTON_NO_NTSYNC=1 fixes issues with Ubisoft Connect Launcher on Proton 11 (also fixes other Ubisoft games like AC Odyssey, Immortals: Fenix Rising).
Update: When using a Proton 10 version that supports NTsync via PROTON_USE_NTSYNC=1 the Ubisoft Connect Launcher is also working as expected 100% of the time with NTsync enabled hinting to this being a regression issue in Proton 11
Since the original report, I re-tested and gathered more targeted data. A few corrections and new findings below.
The attached steam-3751950.log actually shows:
{'gamedrive', 'nvml', 'nofsync', 'forcelgadd'}I likely had multiple Proton versions installed and the log came from a different run than I described. All testing described below was confirmed on GE-Proton11-3; I have not re-verified this on Proton Experimental since correcting the environment, so I'm not claiming it reproduces there until confirmed.
The original report only showed GDB's own crash backtrace after PTRACE_ATTACH/detach, which doesn't actually show what the game was doing — it shows GDB dying. To get real data, I read the kernel's thread state directly via procfs, which does not use ptrace and does not disturb the process:
PID=$(pgrep -x ACBlackFlag.exe | head -n1)
sudo bash -c 'for t in /proc/'"$PID"'/task/*; do
tid=$(basename "$t")
echo "== TID $tid =="
grep "^State" "$t/status" 2>/dev/null
printf "wchan: "; cat "$t/wchan" 2>/dev/null; echo
cat "$t/syscall" 2>/dev/null; echo
done'
Result while the process appeared hung:
== TID <pid> ==
State: S (sleeping)
wchan: msleep_interruptible
syscall: -1 0x10e6f8 0x6ffffd15b302
Caveat: only the main thread was present at the moment of capture, and I did not confirm RSS had already reached the ~600MB plateau reported in the original hang before taking this snapshot. So it's possible this caught an early initialization phase rather than the fully-stalled state. I'll re-verify RSS is at the plateau before capturing next time to rule this out.
With that caveat noted, the main thread was not blocked in a userspace futex wait (which would point to a VMProtect/ntsync userspace deadlock). It was sleeping inside msleep_interruptible, i.e. a kernel-side retry/poll loop, which is more consistent with a driver-level wait (syscall: -1 means it's inside kernel code, not returning from a specific syscall number).
No NVIDIA driver errors, timeouts, or GPU hang warnings appear in dmesg during the hang window. The driver loaded cleanly at boot; nothing unusual was logged while the process was stuck.
Re-tested with strace -p <pid> alone (no detach needed) — this also reliably unstuck the process. So the trigger is any PTRACE_ATTACH, not something specific to GDB. I'd suggest retitling this as a ptrace-attach-triggered wake rather than a "GDB interrupt."
A subsequent strace -f -tt -p <pid> -o file.log snapshot (taken immediately after attach, so already somewhat disturbed) showed 100+ worker threads parked in ordinary futex(FUTEX_WAIT_PRIVATE, ...), readv(), and pselect6() calls — consistent with an idle thread pool waiting for work, not a classic circular-wait deadlock among userspace locks.
Given:
msleep_interruptible (kernel-side wait), not a userspace futex (with the capture-timing caveat above)This looks less like a pure VMProtect-userspace threading deadlock and more like a stall in GPU/graphics device initialization (e.g., DXVK/VKD3D device creation or a similar wait loop that happens to be interruptible by any process trace event). The original VMProtect suspicion isn't ruled out — .vmp4-protected code could still be involved in whatever calls into this wait — but I no longer think it's the whole picture.
sudo cat /proc/<pid>/stack for the hung thread if kernel symbols are available, to get the actual kernel call chain above msleep_interruptiblePROTON_NO_NTSYNC=1 / PROTON_NO_FSYNC=1 individually toggled to see if either changes reproducibilityAttached: steam-3751950.log (Proton run trace), acbf_prehang_procfs.log (pre-attach thread state, most reliable evidence so far), acbf_strace_full.log (post-attach thread snapshot, for reference).
acbf_prehang_procfs.log
acbf_strace_full.log
steam-3751950.log
The second stall point @igormcsouza described (login succeeds, ACBlackFlag.exe parks at 1 thread during the UbisoftGameLauncher64.exe inject handshake, a gdb attach unsticks it, kernel.split_lock_mitigate=0 fixes it) is the same thing I traced in Far Cry 4, and the mechanism explains all three observations: https://github.com/ValveSoftware/Proton/issues/2143#issuecomment-5850732240
In short: the injection target executes a split-locked instruction right away. With split_lock_mitigate=1 the kernel sleeps 10 ms in msleep_interruptible() before letting it run, and gives up if interrupted. The injector's context polling makes wineserver signal the thread thousands of times per second, so it re-traps forever. Attaching gdb works because wineserver then can't ptrace the thread: GetThreadContext fails with error 5, and Ubisoft's starter logs Falling back to no injecion and relaunches the game without injection (Ubisoft Game Launcher\logs\game_starter_log.txt). It is not a lost wakeup.
To confirm on AC: during a stall, journalctl -k | grep split_lock should list ACBlackFlag.exe, and /proc/<pid>/syscall should read -1 <sp> <trap address>. The pre-login CEF stall with ntsync described above looks like a separate problem; this doesn't address it.
proton experimentalx6 2026-09ge-proton11-3x1 2026-09proton hotfixx1 2026-07PROTON_NO_NTSYNC=1x4 2026-09PROTON_NO_FSYNC=1x2 2026-09PROTON_USE_NTSYNC=1x1 2026-07PROTON_ENABLE_HDR=1x1 2026-07PROTON_ENABLE_WAYLAND=1x1 2026-07PROTON_ENABLE_HDMI_HDR=1x1 2026-07PROTON_ENABLE_WAYLANDx1 2026-07PROTON_NO_NTSYNC=1`**x1 2026-07WINEFSYNC=1x1 2026-07PROTON_ENABLE_WAYLAND=1 PROTON_ENABLE_HDR=1 %command%x1 2026-07PROTON_ENABLE_HDMI_HDR=1 %command%x1 2026-07PROTON_NO_NTSYNC=1 %command%x1 2026-07
Compatibility Report
System Information
I confirm:
Symptoms
Game does not start past the Ubisoft Connect Banner ... I tried to watch the logs and it seems stuck in a loop, steam and ubisoft connect thinks the game is running.. but nothing happens!
Reproduction
Install thru steam and start the game using proton experimental
While I was debugging I attached gdb to see the issue and then the game started! I think this might be a time race conditional error.. for now, the game only starts for me if I do this!
assassins-creed-black-flag-resynced-debug-notes.md
I asked the AI to document the process for me so that anyone else can try also!
I also created a script that can help maybe... to start the game with the workaround!
acbf_resync_nudge.sh