ValveSoftware / Proton

Compatibility tool for Steam Play based on Wine and additional components
Other
23.31k stars 1.02k forks source link

Cosmoteer: Starship Architect & Commander (799600) #7514

Open delizin opened 4 months ago

delizin commented 4 months ago

Compatibility Report

System Information

I confirm:

Steam Log: steam-799600.log.tar.gz

Symptoms

The game frequently crashes to desktop with no error or will freeze when loading a game while currently in game. I reached out to the game developer who did not see any crashes reported in the game logs, just that the game was closing abruptly.

Reproduction

  1. Create a new game or load an existing game.
  2. Create a new save or quick save.
  3. Load or quick load that save while still in game until game crashes or freezes.
kisak-valve commented 4 months ago

Hello @flibitijibibo, this compatibility report might interest you. The Proton log hints towards an access violation (c0000005) in xaudio2_8 with thread 022c named FAudio_AudioClientThread.

flibitijibibo commented 4 months ago

Looks like this is in the Wine platform backend, couldn't say for sure where it is though:

https://github.com/FNA-XNA/FAudio/blob/master/src/FAudio_platform_win32.c#L155

waltdestler commented 4 months ago

Hi, I'm the dev of Cosmoteer. Feel free to reach out to me if you need any info from me or there's anything I can do to help debug/solve this issue. (Though I have little experience with Linux or Proton.)

Unrelated, there's a separate issue/regression with text rendering in Cosmoteer being ugly/aliased in Proton 8+ (looks fine on Proton 7). Should I start a new issue for that or use this issue?

kisak-valve commented 4 months ago

Hello @waltdestler, in general we're using one issue report per unofficially supported game title. This is the right place for all feedback related to the game with Proton.

waltdestler commented 4 months ago

Okay, in that case, here's more info about the issue: Cosmoteer generates its font atlases dynamically on-the-fly using Windows text rendering APIs. (Cosmoteer is written in C#/.NET using WinForms, which I think uses GDI+ under the hood, though I could be mistaken.)

On Proton 7, here's what that looks like: Proton 7 (Probably not quite as good as on Windows, but basically fine.)

But on Proton 8 or experimental, the text looks very ugly and aliased: Proton 8

Both screenshots are from my Steam Deck where I am simply toggling the Proton versions.

alasky17 commented 4 months ago

@waltdestler Thank you! We are looking into this :)

waltdestler commented 4 months ago

@waltdestler Thank you! We are looking into this :)

Thank you! Please don't hesitate to reach out to me if I can help with either of these issues.

gofman commented 4 months ago

The font regression should hopefully be fixed in the just updated Proton Experimental ([bleeding-edge] branch).

While looking at that I stomped on some crashes on the main menu (which are maybe the same ones which were originally reported in this issue, not entirely sure).

The problem I reproduced is related to IXAudio2Voice::DestroyVoice called for a subvoice which is the output for some other voice(s). Wine xaudio / faudio ended up using the voice after free in this case and corrupting memory. I fixed that in Proton Experimental ([bleeding-edge]), however, I think here is essentially game bug which leads to a memory leak whenever a voice is deleted this way (both on Windows and now in Proton [bleeding-edge] instead of crashing). MS docs [1] suggest that IXAudio2Voice::DestroyVoice fails in such a case and my unit testing shows that it is indeed the case. But then the voice is never deleted.

@waltdestler do you think it is possible to fix in game and clear the voice being deleted from the outputs of other voices before deleting it, so it is not leaked (e. g., IXAudio2Voice::SetOutputVoices with 0 SendVoices in XAUDIO2_VOICE_SENDS.SendCount will clear all the output voices)?

  1. https://learn.microsoft.com/en-us/windows/win32/api/xaudio2/nf-xaudio2-ixaudio2voice-destroyvoice
waltdestler commented 4 months ago

@gofman Are you able to provide any clues (a call stack maybe?) about where DestroyVoice is getting called? Cosmoteer caches voices and I believe should never call DestroyVoice until the player exits the whole game. To make sure, I put breakpoints everywhere I call DestroyVoice and they never get hit until the game exits.

gofman commented 4 months ago

I've recorded backtrace from such DestroyVoice (such call can be reproduced in main menu once left joystick is moved on Deck and the displayed planet changes). There are also call to DestroyVoice when going from gameplay to main menu but those are not erroneous.

