Summary
RitsuLib v0.2.31 crashes Slay the Spire 2 when entering Multiplayer -> Host -> Standard on Linux/Steam. I narrowed the native crash to the Steam lobby capability route, specifically the call to SteamMatchmaking.SetLobbyMemberData(...) through RitsuLibSteamworks.TrySetLobbyMemberData(...).
Environment
- Game: Slay the Spire 2
v0.103.2
- RitsuLib affected version:
v0.2.31
- Last tested working RitsuLib version:
v0.2.26
- Platform: Linux, Steam build
- Route:
Multiplayer -> Host -> Standard
Reproduction
- Install
RitsuLib v0.2.31.
- Launch the game through Steam on Linux.
- Navigate to
Multiplayer -> Host -> Standard.
- The game crashes with SIGSEGV shortly after Steam host initialization.
I also reproduced this with only RitsuLib enabled, so it does not appear to require another mod using RitsuLib.
Observed Logs
The official v0.2.31 crash stops after Steam host initialization and before RitsuLib logs the sidecar session as bound:
[INFO] [SteamHost] Initializing Steam host. Our player id: <steam_id>
Diagnostic Narrowing
I built a few local diagnostic variants from v0.2.31:
- Force
RitsuLibMobileSteamRuntime.SuppressNativeSteamIntegration => true: no crash.
- Skip only
RitsuLibSidecarNativeTrailerSteamSendPatch: still crashes.
- Skip only
RitsuLibSidecarSteamLobbyValidationRoute: no crash.
- Instrument
RitsuLibSidecarSteamLobbyValidationRoute: crash occurs after the marker immediately before TrySetLobbyMemberData, with no matching after-marker.
Instrumented crash boundary:
[INFO] [SteamHost] Initializing Steam host. Our player id: <steam_id>
[INFO] [com.ritsukage.sts2-RitsuLib] [SteamLobbyRouteDiag] IsAvailable enter
[INFO] [com.ritsukage.sts2-RitsuLib] [SteamLobbyRouteDiag] IsAvailable before GetRawLobbyIdentifier
[INFO] [com.ritsukage.sts2-RitsuLib] [SteamLobbyRouteDiag] IsAvailable before TryGetNumLobbyMembers lobby=<lobby_id>
[INFO] [com.ritsukage.sts2-RitsuLib] [SteamLobbyRouteDiag] IsAvailable after TryGetNumLobbyMembers count=1
[INFO] [com.ritsukage.sts2-RitsuLib] [SteamLobbyRouteDiag] IsAvailable before TryLobbyContainsMember lobby=<lobby_id> member=<steam_id>
[INFO] [com.ritsukage.sts2-RitsuLib] [SteamLobbyRouteDiag] PublishLocalEvidence enter
[INFO] [com.ritsukage.sts2-RitsuLib] [SteamLobbyRouteDiag] TryReadSteamLobbyId before GetRawLobbyIdentifier
[INFO] [com.ritsukage.sts2-RitsuLib] [SteamLobbyRouteDiag] TryReadSteamLobbyId before TryGetNumLobbyMembers lobby=<lobby_id>
[INFO] [com.ritsukage.sts2-RitsuLib] [SteamLobbyRouteDiag] PublishLocalEvidence before TrySetLobbyMemberData lobby=<lobby_id>
Then I tested one more diagnostic build that changed only PublishLocalEvidence to skip the SetLobbyMemberData write. That did not crash and reached the hosted lobby:
[INFO] [SteamHost] Initializing Steam host. Our player id: <steam_id>
[INFO] [com.ritsukage.sts2-RitsuLib] [SteamLobbyRouteDiag] Diagnostic build: skipping SetLobbyMemberData lobby=<lobby_id>
[INFO] [com.ritsukage.sts2-RitsuLib] [Sidecar] Session bound epoch=1, netType=Host, netId=<steam_id>
[INFO] [RMP:HostBootstrap] Hosted Standard lobby via Steam with capacity 16.
Suspected Regression Area
The relevant change appears to be in the Steam integration refactor included in v0.2.31, especially commit:
0086578 feat(Steam Integration): refactor Steam-related functionality and update dependencies
That adds Platform/Steam/RitsuLibSteamworks.cs and changes RitsuLibSidecarSteamLobbyValidationRoute to use the reflection wrapper for lobby operations.
Current Hypothesis
The SIGSEGV is caused by the reflected SteamMatchmaking.SetLobbyMemberData(...) call in RitsuLibSteamworks.TrySetLobbyMemberData(...) on Linux/Steam in this game context. Managed try/catch does not catch it because the crash is native.
A possible mitigation may be to avoid the Steam lobby member-data write on affected platforms/hosts, or gate it behind an availability check that proves this specific call is safe, while keeping the other sidecar validation routes available.
Summary
RitsuLibv0.2.31crashes Slay the Spire 2 when enteringMultiplayer -> Host -> Standardon Linux/Steam. I narrowed the native crash to the Steam lobby capability route, specifically the call toSteamMatchmaking.SetLobbyMemberData(...)throughRitsuLibSteamworks.TrySetLobbyMemberData(...).Environment
v0.103.2v0.2.31v0.2.26Multiplayer -> Host -> StandardReproduction
RitsuLib v0.2.31.Multiplayer -> Host -> Standard.I also reproduced this with only RitsuLib enabled, so it does not appear to require another mod using RitsuLib.
Observed Logs
The official
v0.2.31crash stops after Steam host initialization and before RitsuLib logs the sidecar session as bound:Diagnostic Narrowing
I built a few local diagnostic variants from
v0.2.31:RitsuLibMobileSteamRuntime.SuppressNativeSteamIntegration => true: no crash.RitsuLibSidecarNativeTrailerSteamSendPatch: still crashes.RitsuLibSidecarSteamLobbyValidationRoute: no crash.RitsuLibSidecarSteamLobbyValidationRoute: crash occurs after the marker immediately beforeTrySetLobbyMemberData, with no matching after-marker.Instrumented crash boundary:
Then I tested one more diagnostic build that changed only
PublishLocalEvidenceto skip theSetLobbyMemberDatawrite. That did not crash and reached the hosted lobby:Suspected Regression Area
The relevant change appears to be in the Steam integration refactor included in
v0.2.31, especially commit:That adds
Platform/Steam/RitsuLibSteamworks.csand changesRitsuLibSidecarSteamLobbyValidationRouteto use the reflection wrapper for lobby operations.Current Hypothesis
The SIGSEGV is caused by the reflected
SteamMatchmaking.SetLobbyMemberData(...)call inRitsuLibSteamworks.TrySetLobbyMemberData(...)on Linux/Steam in this game context. Managedtry/catchdoes not catch it because the crash is native.A possible mitigation may be to avoid the Steam lobby member-data write on affected platforms/hosts, or gate it behind an availability check that proves this specific call is safe, while keeping the other sidecar validation routes available.