def _grade_exercise(setup_manager: SetupManager, ex: Exercise, seed: int) -> Result: grade = None rate_limit = rate_limiter.RateLimiter(120) metadata_ticker = rate_limiter.RateLimiter(2) game_interface = setup_manager.game_interface game_tick_packet = GameTickPacket( ) # We want to do a deep copy for game inputs so people don't mess with em # Run until the Exercise finishes. while grade is None: # Read from game data shared memory game_interface.update_live_data_packet(game_tick_packet) try: grade = ex.on_tick(game_tick_packet) ex.render(game_interface.renderer) if metadata_ticker.acquire_if_ready(): # Check for agent metadata regularly. Ensures bots are properly started, # constrained to certain CPU cores, and run at high process priority. # This mimics what RLBotGUI does during a match. setup_manager.try_recieve_agent_metadata() except Exception as e: return Result( ex, seed, FailDueToExerciseException(e, traceback.format_exc())) rate_limit.acquire() return Result(ex, seed, grade)
def _grade_exercise(game_interface: GameInterface, ex: Exercise, seed: int) -> Result: grade = None rate_limit = rate_limiter.RateLimiter(120) last_tick_game_time = None # What the tick time of the last observed tick was game_tick_packet = GameTickPacket() # We want to do a deep copy for game inputs so people don't mess with em # Run until the Exercise finishes. while grade is None: # Read from game data shared memory game_interface.update_live_data_packet(game_tick_packet) # Run ex.on_tick() only if the game_info has updated. tick_game_time = game_tick_packet.game_info.seconds_elapsed if tick_game_time != last_tick_game_time: last_tick_game_time = tick_game_time try: grade = ex.on_tick(game_tick_packet) ex.render(game_interface.renderer) except Exception as e: return Result(ex, seed, FailDueToExerciseException(e, traceback.format_exc())) rate_limit.acquire() return Result(ex, seed, grade)
def __init__(self): self.logger = get_logger('packet reader') self.game_interface = GameInterface(self.logger) self.game_interface.inject_dll() self.game_interface.load_interface() self.game_tick_packet = game_data_struct.GameTickPacket() self.rate_limit = rate_limiter.RateLimiter(GAME_TICK_PACKET_REFRESHES_PER_SECOND) self.last_call_real_time = datetime.now() # When we last called the Agent
def run(self): """ Loads interface for RLBot, prepares environment and agent, and calls the update for the agent. """ self.logger.debug('initializing agent') self.game_interface.load_interface() self.prepare_for_run() # Create Ratelimiter rate_limit = rate_limiter.RateLimiter( GAME_TICK_PACKET_POLLS_PER_SECOND) last_tick_game_time = 0 # What the tick time of the last observed tick was last_call_real_time = datetime.now() # When we last called the Agent frame_urgency = 0 # If the bot is getting called more than its preferred max rate, urgency will go negative. # Get bot module self.load_agent() self.last_module_modification_time = self.check_modification_time( os.path.dirname(self.agent_class_file)) # Run until main process tells to stop, or we detect Ctrl+C try: while not self.terminate_request_event.is_set(): self.pull_data_from_game() # game_tick_packet = self.game_interface.get # Read from game data shared memory # Run the Agent only if the game_info has updated. tick_game_time = self.get_game_time() now = datetime.now() should_call_while_paused = now - last_call_real_time >= MAX_AGENT_CALL_PERIOD if frame_urgency < 4 / self.maximum_tick_rate_preference: # Urgency increases every frame, but don't let it build up a large backlog frame_urgency += tick_game_time - last_tick_game_time if (tick_game_time != last_tick_game_time or should_call_while_paused) and frame_urgency >= 0: last_call_real_time = now # Urgency decreases when a tick is processed. frame_urgency -= 1 / self.maximum_tick_rate_preference self.perform_tick() last_tick_game_time = tick_game_time # Ratelimit here rate_limit.acquire() except KeyboardInterrupt: self.terminate_request_event.set() self.retire_agent(self.agent) # If terminated, send callback self.termination_complete_event.set()
def game_loop(self): """The main game loop. This is where your hivemind code goes.""" # Setting up rate limiter. rate_limit = rate_limiter.RateLimiter(120) # Setting up data. field_info = FieldInfoPacket() self.game_interface.update_field_info_packet(field_info) packet = GameTickPacket() self.game_interface.update_live_data_packet(packet) data.setup(self, packet, field_info, self.running_indices) self.ball.predict = BallPrediction() # https://github.com/RLBot/RLBotPythonExample/wiki/Ball-Path-Prediction # MAIN LOOP: while True: # Updating the game packet from the game. self.game_interface.update_live_data_packet(packet) # Processing packet. data.process(self, packet) # Ball prediction. self.game_interface.update_ball_prediction(self.ball.predict) # Planning. brain.plan(self) # Rendering. self.render_debug(self.game_interface.renderer) # For each drone under the hivemind's control, do something. for drone in self.drones: # The controls are reset each frame. drone.ctrl = PlayerInput( ) # Basically the same as SimpleControllerState(). # Role execution. if drone.role is not None: drone.role.execute(self, drone) self.render_role(self.game_interface.renderer, drone) # Send the controls to the bots. self.game_interface.update_player_input( drone.ctrl, drone.index) # Rate limit sleep. rate_limit.acquire()
def _wait_until_good_ticks(game_interface: GameInterface, required_new_ticks: int=3): """Blocks until we're getting new packets, indicating that the match is ready.""" rate_limit = rate_limiter.RateLimiter(120) last_tick_game_time = None # What the tick time of the last observed tick was game_tick_packet = GameTickPacket() # We want to do a deep copy for game inputs so people don't mess with em seen_times = 0 while seen_times < required_new_ticks: # Read from game data shared memory game_interface.update_live_data_packet(game_tick_packet) tick_game_time = game_tick_packet.game_info.seconds_elapsed if tick_game_time != last_tick_game_time and game_tick_packet.game_info.is_round_active: last_tick_game_time = tick_game_time seen_times += 1 rate_limit.acquire()
def _wait_until_good_ticks(game_interface: GameInterface, required_new_ticks: int=3): """Blocks until we're getting new packets, indicating that the match is ready.""" rate_limit = rate_limiter.RateLimiter(120) last_tick_game_time = None # What the tick time of the last observed tick was packet = GameTickPacket() # We want to do a deep copy for game inputs so people don't mess with em seen_times = 0 while seen_times < required_new_ticks: game_interface.update_live_data_packet(packet) def is_good_tick(): if packet.game_info.seconds_elapsed == last_tick_game_time: return False if not packet.game_info.is_round_active: return False if any(car.is_demolished for car in packet.game_cars): return False return True if is_good_tick(): seen_times += 1 last_tick_game_time = packet.game_info.seconds_elapsed rate_limit.acquire()
def game_loop(self): """The main game loop. This is where your hivemind code goes.""" # Setting up rate limiter. rate_limit = rate_limiter.RateLimiter(120) # Setting up data. field_info = FieldInfoPacket() self.game_interface.update_field_info_packet(field_info) packet = GameTickPacket() self.game_interface.update_live_data_packet(packet) data.setup(self, packet, field_info, self.running_indices) self.ball.predict = BallPrediction() # MAIN LOOP: while True: # Updating the game packet from the game. self.game_interface.update_live_data_packet(packet) # Processing packet. data.process(self, packet) # Ball prediction. self.game_interface.update_ball_prediction(self.ball.predict) brain.think(self) for drone in self.drones: drone.ctrl = PlayerInput() if drone.role is not None: drone.role.execute(self, drone) self.game_interface.update_player_input( drone.ctrl, drone.index) self.draw_debug() # Rate limit sleep. rate_limit.acquire()
def run(self): """ Loads interface for RLBot, prepares environment and agent, and calls the update for the agent. """ self.logger.debug('initializing agent') self.game_interface.load_interface() self.prepare_for_run() # Create Ratelimiter rate_limit = rate_limiter.RateLimiter( GAME_TICK_PACKET_POLLS_PER_SECOND) last_tick_game_time = None # What the tick time of the last observed tick was last_call_real_time = datetime.now() # When we last called the Agent # Get bot module self.load_agent() self.last_module_modification_time = self.check_modification_time( os.path.dirname(self.agent_class_file)) # Run until main process tells to stop, or we detect Ctrl+C try: while not self.terminate_request_event.is_set(): self.pull_data_from_game() # game_tick_packet = self.game_interface.get # Read from game data shared memory # Run the Agent only if the game_info has updated. tick_game_time = self.get_game_time() should_call_while_paused = datetime.now( ) - last_call_real_time >= MAX_AGENT_CALL_PERIOD if tick_game_time != last_tick_game_time or should_call_while_paused: last_tick_game_time = tick_game_time last_call_real_time = datetime.now() # Reload the Agent if it has been modified or if reload is requested from outside. if self.agent.is_hot_reload_enabled(): self.hot_reload_if_necessary() try: chat_messages = self.game_interface.receive_chat( self.index, self.team, self.last_message_index) for i in range(0, chat_messages.MessagesLength()): message = chat_messages.Messages(i) if len(self.match_config.player_configs ) > message.PlayerIndex(): self.agent.handle_quick_chat( index=message.PlayerIndex(), team=self.match_config.player_configs[ message.PlayerIndex()].team, quick_chat=message.QuickChatSelection()) else: self.logger.debug( f"Skipping quick chat delivery for {message.MessageIndex()} because " "we don't recognize the player index. Probably stale." ) self.last_message_index = message.MessageIndex() except EmptyDllResponse: self.logger.debug("Empty response when reading chat!") # Call agent try: self.call_agent( self.agent, self.agent_class_wrapper.get_loaded_class()) except Exception as e: self.logger.error("Call to agent failed:\n" + traceback.format_exc()) # Ratelimit here rate_limit.acquire() except KeyboardInterrupt: self.terminate_request_event.set() self.retire_agent(self.agent) # If terminated, send callback self.termination_complete_event.set()
def run(self): """ Loads interface for RLBot, prepares environment and agent, and calls the update for the agent. """ self.logger.debug('initializing agent') self.game_interface.load_interface() self.prepare_for_run() # Create Ratelimiter rate_limit = rate_limiter.RateLimiter(GAME_TICK_PACKET_REFRESHES_PER_SECOND) last_tick_game_time = None # What the tick time of the last observed tick was last_call_real_time = datetime.now() # When we last called the Agent # Get bot module agent, agent_class_file = self.load_agent() last_module_modification_time = os.stat(agent_class_file).st_mtime # Run until main process tells to stop while not self.terminate_request_event.is_set(): before = datetime.now() self.pull_data_from_game() # game_tick_packet = self.game_interface.get # Read from game data shared memory # Run the Agent only if the game_info has updated. tick_game_time = self.get_game_time() should_call_while_paused = datetime.now() - last_call_real_time >= MAX_AGENT_CALL_PERIOD if tick_game_time != last_tick_game_time or should_call_while_paused: last_tick_game_time = tick_game_time last_call_real_time = datetime.now() # Reload the Agent if it has been modified or if reload is requested from outside. try: new_module_modification_time = os.stat(agent_class_file).st_mtime if new_module_modification_time != last_module_modification_time or self.reload_request_event.is_set(): self.reload_request_event.clear() last_module_modification_time = new_module_modification_time agent, agent_class_file = self.reload_agent(agent, agent_class_file) except FileNotFoundError: self.logger.error("Agent file {} was not found. Will try again.".format(agent_class_file)) time.sleep(0.5) except Exception: self.logger.error("Reloading the agent failed:\n" + traceback.format_exc()) time.sleep(0.5) # Avoid burning CPU / logs if this starts happening constantly # Call agent try: self.call_agent(agent, self.agent_class_wrapper.get_loaded_class()) except Exception as e: self.logger.error("Call to agent failed:\n" + traceback.format_exc()) # Ratelimit here after = datetime.now() rate_limit.acquire(after - before) if hasattr(agent, 'retire'): agent.retire() # If terminated, send callback self.termination_complete_event.set()
def run(self): """ Loads interface for RLBot, prepares environment and agent, and calls the update for the agent. """ self.logger.debug('initializing agent') self.game_interface.load_interface() self.prepare_for_run() # Create Ratelimiter rate_limit = rate_limiter.RateLimiter( GAME_TICK_PACKET_REFRESHES_PER_SECOND) last_tick_game_time = None # What the tick time of the last observed tick was last_call_real_time = datetime.now() # When we last called the Agent # Get bot module agent, agent_class_file = self.load_agent() last_module_modification_time = os.stat(agent_class_file).st_mtime # Run until main process tells to stop while not self.terminate_request_event.is_set(): before = datetime.now() self.pull_data_from_game() # game_tick_packet = self.game_interface.get # Read from game data shared memory # Run the Agent only if the game_info has updated. tick_game_time = self.get_game_time() should_call_while_paused = datetime.now( ) - last_call_real_time >= MAX_AGENT_CALL_PERIOD if tick_game_time != last_tick_game_time or should_call_while_paused: last_tick_game_time = tick_game_time last_call_real_time = datetime.now() # Reload the Agent if it has been modified. new_module_modification_time = os.stat( agent_class_file).st_mtime if new_module_modification_time != last_module_modification_time: try: last_module_modification_time = new_module_modification_time self.logger.info('Reloading Agent: ' + agent_class_file) self.agent_class_wrapper.reload() old_agent = agent agent, agent_class_file = self.load_agent() # Retire after the replacement initialized properly. if hasattr(old_agent, 'retire'): old_agent.retire() except Exception as e: self.logger.error("Reloading the agent failed:\n" + traceback.format_exc()) # Call agent try: self.call_agent( agent, self.agent_class_wrapper.get_loaded_class()) except Exception as e: self.logger.error("Call to agent failed:\n" + traceback.format_exc()) # Ratelimit here after = datetime.now() rate_limit.acquire(after - before) if hasattr(agent, 'retire'): agent.retire() # If terminated, send callback self.termination_complete_event.set()
def run(self): """ Loads interface for RLBot, prepares environment and agent, and calls the update for the agent. """ self.logger.debug('initializing agent') self.game_interface.load_interface() self.prepare_for_run() # Create Ratelimiter rate_limit = rate_limiter.RateLimiter( GAME_TICK_PACKET_POLLS_PER_SECOND) last_tick_game_time = None # What the tick time of the last observed tick was last_call_real_time = datetime.now() # When we last called the Agent # Get bot module agent, agent_class_file = self.load_agent() last_module_modification_time = os.stat(agent_class_file).st_mtime # Run until main process tells to stop, or we detect Ctrl+C try: while not self.terminate_request_event.is_set(): self.pull_data_from_game() # game_tick_packet = self.game_interface.get # Read from game data shared memory # Run the Agent only if the game_info has updated. tick_game_time = self.get_game_time() should_call_while_paused = datetime.now( ) - last_call_real_time >= MAX_AGENT_CALL_PERIOD if tick_game_time != last_tick_game_time or should_call_while_paused: last_tick_game_time = tick_game_time last_call_real_time = datetime.now() # Reload the Agent if it has been modified or if reload is requested from outside. try: new_module_modification_time = os.stat( agent_class_file).st_mtime if new_module_modification_time != last_module_modification_time or self.reload_request_event.is_set( ): self.reload_request_event.clear() last_module_modification_time = new_module_modification_time agent, agent_class_file = self.reload_agent( agent, agent_class_file) except FileNotFoundError: self.logger.error( f"Agent file {agent_class_file} was not found. Will try again." ) time.sleep(0.5) except Exception: self.logger.error("Reloading the agent failed:\n" + traceback.format_exc()) time.sleep( 0.5 ) # Avoid burning CPU / logs if this starts happening constantly # Call agent try: self.call_agent( agent, self.agent_class_wrapper.get_loaded_class()) except Exception as e: self.logger.error("Call to agent failed:\n" + traceback.format_exc()) # Ratelimit here rate_limit.acquire() except KeyboardInterrupt: self.terminate_request_event.set() # Shut down the bot by calling cleanup functions. if hasattr(agent, 'retire'): try: agent.retire() except Exception as e: self.logger.error("Retiring the agent failed:\n" + traceback.format_exc()) if hasattr(agent, 'renderer') and isinstance(agent.renderer, RenderingManager): agent.renderer.clear_all_touched_render_groups() # Zero out the inputs, so it's more obvious that the bot has stopped. self.game_interface.update_player_input(PlayerInput(), self.index) # If terminated, send callback self.termination_complete_event.set()