4711.080:000000010801CE9D:011c:0120:trace:xaudio2:XA2SUB_DestroyVoice qqqqq addrs[0] 000000010805BE03 (C:\windows\system32\xaudio2_8.dll + 000000000001BE03).
4711.080:000000010801CE9D:011c:0120:trace:xaudio2:XA2SUB_DestroyVoice qqqqq addrs[1] 000000010801CE9D (E:\steamapps\common\Cosmoteer\Bin\SharpDX.XAudio2.dll + 000000000000CE9D).
4711.080:000000010801CE9D:011c:0120:trace:xaudio2:XA2SUB_DestroyVoice qqqqq addrs[2] 000000010484AA5A (E:\steamapps\common\Cosmoteer\Bin\HalflingPlatformWDX.dll + 000000000002AA5A).
4711.080:000000010801CE9D:011c:0120:trace:xaudio2:XA2SUB_DestroyVoice qqqqq addrs[3] 0000000103A9CBA5 (E:\steamapps\common\Cosmoteer\Bin\HalflingCore.dll + 000000000038CBA5).
4711.080:000000010801CE9D:011c:0120:trace:xaudio2:XA2SUB_DestroyVoice qqqqq addrs[4] 0000000102A4E33D (E:\steamapps\common\Cosmoteer\Bin\Cosmoteer.dll + 000000000023E33D).
4711.080:000000010801CE9D:011c:0120:trace:xaudio2:XA2SUB_DestroyVoice qqqqq addrs[5] 0000000103AA3921 (E:\steamapps\common\Cosmoteer\Bin\HalflingCore.dll + 0000000000393921).
4711.080:000000010801CE9D:011c:0120:trace:xaudio2:XA2SUB_DestroyVoice qqqqq addrs[6] 0000000103AA37EE (E:\steamapps\common\Cosmoteer\Bin\HalflingCore.dll + 00000000003937EE).
4711.080:000000010801CE9D:011c:0120:trace:xaudio2:XA2SUB_DestroyVoice qqqqq addrs[7] 0000000102CDE542 (E:\steamapps\common\Cosmoteer\Bin\Cosmoteer.dll + 00000000004CE542).
4711.080:000000010801CE9D:011c:0120:trace:xaudio2:XA2SUB_DestroyVoice qqqqq addrs[8] 00000000A2FDE090 ((unknown) + 0000000000000000).
4711.080:000000010801CE9D:011c:0120:trace:xaudio2:XA2SUB_DestroyVoice qqqqq addrs[9] 00000000A2FDDF8A ((unknown) + 0000000000000000).
4711.080:000000010801CE9D:011c:0120:trace:xaudio2:XA2SUB_DestroyVoice qqqqq addrs[10] 00000000A2FDDC27 ((unknown) + 0000000000000000).
4711.080:000000010801CE9D:011c:0120:trace:xaudio2:XA2SUB_DestroyVoice qqqqq addrs[11] 00000000A2FDCBC9 ((unknown) + 0000000000000000).
4711.080:000000010801CE9D:011c:0120:trace:xaudio2:XA2SUB_DestroyVoice qqqqq addrs[12] 00000000A2FDC5B6 ((unknown) + 0000000000000000).
4711.080:000000010801CE9D:011c:0120:trace:xaudio2:XA2SUB_DestroyVoice qqqqq addrs[13] 00000000A2FDB163 ((unknown) + 0000000000000000).
4711.080:000000010801CE9D:011c:0120:trace:xaudio2:XA2SUB_DestroyVoice qqqqq addrs[14] 000000010483128E (E:\steamapps\common\Cosmoteer\Bin\HalflingPlatformWDX.dll + 000000000001128E).
4711.080:000000010801CE9D:011c:0120:trace:xaudio2:XA2SUB_DestroyVoice qqqqq addrs[15] 0000000103AA6C5C (E:\steamapps\common\Cosmoteer\Bin\HalflingCore.dll + 0000000000396C5C).
4711.080:000000010801CE9D:011c:0120:trace:xaudio2:XA2SUB_DestroyVoice qqqqq addrs[16] 0000000102A20406 (E:\steamapps\common\Cosmoteer\Bin\Cosmoteer.dll + 0000000000210406).
4711.080:000000010801CE9D:011c:0120:trace:xaudio2:XA2SUB_DestroyVoice qqqqq addrs[17] 0000000100F8E933 (E:\steamapps\common\Cosmoteer\Bin\coreclr.dll + 000000000015E933).
4711.080:000000010801CE9D:011c:0120:trace:xaudio2:XA2SUB_DestroyVoice qqqqq addrs[18] 0000000100F1F605 (E:\steamapps\common\Cosmoteer\Bin\coreclr.dll + 00000000000EF605).
4711.080:000000010801CE9D:011c:0120:trace:xaudio2:XA2SUB_DestroyVoice qqqqq addrs[19] 0000000100F1E228 (E:\steamapps\common\Cosmoteer\Bin\coreclr.dll + 00000000000EE228).
4711.080:000000010801CE9D:011c:0120:trace:xaudio2:XA2SUB_DestroyVoice qqqqq addrs[20] 0000000100EF0F7A (E:\steamapps\common\Cosmoteer\Bin\coreclr.dll + 00000000000C0F7A).
4711.080:000000010801CE9D:011c:0120:trace:xaudio2:XA2SUB_DestroyVoice qqqqq addrs[21] 0000000100EF12D3 (E:\steamapps\common\Cosmoteer\Bin\coreclr.dll + 00000000000C12D3).
4711.080:000000010801CE9D:011c:0120:trace:xaudio2:XA2SUB_DestroyVoice qqqqq addrs[22] 0000000100EBE17E (E:\steamapps\common\Cosmoteer\Bin\coreclr.dll + 000000000008E17E).
4711.080:000000010801CE9D:011c:0120:trace:xaudio2:XA2SUB_DestroyVoice qqqqq addrs[23] 0000000100F74E88 (E:\steamapps\common\Cosmoteer\Bin\coreclr.dll + 0000000000144E88).
4711.080:000000010801CE9D:011c:0120:trace:xaudio2:XA2SUB_DestroyVoice qqqqq addrs[24] 0000000100DD9A8A (E:\steamapps\common\Cosmoteer\Bin\hostpolicy.dll + 0000000000019A8A).
4711.080:000000010801CE9D:011c:0120:trace:xaudio2:XA2SUB_DestroyVoice qqqqq addrs[25] 0000000100DD9D7C (E:\steamapps\common\Cosmoteer\Bin\hostpolicy.dll + 0000000000019D7C).
4711.080:000000010801CE9D:011c:0120:trace:xaudio2:XA2SUB_DestroyVoice qqqqq addrs[26] 0000000100DDA709 (E:\steamapps\common\Cosmoteer\Bin\hostpolicy.dll + 000000000001A709).
4711.080:000000010801CE9D:011c:0120:trace:xaudio2:XA2SUB_DestroyVoice qqqqq addrs[27] 0000000100D6B7B0 (E:\steamapps\common\Cosmoteer\Bin\hostfxr.dll + 000000000000B7B0).
4711.080:000000010801CE9D:011c:0120:trace:xaudio2:XA2SUB_DestroyVoice qqqqq addrs[28] 0000000100D6E42A (E:\steamapps\common\Cosmoteer\Bin\hostfxr.dll + 000000000000E42A).
4711.080:000000010801CE9D:011c:0120:trace:xaudio2:XA2SUB_DestroyVoice qqqqq addrs[29] 0000000100D70966 (E:\steamapps\common\Cosmoteer\Bin\hostfxr.dll + 0000000000010966).
4711.080:000000010801CE9D:011c:0120:trace:xaudio2:XA2SUB_DestroyVoice qqqqq addrs[30] 0000000100D6EA94 (E:\steamapps\common\Cosmoteer\Bin\hostfxr.dll + 000000000000EA94).
4711.080:000000010801CE9D:011c:0120:trace:xaudio2:XA2SUB_DestroyVoice qqqqq addrs[31] 0000000100D68553 (E:\steamapps\common\Cosmoteer\Bin\hostfxr.dll + 0000000000008553).
4711.080:000000010801CE9D:011c:0120:trace:xaudio2:XA2SUB_DestroyVoice qqqqq addrs[32] 0000000140012A70 (E:\steamapps\common\Cosmoteer\Bin\Cosmoteer.exe + 0000000000012A70).
4711.080:000000010801CE9D:011c:0120:trace:xaudio2:XA2SUB_DestroyVoice qqqqq addrs[33] 0000000140012DEB (E:\steamapps\common\Cosmoteer\Bin\Cosmoteer.exe + 0000000000012DEB).
4711.080:000000010801CE9D:011c:0120:trace:xaudio2:XA2SUB_DestroyVoice qqqqq addrs[34] 0000000140014298 (E:\steamapps\common\Cosmoteer\Bin\Cosmoteer.exe + 0000000000014298).
4711.080:000000010801CE9D:011c:0120:trace:xaudio2:XA2SUB_DestroyVoice qqqqq addrs[35] 000000017801476D (C:\windows\system32\kernel32.dll + 000000000001476D).
4711.080:000000010801CE9D:011c:0120:trace:xaudio2:XA2SUB_DestroyVoice qqqqq addrs[36] 000000017000F3FF (C:\windows\system32\ntdll.dll + 000000000000F3FF)

