fix(memory-quiz): fix playMode persistence by updating validator

ROOT CAUSE FOUND:
The MemoryQuizGameValidator.getInitialState() method was hardcoding
playMode to 'cooperative' and not accepting it as a config parameter.

Even though socket-server.ts was passing playMode from the saved config,
the validator's TypeScript signature didn't include it:

BEFORE:
```typescript
getInitialState(config: {
  selectedCount: number
  displayTime: number
  selectedDifficulty: DifficultyLevel
}): SorobanQuizState {
  return {
    // ...
    playMode: 'cooperative',  // ← ALWAYS HARDCODED!
  }
}
```

AFTER:
```typescript
getInitialState(config: {
  selectedCount: number
  displayTime: number
  selectedDifficulty: DifficultyLevel
  playMode?: 'cooperative' | 'competitive'  // ← NEW!
}): SorobanQuizState {
  return {
    // ...
    playMode: config.playMode || 'cooperative',  // ← USES CONFIG VALUE!
  }
}
```

Also added comprehensive debug logging throughout the flow:
- socket-server.ts: logs room.gameConfig, extracted config, and resulting playMode
- RoomMemoryQuizProvider.tsx: logs roomData.gameConfig and merged state
- MemoryQuizGameValidator.ts: logs config received and playMode returned

This will help identify any remaining persistence issues.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Thomas Hallock
2025-10-15 12:50:19 -05:00
parent c9e5c473e6
commit de0efd5932
3 changed files with 77 additions and 14 deletions

View File

@@ -210,19 +210,32 @@ export function RoomMemoryQuizProvider({ children }: { children: ReactNode }) {
// Settings are scoped by game name to preserve settings when switching games
const mergedInitialState = useMemo(() => {
const gameConfig = roomData?.gameConfig as Record<string, any> | null | undefined
console.log('[RoomMemoryQuizProvider] Initializing - gameConfig:', gameConfig)
console.log(
'[RoomMemoryQuizProvider] Initializing - Full roomData.gameConfig:',
JSON.stringify(gameConfig, null, 2)
)
if (!gameConfig) {
console.log('[RoomMemoryQuizProvider] No gameConfig, using initialState')
console.log(
'[RoomMemoryQuizProvider] No gameConfig, using initialState with playMode:',
initialState.playMode
)
return initialState
}
// Get settings for this specific game (memory-quiz)
const savedConfig = gameConfig['memory-quiz'] as Record<string, any> | null | undefined
console.log('[RoomMemoryQuizProvider] Loading saved config for memory-quiz:', savedConfig)
console.log(
'[RoomMemoryQuizProvider] Extracted memory-quiz config:',
JSON.stringify(savedConfig, null, 2)
)
console.log('[RoomMemoryQuizProvider] savedConfig.playMode value:', savedConfig?.playMode)
if (!savedConfig) {
console.log('[RoomMemoryQuizProvider] No saved config for memory-quiz, using initialState')
console.log(
'[RoomMemoryQuizProvider] No saved config for memory-quiz, using initialState with playMode:',
initialState.playMode
)
return initialState
}
@@ -234,12 +247,20 @@ export function RoomMemoryQuizProvider({ children }: { children: ReactNode }) {
selectedDifficulty: savedConfig.selectedDifficulty ?? initialState.selectedDifficulty,
playMode: savedConfig.playMode ?? initialState.playMode,
}
console.log('[RoomMemoryQuizProvider] Merged state:', {
selectedCount: merged.selectedCount,
displayTime: merged.displayTime,
selectedDifficulty: merged.selectedDifficulty,
playMode: merged.playMode,
})
console.log(
'[RoomMemoryQuizProvider] Merged state:',
JSON.stringify(
{
selectedCount: merged.selectedCount,
displayTime: merged.displayTime,
selectedDifficulty: merged.selectedDifficulty,
playMode: merged.playMode,
},
null,
2
)
)
console.log('[RoomMemoryQuizProvider] Final merged.playMode:', merged.playMode)
return merged
}, [roomData?.gameConfig])

View File

@@ -405,8 +405,14 @@ export class MemoryQuizGameValidator
selectedCount: number
displayTime: number
selectedDifficulty: DifficultyLevel
playMode?: 'cooperative' | 'competitive'
}): SorobanQuizState {
return {
console.log(
'[MemoryQuizValidator] getInitialState called with config:',
JSON.stringify(config, null, 2)
)
const initialState: SorobanQuizState = {
cards: [],
quizCards: [],
correctAnswers: [],
@@ -422,7 +428,7 @@ export class MemoryQuizGameValidator
activePlayers: [],
playerMetadata: {},
playerScores: {},
playMode: 'cooperative',
playMode: config.playMode || 'cooperative',
numberFoundBy: {},
// UI state
gamePhase: 'setup',
@@ -433,6 +439,9 @@ export class MemoryQuizGameValidator
testingMode: false,
showOnScreenKeyboard: false,
}
console.log('[MemoryQuizValidator] getInitialState returning playMode:', initialState.playMode)
return initialState
}
}

View File

@@ -94,12 +94,35 @@ export function initializeSocketServer(httpServer: HTTPServer) {
} else if (room.gameName === 'memory-quiz') {
// Access nested gameConfig: { 'memory-quiz': { selectedCount, displayTime, selectedDifficulty, playMode } }
const memoryQuizConfig = (room.gameConfig as any)?.['memory-quiz'] || {}
initialState = validator.getInitialState({
console.log(
'[join-arcade-session] memory-quiz - Full room.gameConfig:',
JSON.stringify(room.gameConfig, null, 2)
)
console.log(
'[join-arcade-session] memory-quiz - Extracted memoryQuizConfig:',
JSON.stringify(memoryQuizConfig, null, 2)
)
console.log(
'[join-arcade-session] memory-quiz - playMode from config:',
memoryQuizConfig.playMode
)
const configToPass = {
selectedCount: memoryQuizConfig.selectedCount || 5,
displayTime: memoryQuizConfig.displayTime || 2.0,
selectedDifficulty: memoryQuizConfig.selectedDifficulty || 'easy',
playMode: memoryQuizConfig.playMode || 'cooperative',
})
}
console.log(
'[join-arcade-session] memory-quiz - Config being passed to getInitialState:',
JSON.stringify(configToPass, null, 2)
)
initialState = validator.getInitialState(configToPass)
console.log(
'[join-arcade-session] memory-quiz - initialState.playMode after getInitialState:',
initialState.playMode
)
} else {
// Fallback for other games
initialState = validator.getInitialState(room.gameConfig || {})
@@ -129,7 +152,17 @@ export function initializeSocketServer(httpServer: HTTPServer) {
roomId,
version: session.version,
sessionUserId: session.userId,
gameName: session.currentGame,
})
// Log playMode specifically for memory-quiz
if (session.currentGame === 'memory-quiz') {
console.log(
'[join-arcade-session] memory-quiz session - gameState.playMode:',
(session.gameState as any).playMode
)
}
socket.emit('session-state', {
gameState: session.gameState,
currentGame: session.currentGame,