Bug
In src/sockets/chessSockets.ts, the disconnect event handler has a logic error that causes the game outcome to always have winner: undefined when both players are offline.
Root Cause
The sequence is:
const game = gameManager.disconnect(userId); // marks current player as connected: false
if (!game.players.white?.connected && !game.players.black?.connected) {
game.outcome = {
// Both are already false at this point — ternary always returns undefined
winner: game.players.white?.connected ? 'white' : game.players.black?.connected ? 'black' : undefined,
reason: 'resignation',
};
}
After gameManager.disconnect(userId) runs, the disconnecting player is already marked connected: false. So when the both-offline check passes, both game.players.white?.connected and game.players.black?.connected are false. The winner ternary therefore always resolves to undefined.
Impact
When a player disconnects while their opponent is already disconnected (e.g. opponent dropped then this player drops before the 5-second timer fires), the game is erased with outcome = { winner: undefined, reason: 'resignation' }. No player is credited a win.
Expected Behavior
The winner should be the player who was still connected before this disconnect — i.e., the opponent of userId.
Suggested Fix
Capture the still-connected color before calling gameManager.disconnect, or derive the winner from userId directly:
const playerColor = /* derive from game before disconnect */;
const game = gameManager.disconnect(userId);
if (!game.players.white?.connected && !game.players.black?.connected) {
const winnerColor = playerColor === 'white' ? 'black' : 'white';
game.outcome = {
winner: game.players[winnerColor] ? winnerColor : undefined,
reason: 'resignation',
};
}
Related
The existing getPlayerColor private method on GameManager could expose this info, but it's currently private. Alternatively, the socket layer could determine the disconnecting player's color before calling disconnect.
Bug
In
src/sockets/chessSockets.ts, thedisconnectevent handler has a logic error that causes the game outcome to always havewinner: undefinedwhen both players are offline.Root Cause
The sequence is:
After
gameManager.disconnect(userId)runs, the disconnecting player is already markedconnected: false. So when the both-offline check passes, bothgame.players.white?.connectedandgame.players.black?.connectedarefalse. The winner ternary therefore always resolves toundefined.Impact
When a player disconnects while their opponent is already disconnected (e.g. opponent dropped then this player drops before the 5-second timer fires), the game is erased with
outcome = { winner: undefined, reason: 'resignation' }. No player is credited a win.Expected Behavior
The winner should be the player who was still connected before this disconnect — i.e., the opponent of
userId.Suggested Fix
Capture the still-connected color before calling
gameManager.disconnect, or derive the winner fromuserIddirectly:Related
The existing
getPlayerColorprivate method onGameManagercould expose this info, but it's currently private. Alternatively, the socket layer could determine the disconnecting player's color before callingdisconnect.