So the call to DestroyVoice and SharpDX.XAudio2.dll are not directly from game dll but are from HalflingCore / HalflingPlatformWDX while those are called from Cosmoteer.dll. This backtrace is probably not much useful beyond that as it has binary addresses through compiled managed code, I don't immediately know how to get that in terms of managed methods. It is probably possible to reverse engineer all those on the way and see what might be there exactly but it would take some time, maybe it is easier to log from game or maybe you know some way (option?) for .Net core to trigger meaningful backtrace (as simply crashing in DestroyVoice doesn't seem to yield that).

waltdestler commented 4 months ago

@gofman Ah thanks, turns out the problem is specifically when a game simulation instances switches to another instance (which is what happens when changing the title screen planet), which I simply neglected to test. Thanks for the info, should be an easy fix on my end for the next patch. (I'm a little miffed that DestroyVoice simply fails silently in that case.)

Thanks for the other fixes too!

gofman commented 4 months ago

@gofman (I'm a little miffed that DestroyVoice simply fails silently in that case.)

Well, not on Proton (until yesterday's Exp [bleeding-edge]) where it crashes loudly :)

Great that it is clear now.

waltdestler commented 4 months ago

Hmm scratch that, my code is (or at least should be) already calling SetOutputVoices with 0 voices on all "input" voices before calling DestroyVoice on the output voice. I'm guessing that's bugged somehow, but since XAudio2 provides no error or other feedback (at least on Windows), I'm not sure how to track that down.

FWIW, I also find it curious that this has not been a problem on Steam Deck (or in fact most people who play Cosmoteer via Proton).

gofman commented 4 months ago

Maybe the problematic DestroyVoice is called implicitly from within a library used? When switching instances we get DestroyVoice call but surely no SetOutputVoices before that. Also a voice being deleted may be the output for submix voice, although it is maybe not the case here.

gofman commented 4 months ago

BTW one way you can see it in Proton is to run with PROTON_LOG=+xaudio2. That will log all the xaudio calls. Or you can also use PROTON_LOG=-all,+xaudio2 to avoid all the other unrelated default logging.

waltdestler commented 4 months ago

Aha, I found the problem! The .NET wrapper library I'm using (SharpDX, which is no longer maintained but until now pretty stable/bug-free) is bugged and will no-op if SetOutputVoices is called with no output voices. Easy work-around on my end. Thanks for alerting me to this issue and helping to debug!

I'll fix this for the next public Cosmoteer patch, but let me know if you'd like me to upload the fix to a beta branch if you want to test on your end.

gofman commented 4 months ago

Sure I can check the pre-release game. Also if you can run Cosmoteer on Proton and enable default logging with PROTON_LOG=1 %command% in launch parameters, default log from Proton Experimental [bleeding-edge] will have 'err:' lines (grep err: ~/steam-799600.log) if the active voice destroy was attempted.

waltdestler commented 4 months ago

Okay I have a build with the fix up on the test branch which can be unlocked using the ultra-secure password testtesttest.

waltdestler commented 4 months ago

(Also just confirming that the text aliasing issue appears to be fixed on my Steam Deck on Experimental bleeding-edge. Thanks for that too!)

gofman commented 4 months ago

Yes did a quick try and now deleting voices when switching instances seems to go normally. It goes normally on game exit even (when previously was also showing that).

gofman commented 4 months ago

One thing to note, now it seems to set SetOutputVoices with NULL pSends. At least in our implementation (which I didn't check for this aspect but more likely it is the same on Windows) it is not exactly the same as setting with non-NULL pSends and 0 voice count. The latter removes any voices from output, the former (NULL pSends) stes the voice output to mastering voice. Which is likely fine, but I don't know all the details about the voices life in the game.

waltdestler commented 4 months ago

Yeah that's my current workaround for the SharpDX bug. I think it should be fine because the voices get stopped before SetOutputVoices is called.

waltdestler commented 3 months ago

Hi again!

Another issue that some players are reporting is that occasionally some keys (such as using WASD to pan the view around) get virtually "stuck" in the pressed state until they are physically pressed and released again. It's been reported by players with physical keyboards, and I've also personally had it happen on my Steam Deck with the thumbstick configured to emulate WASD.

It's just common enough to be annoying, but rare enough to be really hard for me to debug or figure out any kind of repro. I'm not sure how to investigate further due to my inability to consistently repro the problem. But I'm pretty confident it's a Proton issue and not a game issue because it doesn't happen on Windows.

FWIW, Cosmoteer uses the Windows raw input API to get keyboard and mouse input.

waltdestler commented 2 months ago

Here's another font rendering issue, this time with Chinese characters, some of which appear corrupted/garbled while most are fine. Here's a screenshot of what Cosmoteer looks like on Steam Deck with the language set to Chinese:

screenshot

And here's what it looks like on Windows:

image