diff --git a/backend/app/core/game_engine.py b/backend/app/core/game_engine.py index 8468400..5d8b8a2 100644 --- a/backend/app/core/game_engine.py +++ b/backend/app/core/game_engine.py @@ -989,11 +989,10 @@ class GameEngine: if state.on_third: state.current_on_base_code |= 4 # Bit 2: third base - logger.debug( - f"Prepared next play: batter={state.current_batter.lineup_id}, " - f"pitcher={state.current_pitcher.lineup_id if state.current_pitcher else None}, " - f"catcher={state.current_catcher.lineup_id if state.current_catcher else None}, " - f"on_base_code={state.current_on_base_code}" + logger.info( + f"Prepared next play: batter lineup_id={state.current_batter.lineup_id}, " + f"batting_order={state.current_batter.batting_order}, " + f"pitcher={state.current_pitcher.lineup_id if state.current_pitcher else None}" ) async def _batch_save_inning_rolls(self, game_id: UUID) -> None: diff --git a/backend/app/websocket/handlers.py b/backend/app/websocket/handlers.py index 3a69587..e063bb8 100644 --- a/backend/app/websocket/handlers.py +++ b/backend/app/websocket/handlers.py @@ -546,9 +546,14 @@ def register_handlers(sio: AsyncServer, manager: ConnectionManager) -> None: hit_location=submission.hit_location, ) - # Clear pending roll only AFTER successful validation (one-time use) - state.pending_manual_roll = None - state_manager.update_state(game_id, state) + # CRITICAL: Re-fetch state AFTER resolve_manual_play completes + # The game engine updates state (advances batter, etc.) during resolution. + # Using the old state reference would overwrite those updates! + state = state_manager.get_state(game_id) + if state: + # Clear pending roll only AFTER successful validation (one-time use) + state.pending_manual_roll = None + state_manager.update_state(game_id, state) except GameValidationError as e: # Game engine validation error (e.g., missing hit location) await manager.emit_to_user(