What happens: a player joins a lobby, the fullscreen loader appears and never goes away. Worse, from that point on every further join attempt is silently ignored for the rest of the session, so the player has to reload the page.
Why: after sending the joinGame message, the client waits for a peerId message with no timeout. The TODO in the code already describes exactly this case:
|
// TODO: When the message is sent, it is expected to then receive a "peerId" message |
|
// from the websocket. This "peerId" message might not be sent for different reasons. |
|
// Should there be a security that checks if the "peerId" message has been received |
|
// in the next 10s or something more global that checks the lobby status after the player |
|
// has committed to open a connection with it? |
If peerId never arrives, onLobbyQuickJoinFinished is never called, so the loader is never hidden and _isQuickJoiningOrStartingAGame stays true — which makes both quickJoinLobby and quickJoinWithLobbyID return early forever. Every other failure path calls onLobbyQuickJoinFinished; this one has no exit at all.
The game cannot even detect it: IsSearchingForLobbyToJoin returns that same flag, so it stays true and no condition distinguishes "connecting" from "stuck".
Suggested fix: time out the wait for peerId (the ~10s the TODO suggests) and call onLobbyQuickJoinFinished with a new QuickJoinFailureReason such as TIMEOUT, so QuickJoinJustFailed fires and the player can retry.
Workaround, for reference: count the seconds spent with IsSearchingForLobbyToJoin true and past ~8s run
try { gdjs.multiplayerComponents.displayLoader(runtimeScene, false); } catch (e) {}
try { gdjs.multiplayerPeerJsHelper.connect('join-recovery-probe-' + Date.now()); } catch (e) {}
The failed connection raises peer-unavailable and reaches onPeerUnavailable, the only path that clears the flag without reloading the page. It works, but it depends entirely on private internals.
Reproduces intermittently on gd.games. GDevelop version: 5.6.0 (build 277). Line numbers refer to commit 1a0661d.
What happens: a player joins a lobby, the fullscreen loader appears and never goes away. Worse, from that point on every further join attempt is silently ignored for the rest of the session, so the player has to reload the page.
Why: after sending the
joinGamemessage, the client waits for apeerIdmessage with no timeout. TheTODOin the code already describes exactly this case:GDevelop/Extensions/Multiplayer/multiplayertools.ts
Lines 1097 to 1101 in 1a0661d
If
peerIdnever arrives,onLobbyQuickJoinFinishedis never called, so the loader is never hidden and_isQuickJoiningOrStartingAGamestaystrue— which makes bothquickJoinLobbyandquickJoinWithLobbyIDreturn early forever. Every other failure path callsonLobbyQuickJoinFinished; this one has no exit at all.The game cannot even detect it:
IsSearchingForLobbyToJoinreturns that same flag, so it stays true and no condition distinguishes "connecting" from "stuck".Suggested fix: time out the wait for
peerId(the ~10s the TODO suggests) and callonLobbyQuickJoinFinishedwith a newQuickJoinFailureReasonsuch asTIMEOUT, soQuickJoinJustFailedfires and the player can retry.Workaround, for reference: count the seconds spent with
IsSearchingForLobbyToJointrue and past ~8s runThe failed connection raises
peer-unavailableand reachesonPeerUnavailable, the only path that clears the flag without reloading the page. It works, but it depends entirely on private internals.Reproduces intermittently on gd.games. GDevelop version: 5.6.0 (build 277). Line numbers refer to commit
1a0661d.