@@ -90,6 +90,7 @@ export default class Game {
9090 eloChanges : this . eloChanges ,
9191 pIds : this . pIds ,
9292 accountIds : this . accountIds ,
93+ oldElos : this . oldElos ,
9394 gameCount : this . gameCount ,
9495 location : this . location ,
9596 saveInProgress : this . saveInProgress ,
@@ -414,7 +415,6 @@ export default class Game {
414415 // For ranked duels: if someone leaves during "getready" (countdown before first round),
415416 // cancel the game without ELO penalties - no actual gameplay has happened yet
416417 const isPreGameLeave = this . public && this . duel && this . state === 'getready' ;
417-
418418 // Track disconnection for ranked duels (only if actual gameplay has started)
419419 if ( this . public && this . duel && ! isPreGameLeave ) {
420420 this . disconnectedPlayer = tag ;
@@ -462,7 +462,7 @@ export default class Game {
462462 console . log ( 'Cannot start game: not in waiting state' , this . state ) ;
463463 return ;
464464 }
465-
465+
466466 if ( Object . keys ( this . players ) . length < 2 ) {
467467 console . log ( 'Cannot start game: not enough players' , Object . keys ( this . players ) . length ) ;
468468 if ( hostPlayer ) {
@@ -474,7 +474,7 @@ export default class Game {
474474 }
475475 return ;
476476 }
477-
477+
478478 if ( this . rounds !== this . locations . length ) {
479479 console . log ( 'Cannot start game: locations not loaded' , this . rounds , this . locations . length ) ;
480480 if ( hostPlayer ) {
@@ -773,22 +773,19 @@ export default class Game {
773773 }
774774
775775
776-
777776
778- // let p1OldElo = p1obj?.elo || null;
779- // let p2OldElo = p2obj?.elo || null;
780-
781- // get both players old elo from the database
782777 const p1EloResult = await User . findById ( this . accountIds . p1 ) . select ( 'elo' ) . lean ( ) ;
783778 const p2EloResult = await User . findById ( this . accountIds . p2 ) . select ( 'elo' ) . lean ( ) ;
784779
785- let p1OldElo = p1EloResult ?. elo ?? null ;
786- let p2OldElo = p2EloResult ?. elo ?? null ;
780+ // Use DB value if available, otherwise fall back to stored oldElos from game creation
781+ // This prevents null ELO bugs while still handling external ELO updates
782+ let p1OldElo = p1EloResult ?. elo ?? this . oldElos ?. p1 ?? null ;
783+ let p2OldElo = p2EloResult ?. elo ?? this . oldElos ?. p2 ?? null ;
787784
788785 let p1NewElo = p1OldElo ;
789786 let p2NewElo = p2OldElo ;
790787 // elo changes
791- if ( this . eloChanges ) {
788+ if ( this . eloChanges && p1OldElo && p2OldElo ) {
792789 if ( draw ) {
793790
794791 const changes = this . eloChanges . draw ;
@@ -860,7 +857,7 @@ export default class Game {
860857 }
861858
862859 // Save duel game to MongoDB for history tracking
863- if ( this . duel && this . accountIds ?. p1 && this . accountIds ?. p2 ) {
860+ if ( this . duel && this . accountIds ?. p1 && this . accountIds ?. p2 && p1OldElo && p2OldElo ) {
864861 this . saveInProgress = true ;
865862 const p1Xp = this . calculatePlayerXp ( this . pIds ?. p1 ) ;
866863 const p2Xp = this . calculatePlayerXp ( this . pIds ?. p2 ) ;
@@ -1136,7 +1133,7 @@ export default class Game {
11361133 // Create player summaries sorted by total points (highest first) - include ALL players
11371134 // Calculate XP for public games only (not parties), and only for registered users (not guests)
11381135 const awardXp = this . public ;
1139-
1136+
11401137 const playerSummaries = allPlayers
11411138 . map ( player => {
11421139 const playerXp = ( awardXp && player . accountId ) ? this . calculatePlayerXp ( player . id ) : 0 ;
0 commit comments