gameboy_worlds.emulation.deja_vu.emulators
1from gameboy_worlds.emulation.emulator import Emulator, LowLevelActions 2from gameboy_worlds.emulation.deja_vu.parsers import DejaVuStateParser, AgentState 3from gameboy_worlds.emulation.deja_vu.trackers import CoreDejaVuTracker 4from gameboy_worlds.utils import log_error 5from typing import Tuple 6import numpy as np 7 8 9class DejaVuEmulator(Emulator): 10 """ 11 Deja Vu-specific emulator adapter. 12 13 Handles Deja Vu game-specific logic: 14 - Menu navigation and investigation system 15 - Dialogue and clue collection 16 - Puzzle-solving phases 17 """ 18 19 REQUIRED_STATE_PARSER = DejaVuStateParser 20 REQUIRED_STATE_TRACKER = CoreDejaVuTracker 21 _MAXIMUM_DIALOGUE_PRESSES = 2000 # For now set a crazy high value 22 """ Maximum number of times the agent will click B to get through a dialogue. """ 23 _SKIP_DIALOGUE = False 24 """ Whether to auto skip dialogue by clicking B repeatedly until we are no longer in dialogue.""" 25 26 def step(self, action=None) -> Tuple[np.ndarray, bool]: 27 """ 28 Execute one game step with Deja Vu-specific handling. 29 30 Handles dialogue auto-skip to speed up gameplay while preserving investigation mechanics. 31 32 Args: 33 action: The action to execute (can be None for no action) 34 35 Returns: 36 Tuple of (frames, done): frames from the step, and whether episode ended 37 """ 38 frames, done = super().step(action) 39 self.state_parser: DejaVuStateParser 40 current_frame = self.get_current_frame() 41 42 all_next_frames = [frames] 43 if self._SKIP_DIALOGUE: 44 # Auto-skip dialogue to accelerate game progression 45 # This allows the agent to move through story elements faster 46 # For Deja Vu, dialogue is critical to story progression and investigations, so we initialize the auto-skip action to false 47 current_state = self.state_parser.get_agent_state(current_frame) 48 n_clicks = 0 49 # Clicks through any dialogue popups 50 while ( 51 n_clicks < self._MAXIMUM_DIALOGUE_PRESSES 52 and current_state == AgentState.IN_DIALOGUE 53 ): 54 next_frames = self.run_action_on_emulator( 55 LowLevelActions.PRESS_BUTTON_A 56 ) 57 current_state = self.state_parser.get_agent_state(next_frames[-1]) 58 all_next_frames.append(next_frames) 59 n_clicks += 1 60 61 if len(all_next_frames) > 1: 62 frames = np.concatenate(all_next_frames) 63 self._update_listeners_after_actions( 64 self._get_unique_frames(frames[1:]) 65 ) # Skip the first frame as that is already counted 66 frames = self._get_unique_frames(frames) 67 68 return frames, done 69 70 def _open_to_first_state(self): 71 self._pyboy.tick(10000, False) # get to opening menu 72 self.run_action_on_emulator( 73 LowLevelActions.PRESS_BUTTON_A 74 ) # press A to get past opening menu 75 self._pyboy.tick(1000, False) # wait for load 76 self.run_action_on_emulator( 77 LowLevelActions.PRESS_BUTTON_A 78 ) # press A to load game 79 self._pyboy.tick(1000, False) # wait for file select 80 self.run_action_on_emulator( 81 LowLevelActions.PRESS_BUTTON_A 82 ) # press A to confirm load 83 self._pyboy.tick(5000, False) # wait for game to load
10class DejaVuEmulator(Emulator): 11 """ 12 Deja Vu-specific emulator adapter. 13 14 Handles Deja Vu game-specific logic: 15 - Menu navigation and investigation system 16 - Dialogue and clue collection 17 - Puzzle-solving phases 18 """ 19 20 REQUIRED_STATE_PARSER = DejaVuStateParser 21 REQUIRED_STATE_TRACKER = CoreDejaVuTracker 22 _MAXIMUM_DIALOGUE_PRESSES = 2000 # For now set a crazy high value 23 """ Maximum number of times the agent will click B to get through a dialogue. """ 24 _SKIP_DIALOGUE = False 25 """ Whether to auto skip dialogue by clicking B repeatedly until we are no longer in dialogue.""" 26 27 def step(self, action=None) -> Tuple[np.ndarray, bool]: 28 """ 29 Execute one game step with Deja Vu-specific handling. 30 31 Handles dialogue auto-skip to speed up gameplay while preserving investigation mechanics. 32 33 Args: 34 action: The action to execute (can be None for no action) 35 36 Returns: 37 Tuple of (frames, done): frames from the step, and whether episode ended 38 """ 39 frames, done = super().step(action) 40 self.state_parser: DejaVuStateParser 41 current_frame = self.get_current_frame() 42 43 all_next_frames = [frames] 44 if self._SKIP_DIALOGUE: 45 # Auto-skip dialogue to accelerate game progression 46 # This allows the agent to move through story elements faster 47 # For Deja Vu, dialogue is critical to story progression and investigations, so we initialize the auto-skip action to false 48 current_state = self.state_parser.get_agent_state(current_frame) 49 n_clicks = 0 50 # Clicks through any dialogue popups 51 while ( 52 n_clicks < self._MAXIMUM_DIALOGUE_PRESSES 53 and current_state == AgentState.IN_DIALOGUE 54 ): 55 next_frames = self.run_action_on_emulator( 56 LowLevelActions.PRESS_BUTTON_A 57 ) 58 current_state = self.state_parser.get_agent_state(next_frames[-1]) 59 all_next_frames.append(next_frames) 60 n_clicks += 1 61 62 if len(all_next_frames) > 1: 63 frames = np.concatenate(all_next_frames) 64 self._update_listeners_after_actions( 65 self._get_unique_frames(frames[1:]) 66 ) # Skip the first frame as that is already counted 67 frames = self._get_unique_frames(frames) 68 69 return frames, done 70 71 def _open_to_first_state(self): 72 self._pyboy.tick(10000, False) # get to opening menu 73 self.run_action_on_emulator( 74 LowLevelActions.PRESS_BUTTON_A 75 ) # press A to get past opening menu 76 self._pyboy.tick(1000, False) # wait for load 77 self.run_action_on_emulator( 78 LowLevelActions.PRESS_BUTTON_A 79 ) # press A to load game 80 self._pyboy.tick(1000, False) # wait for file select 81 self.run_action_on_emulator( 82 LowLevelActions.PRESS_BUTTON_A 83 ) # press A to confirm load 84 self._pyboy.tick(5000, False) # wait for game to load
Deja Vu-specific emulator adapter.
Handles Deja Vu game-specific logic:
- Menu navigation and investigation system
- Dialogue and clue collection
- Puzzle-solving phases
REQUIRED_STATE_PARSER =
<class 'gameboy_worlds.emulation.deja_vu.parsers.DejaVuStateParser'>
The minimal functionality StateParser needed for this emulator to run
REQUIRED_STATE_TRACKER =
<class 'gameboy_worlds.emulation.deja_vu.trackers.CoreDejaVuTracker'>
The minimal functionality StateTracker needed for this emulator to run
def
step(self, action=None) -> Tuple[numpy.ndarray, bool]:
27 def step(self, action=None) -> Tuple[np.ndarray, bool]: 28 """ 29 Execute one game step with Deja Vu-specific handling. 30 31 Handles dialogue auto-skip to speed up gameplay while preserving investigation mechanics. 32 33 Args: 34 action: The action to execute (can be None for no action) 35 36 Returns: 37 Tuple of (frames, done): frames from the step, and whether episode ended 38 """ 39 frames, done = super().step(action) 40 self.state_parser: DejaVuStateParser 41 current_frame = self.get_current_frame() 42 43 all_next_frames = [frames] 44 if self._SKIP_DIALOGUE: 45 # Auto-skip dialogue to accelerate game progression 46 # This allows the agent to move through story elements faster 47 # For Deja Vu, dialogue is critical to story progression and investigations, so we initialize the auto-skip action to false 48 current_state = self.state_parser.get_agent_state(current_frame) 49 n_clicks = 0 50 # Clicks through any dialogue popups 51 while ( 52 n_clicks < self._MAXIMUM_DIALOGUE_PRESSES 53 and current_state == AgentState.IN_DIALOGUE 54 ): 55 next_frames = self.run_action_on_emulator( 56 LowLevelActions.PRESS_BUTTON_A 57 ) 58 current_state = self.state_parser.get_agent_state(next_frames[-1]) 59 all_next_frames.append(next_frames) 60 n_clicks += 1 61 62 if len(all_next_frames) > 1: 63 frames = np.concatenate(all_next_frames) 64 self._update_listeners_after_actions( 65 self._get_unique_frames(frames[1:]) 66 ) # Skip the first frame as that is already counted 67 frames = self._get_unique_frames(frames) 68 69 return frames, done
Execute one game step with Deja Vu-specific handling.
Handles dialogue auto-skip to speed up gameplay while preserving investigation mechanics.
Arguments:
- action: The action to execute (can be None for no action)
Returns:
Tuple of (frames, done): frames from the step, and whether episode ended
Inherited Members
- gameboy_worlds.emulation.emulator.Emulator
- Emulator
- game
- headless
- max_steps
- session_path
- wait_ticks
- press_step
- render_headless
- reset_count
- step_count
- screen_shape
- save_video
- video_writer
- state_parser
- state_tracker
- create_first_state
- set_init_state
- reset
- get_current_frame
- get_state_parser
- run_action_on_emulator
- check_if_done
- close
- human_play
- random_play
- save_state
- delete_state
- get_env_variant