def main(): """Testing for errors and performance""" from timeit import timeit from rlbot.utils.structures.game_data_struct import GameTickPacket from skeleton.test.skeleton_agent_test import SkeletonAgentTest, MAX_BOOSTS agent = SkeletonAgentTest() game_tick_packet = GameTickPacket() game_tick_packet.num_boost = MAX_BOOSTS agent.initialize_agent() def test_function(): return closest_available_boost(agent.game_data.my_car.location, agent.game_data.boost_pads) test_function() fps = 120 n_times = 10000 time_taken = timeit(test_function, number=n_times) percentage = time_taken * fps / n_times * 100 print(f"Took {time_taken} seconds to run {n_times} times.") print(f"That's {percentage:.5f} % of our time budget.")
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 _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 start(self): """Runs once, sets up the hivemind and its agents.""" # Prints an activation message into the console. # This let's you know that the process is up and running. self.logger.info("Hello World!") # Loads game interface. self.game_interface.load_interface() # This is how you access field info. # First create the initialise the object... field_info = FieldInfoPacket() # Then update it. self.game_interface.update_field_info_packet(field_info) # Same goes for the packet, but that is # also updated in the main loop every tick. packet = GameTickPacket() self.game_interface.update_live_data_packet(packet) # Initialise drones list. Will be filled with Drone objects for every drone. self.drones = [] # Runs the game loop where the hivemind will spend the rest of its time. self.game_loop()
def main(self): while True: packet = GameTickPacket() self.game_interface.update_live_data_packet(packet) gametime = "{:.2f}".format(packet.game_info.seconds_elapsed) if packet.game_info.is_match_ended: print("Game is over, exiting.") self.gameWrapUp() self.stopHost() break if self.firstIter: if packet.num_cars >= 1: if self.joinTimer <= 0: self.joinTimer = time.time() if time.time() - self.joinTimer >=1: #arbitrary timer to ensure all cars connected self.firstIter = False self.currentTime = float(gametime) self.gatherMatchData(packet) if self.timeCheck(float(gametime)): print("framework reset, resetting announcerbot") self.reset() if not self.firstIter: self.updateGameBall(packet) self.updateTouches(packet) self.handleShotDetection() self.scoreCheck(packet) self.overtimeCheck(packet)
def manage_game_state(challenge: dict, upgrades: dict, setup_manager: SetupManager) -> Tuple[bool, dict]: """ Continuously track the game and adjust state to respect challenge rules and upgrades. At the end of the game, calculate results and the challenge completion and return that """ early_failure = False, {} expected_player_count = challenge["humanTeamSize"] + len( challenge["opponentBots"]) # Wait for everything to be initialized packet = wait_till_cars_spawned(setup_manager, expected_player_count) if packet.num_cars == 0: print("The game was initialized with no cars") return early_failure stats_tracker = ManualStatsTracker(challenge) while True: try: eel.sleep(0) # yield to allow other gui threads to operate. packet = GameTickPacket() setup_manager.game_interface.fresh_live_data_packet( packet, 1000, WITNESS_ID) if packet.num_cars == 0: # User seems to have ended the match print("User ended the match") return early_failure stats_tracker.updateStats(packet) results = packet_to_game_results(packet) if has_user_perma_failed(challenge, stats_tracker.stats): time.sleep(1) setup_failure_freeplay(setup_manager, "You failed the challenge!") return early_failure if end_by_mercy(challenge, stats_tracker.stats, results): time.sleep(3) setup_failure_freeplay(setup_manager, "Challenge completed by mercy rule!", "green") return True, results if packet.game_info.is_match_ended: break except KeyError: traceback.print_exc() # it means that the game was interrupted by the user print("Looks like the game is in a bad state") setup_failure_freeplay(setup_manager, "The game was interrupted.") return early_failure return calculate_completion(challenge, stats_tracker.stats, results), results
def __init__(self, name): super().__init__(name) self.logger = get_logger(name) self.__key = hash("BaseScript:" + name) self.game_tick_packet = GameTickPacket() self.ball_prediction = BallPrediction() self.game_interface = GameInterface(self.logger) self.game_interface.load_interface() fake_index = random.randint( 100, 10000) # a number unlikely to conflict with bots or other scripts self.renderer = self.game_interface.renderer.get_rendering_manager( bot_index=fake_index, bot_team=2) # Get matchcomms root if provided as a command line argument. try: pos = sys.argv.index("--matchcomms-url") potential_url = urlparse(sys.argv[pos + 1]) except (ValueError, IndexError): # Missing the command line argument. pass else: if potential_url.scheme == "ws" and potential_url.netloc: self.matchcomms_root = potential_url else: raise ValueError("The matchcomms url is invalid")
def __game_loop(self): """ The bot hivemind will stay in this loop for the whole game. This is where the initialize_hive and get_outputs functions are called. """ # Creating ball prediction and field info objects to later update in wrapper methods. self._ball_prediction = BallPrediction() # Create packet object. packet = GameTickPacket() # Uses one of the drone indices as a key. first_index = next(iter(self.drone_indices)) self.game_interface.fresh_live_data_packet(packet, 20, first_index) # Get a rendering manager for the hivemind. self.team = packet.game_cars[first_index].team self.renderer = self.game_interface.renderer.get_rendering_manager( bot_index=first_index, bot_team=self.team) # Initialization step for your hivemind. self.initialize_hive(packet) while not self.quit_event.is_set(): try: # Updating the packet. self.game_interface.fresh_live_data_packet( packet, 20, first_index) # Get outputs from hivemind for each bot. # Outputs are expected to be a Dict[int, PlayerInput] outputs = self.get_outputs(packet) if outputs is None: self.logger.error("No outputs were returned.") self.logger.error( " Try putting `return {i: PlayerInput() for i in self.drone_indices}`" ) self.logger.error(" in `get_outputs()` to troubleshoot.") continue if len(outputs) < len(self.drone_indices): self.logger.error("Not enough outputs were given.") elif len(outputs) > len(self.drone_indices): self.logger.error("Too many outputs were given.") # Send the drone inputs to the drones. for index in outputs: if index not in self.drone_indices: self.logger.error( "Tried to send output to bot index not in drone_indices." ) continue output = outputs[index] self.game_interface.update_player_input(output, index) except Exception: traceback.print_exc()
def __init__(self, name, team, index): super().__init__(name, team, index) self.logger = get_logger('ExeSocket' + str(self.index)) self.is_retired = False self.executable_path = None self.game_interface = GameInterface(self.logger) self.game_tick_packet = GameTickPacket() self.spawn_id_seen = False
def fetch_game_tick_packet() -> GameTickPacket: global sm if sm is None: sm = SetupManager() sm.connect_to_game() game_tick_packet = GameTickPacket() sm.game_interface.update_live_data_packet(game_tick_packet) return game_tick_packet
def __init__(self): super().__init__("Caster") print("Caster created") self.touchTimer = 0 self.currentTime = 0 self.firstIter = True self.overTime = False self.shotDetection = True self.shooter = None self.currentZone = None self.KOE = None self.contactNames = rstring(["hits", "touches", "moves"]) self.dominantNames = rstring(["dominant", "commanding", "powerful"]) self.dangerously = rstring( ["alarmingly", "perilously", "precariously", "dangerously"]) self.RC_Intros = rstring([ "Here's a fun fact. ", "Check this out. ", "This is interesting. ", "What do you think about this?", "Oh, look at this.", ]) self.touch_comments = [ "makes contact", "gets a touch", "hits the ball", "gets a piece of the ball", ] self.touch_commentary = [] self.ballHistory = [] self.lastTouches = [] self.RC_list = [0, 1, 2, 3, 4, 5, 6, 7] self.teams = [] self.zoneInfo = None self.joinTimer = 0 self.packet = GameTickPacket() self.f_packet = None # FieldInfoPacket() self.ball_predictions = BallPrediction() self.lastCommentTime = 0 self.comment_ids = [x + 1 for x in range(18)] self.make_touch_comment = False self.summary_count = 0 self.game_length = -1 self.clock_time = 0 self.q = Queue(maxsize=200) self.random_lockout = time.perf_counter() self.host = threading.Thread( target=host, args=( self.q, 0, ), ) self.host.start()
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 main(): """Testing for errors and performance""" agent = SkeletonAgentTest("test_agent", 0, 0) agent.initialize_agent() game_tick_packet = GameTickPacket() game_tick_packet.num_cars = MAX_PLAYERS game_tick_packet.num_boost = MAX_BOOSTS game_tick_packet.num_goals = MAX_GOALS def test_function(): return agent.get_output(game_tick_packet) fps = 120 n_times = 1000 time_taken = timeit(test_function, number=n_times) percentage = round(time_taken * fps / n_times * 100, 5) print(f"Took {time_taken} seconds to run {n_times} times.") print(f"That's {percentage} % of our time budget.")
def wait_till_cars_spawned( setup_manager: SetupManager, expected_player_count: int ) -> GameTickPacket: packet = GameTickPacket() setup_manager.game_interface.fresh_live_data_packet(packet, 1000, WITNESS_ID) waiting_start = time.monotonic() while packet.num_cars != expected_player_count and time.monotonic() - waiting_start < 5: print("Game started but no cars are in the packets") time.sleep(0.5) setup_manager.game_interface.fresh_live_data_packet(packet, 1000, WITNESS_ID) return packet
def __init__(self, name): super().__init__(name) self.logger = get_logger(name) self.__key = hash("BaseScript:" + name) self.game_tick_packet = GameTickPacket() self.ball_prediction = BallPrediction() self.game_interface = GameInterface(self.logger) self.game_interface.load_interface() fake_index = random.randint( 100, 10000) # a number unlikely to conflict with bots or other scripts self.renderer = self.game_interface.renderer.get_rendering_manager( bot_index=fake_index, bot_team=2)
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 game_loop(self): # Creating packet which will be updated every tick. packet = GameTickPacket() # MAIN LOOP: while self.loop_check(): #print('test') prev_time = packet.game_info.seconds_elapsed # Updating the game tick packet. self.game_interface.update_live_data_packet(packet) # Checking if packet is new, otherwise sleep. if prev_time == packet.game_info.seconds_elapsed: time.sleep(0.001) continue # Create a Drone object for every drone that holds its information. if packet.num_cars > len(self.drones): # Clears the list if there are more cars than drones. self.drones.clear() for index in range(packet.num_cars): self.drones.append( Drone(index, packet.game_cars[index].team)) # Processing drone data. for drone in self.drones: drone.update(packet.game_cars[drone.index], packet.game_info.seconds_elapsed) # Steps through the choreography. try: self.choreo.step(packet, self.drones) except Exception: traceback.print_exc() # Resets choreography once it has finished. if self.choreo.finished: # Re-instantiates the choreography. self.choreo = self.choreo.__class__(self.game_interface) self.choreo.generate_sequence(self.drones) # Sends the drone inputs to the drones. for drone in self.drones: self.game_interface.update_player_input( convert_player_input(drone.ctrl), drone.index)
def detect_events(self, game_tick_packet) -> List[PlayerEvent]: """ Detects any PlayerEvents which happened since the last call. """ events = [] if not self.prev_tick_packet: self.prev_tick_packet = GameTickPacket() else: # compate to prev_tick_packet seconds_elapsed = game_tick_packet.game_info.seconds_elapsed for i, player, prev_player in zip(range(game_tick_packet.num_cars), game_tick_packet.game_cars, self.prev_tick_packet.game_cars): score = player.score_info prev_score = prev_player.score_info if score.score != prev_score.score: events.append( PlayerEvent(PlayerEventType.SCORE, player, seconds_elapsed)) if score.goals != prev_score.goals: events.append( PlayerEvent(PlayerEventType.GOALS, player, seconds_elapsed)) if score.own_goals != prev_score.own_goals: events.append( PlayerEvent(PlayerEventType.OWN_GOALS, player, seconds_elapsed)) if score.assists != prev_score.assists: events.append( PlayerEvent(PlayerEventType.ASSISTS, player, seconds_elapsed)) if score.saves != prev_score.saves: events.append( PlayerEvent(PlayerEventType.SAVES, player, seconds_elapsed)) if score.shots != prev_score.shots: events.append( PlayerEvent(PlayerEventType.SHOTS, player, seconds_elapsed)) if score.demolitions != prev_score.demolitions: events.append( PlayerEvent(PlayerEventType.DEMOLITIONS, player, seconds_elapsed)) ctypes.pointer(self.prev_tick_packet)[0] = game_tick_packet # memcpy return events
def is_discontinuous(self, game_tick_packet: GameTickPacket) -> bool: """ Returns true iff it is implausible that we arrived at the current game_tick_packet by just waiting. Compares to the last time this function has been called. """ with self._update_prev_on_return(game_tick_packet): if self.prev_tick_packet is None: self.prev_tick_packet = GameTickPacket() return False # Be on the safe side - On the first tick things are ok. dt = game_tick_packet.game_info.seconds_elapsed - self.prev_tick_packet.game_info.seconds_elapsed if dt == 0: return False ball_dist = obj_distance(game_tick_packet.game_ball, self.prev_tick_packet.game_ball) ball_speed = ball_dist / dt # TODO: detect it on other things as well. e.g. cars, gametime. return ball_speed > self.MAX_PLAUSIBLE_BALL_SPEED
def connect(self, game_interface: GameInterface, configs): print("commentator connected!") self.config_paths = configs self.game_interface = game_interface self.botReadouts = [] print(f"we were passed {len(configs)} bundles") for i in range(len(configs)): self.botReadouts.append(self.createAgentInfo(configs[i])) self.touchTimer = 0 self.currentTime = 0 self.firstIter = True self.overTime = False self.shotDetection = True self.shooter = None self.currentZone = None self.KOE = None self.contactNames = rstring(["hits", "touches", "moves"]) self.dominantNames = rstring(["dominant", "commanding", "powerful"]) self.dangerously = rstring( ["alarmingly", "perilously", "precariously", "dangerously"]) self.RC_Intros = rstring([ "Here's a fun fact. ", "Check this out. ", "This is interesting. ", "You might like this. " ]) self.ballHistory = [] self.lastTouches = [] self.RC_list = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] self.teams = [] self.zoneInfo = None self.joinTimer = 0 self.packet = GameTickPacket() self.f_packet = FieldInfoPacket() self.ball_predictions = BallPrediction() self.lastCommentTime = time.time() self.finished = False self.q = Queue(maxsize=200) self.host = threading.Thread(target=host, args=( self.q, 0, )) self.host.start() # for each in self.botReadouts: # print(each) # self.speak(each,10,10) self.update()
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 quick_self_check(): bot = NomBot_1_5('bot name', 0, 0) bot.initialize_agent() # Stub out a few things from unittest.mock import MagicMock packet = GameTickPacket() packet.game_cars[0].physics.location.x = 100 def get_ball_prediction_struct(): ball_prediction = BallPrediction() ball_prediction.num_slices = 7 return ball_prediction bot.get_ball_prediction_struct = get_ball_prediction_struct bot.renderer = MagicMock() bot.get_output(packet) info('quick_self_check passed.')
def __init__(self, name: str = "skeleton", team: int = 0, index: int = 0): self.name = name self.index = index self.team = team # keeping the original packet is sometimes useful self.game_tick_packet = GameTickPacket() # cars self.my_car = Player() # other cars as structured numpy arrays self.opponents: np.ndarray = np.empty(()) self.teammates: np.ndarray = np.empty(()) # ball self.ball = Ball() # ball prediction structured numpy array self.ball_prediction: np.ndarray = np.empty(()) # boost pads structured numpy array self.boost_pads: np.ndarray = np.empty(()) # goals self.opp_goal = Goal() self.own_goal = Goal() # goals structured numpy arrays self.opp_goals: np.ndarray = np.empty(()) self.own_goals: np.ndarray = np.empty(()) # other info self.counter = 0 self.time = 0.0 self.time_remaining = 0.0 self.overtime = False self.round_active = False self.kickoff_pause = False self.match_ended = False self.gravity = -650.0
def start(self): """Runs once, sets up the hivemind and its agents.""" # Prints an activation message into the console. # This let's you know that the process is up and running. self.logger.info("Hello World!") # Loads game interface. self.game_interface.load_interface() # Wait a moment for all agents to have a chance to start up and send metadata. self.logger.info("Snoozing for 3 seconds; give me a moment.") time.sleep(3) self.try_receive_agent_metadata() # This is how you access field info. # First create the initialise the object... field_info = FieldInfoPacket() # Then update it. self.game_interface.update_field_info_packet(field_info) # Same goes for the packet, but that is # also updated in the main loop every tick. packet = GameTickPacket() self.game_interface.update_live_data_packet(packet) # Ball prediction works the same. Check the main loop. # Create a Ball object for the ball that holds its information. self.ball = Ball() # Create a Drone object for every drone that holds its information. self.drones = [] for index in range(packet.num_cars): if index in self.running_indices: self.drones.append(Drone(index, packet.game_cars[index].team)) # Other attribute initialisation. self.state = State.SETUP self.pinch_target = None # Runs the game loop where the hivemind will spend the rest of its time. self.game_loop()
def _grade_exercise(game_interface: GameInterface, ex: Exercise, seed: int) -> Result: grade = None 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.fresh_live_data_packet(game_tick_packet, 100, 99) 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())) return Result(ex, seed, grade)
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 test_player_events(self): detector = PlayerEventDetector() gtp = GameTickPacket() gtp.game_info.seconds_elapsed = 14. gtp.num_cars = 2 gtp.game_cars[1].score_info.goals = 3 self.assertListEqual(detector.detect_events(gtp), []) self.assertListEqual(detector.detect_events(gtp), []) gtp = GameTickPacket() gtp.game_info.seconds_elapsed = 15. gtp.num_cars = 2 gtp.game_cars[1].score_info.goals = 5 self.assertListEqual(detector.detect_events(gtp), [ PlayerEvent( type=PlayerEventType.GOALS, player=gtp.game_cars[1], seconds_elapsed=15., ) ]) self.assertListEqual(detector.detect_events(gtp), [])
def main(self): # Create packet packet = GameTickPacket() last_game_time = 0.0 while True: # Update packet self.game_interface.update_live_data_packet(packet) game_time = packet.game_info.seconds_elapsed # Sleep until a new packet is received. if last_game_time == game_time: time.sleep(0.001) else: if packet.game_info.is_round_active: # Renders ball prediction. ball_prediction = BallPrediction() self.game_interface.update_ball_prediction(ball_prediction) self.game_interface.renderer.begin_rendering() self.game_interface.renderer.draw_polyline_3d([step.physics.location for step in ball_prediction.slices[::10]], self.game_interface.renderer.cyan()) self.game_interface.renderer.end_rendering() car_states = {} for i in range(packet.num_cars): car = packet.game_cars[i] if STICK != 0 and car.has_wheel_contact: # Makes cars stick by adding a velocity downwards. pitch = car.physics.rotation.pitch yaw = car.physics.rotation.yaw roll = car.physics.rotation.roll CP = cos(pitch) SP = sin(pitch) CY = cos(yaw) SY = sin(yaw) CR = cos(roll) SR = sin(roll) x = car.physics.velocity.x - STICK*(-CR * CY * SP - SR * SY) y = car.physics.velocity.y - STICK*(-CR * SY * SP + SR * CY) z = car.physics.velocity.z - STICK*(CP * CR) car_states.update({i: CarState(physics=Physics(velocity=Vector3(x,y,z)))}) if packet.game_info.is_kickoff_pause and round(packet.game_ball.physics.location.z) != KICKOFF_BALL_HEIGHT: # Places the ball in the air on kickoff. ball_state = BallState(Physics(location=Vector3(z=KICKOFF_BALL_HEIGHT), velocity=Vector3(0,0,0))) if len(car_states) > 0: game_state = GameState(ball=ball_state, cars=car_states) else: game_state = GameState(ball=ball_state) else: if len(car_states) > 0: game_state = GameState(cars=car_states) else: game_state = GameState() # Uses state setting to set the game state. self.game_interface.set_game_state(game_state)
async def game_loop(self): 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 packet = GameTickPacket() # Run until main process tells to stop while not self.quit_event.is_set(): before = datetime.now() self.game_interface.update_live_data_packet(packet) # Run the Agent only if the gameInfo has updated. tick_game_time = packet.game_info.seconds_elapsed worth_communicating = tick_game_time != last_tick_game_time or \ datetime.now() - last_call_real_time >= MAX_AGENT_CALL_PERIOD ball = packet.game_ball if ball is not None and worth_communicating and max( self.running_indices) < packet.num_cars: last_tick_game_time = tick_game_time last_call_real_time = datetime.now() tiny_player_offsets = [] builder = flatbuffers.Builder(0) for i in range(packet.num_cars): tiny_player_offsets.append( self.copy_player(packet.game_cars[i], builder)) TinyPacket.TinyPacketStartPlayersVector( builder, packet.num_cars) for i in reversed(range(0, len(tiny_player_offsets))): rlbot_index = self.get_rlbot_index(i) builder.PrependUOffsetTRelative( tiny_player_offsets[rlbot_index]) players_offset = builder.EndVector(len(tiny_player_offsets)) ballOffset = self.copy_ball(ball, builder) TinyPacket.TinyPacketStart(builder) TinyPacket.TinyPacketAddPlayers(builder, players_offset) TinyPacket.TinyPacketAddBall(builder, ballOffset) packet_offset = TinyPacket.TinyPacketEnd(builder) builder.Finish(packet_offset) buffer = bytes(builder.Output()) filtered_sockets = {s for s in self.current_sockets if s.open} for socket in filtered_sockets: await socket.send(buffer) self.current_sockets = filtered_sockets after = datetime.now() duration = (after - before).total_seconds() sleep_secs = 1 / 60 - duration if sleep_secs > 0: await asyncio.sleep(sleep_secs)
def main(self): main_path = BLUE_DRAGON_PATH other_path = PURPLE_DRAGON_PATH selected_point_index = 0 while True: packet = GameTickPacket() self.game_interface.update_live_data_packet(packet) renderer = self.game_interface.renderer renderer.begin_rendering() points = main_path.points selected_point_index = min(selected_point_index, len(points) - 1) # select previous if keyboard.is_pressed("-") and selected_point_index > 0: selected_point_index -= 1 time.sleep(0.1) # select next elif keyboard.is_pressed("+") and selected_point_index < len(points) - 1: selected_point_index += 1 time.sleep(0.1) # move selected elif keyboard.is_pressed("left arrow"): points[selected_point_index][0] -= 10 self.draw_line(renderer, points[selected_point_index], vec3(1, 0, 0)) elif keyboard.is_pressed("right arrow"): points[selected_point_index][0] += 10 self.draw_line(renderer, points[selected_point_index], vec3(1, 0, 0)) elif keyboard.is_pressed("up arrow"): points[selected_point_index][1] += 10 self.draw_line(renderer, points[selected_point_index], vec3(0, 1, 0)) elif keyboard.is_pressed("down arrow"): points[selected_point_index][1] -= 10 self.draw_line(renderer, points[selected_point_index], vec3(0, 1, 0)) elif keyboard.is_pressed("0"): points[selected_point_index][2] -= 10 self.draw_line(renderer, points[selected_point_index], vec3(0, 0, 1)) elif keyboard.is_pressed("1"): points[selected_point_index][2] += 10 self.draw_line(renderer, points[selected_point_index], vec3(0, 0, 1)) # insert new one after selected elif keyboard.is_pressed("*"): if selected_point_index == len(points) - 1: new_point = 2 * points[-1] - points[-2] else: new_point = (points[selected_point_index] + points[selected_point_index + 1]) * 0.5 selected_point_index += 1 points.insert(selected_point_index, new_point) time.sleep(0.2) # delete selected elif keyboard.is_pressed("delete"): del points[selected_point_index] selected_point_index -= 1 time.sleep(0.2) # dump points into file elif keyboard.is_pressed("enter"): with open("points.txt", "w") as file: file.write("\nBLUE DRAGON\n") for point in BLUE_DRAGON_PATH.points: file.write(f'vec3({int(point[0])}, {int(point[1])}, {int(point[2])}),\n') file.write("\nPURPLE DRAGON\n") for point in PURPLE_DRAGON_PATH.points: file.write(f'vec3({int(point[0])}, {int(point[1])}, {int(point[2])}),\n') print("dumped path to points.txt") renderer.clear_all_touched_render_groups() time.sleep(0.2) exit() # switch between paths elif keyboard.is_pressed("9"): main_path, other_path = other_path, main_path time.sleep(0.2) continue # render path path = BezierPath(points) curve = Curve(path.to_points(380)) # t = curve.find_nearest(points[min(selected_point_index, len(points) - 2)]) # rendered_points = [curve.point_at(t + i) for i in range(-5000, 5000, 200)] renderer.draw_polyline_3d(curve.points, renderer.white()) renderer.end_rendering() renderer.begin_rendering("stuff") for i in range(30): pos = curve.point_at((1 - i / 30) * curve.length) renderer.draw_string_3d(pos, 1, 1, str(i), renderer.white()) for i, point in enumerate(points): selected = i == selected_point_index color = renderer.yellow() if selected else renderer.red() size = 6 if selected else 4 renderer.draw_rect_3d(point, size, size, True, color, True) renderer.draw_string_2d(10, 10, 1, 1, str(int(curve.length)), renderer.yellow()) renderer.end_rendering() renderer.begin_rendering("reference") blue = renderer.create_color(255, 150, 180, 255) # render the other path for reference path = BezierPath(other_path.points) curve2 = Curve(path.to_points(380)) # rendered_points = [curve2.point_at(curve2.length - curve.length + t + i) for i in range(-5000, 5000, 200)] renderer.draw_polyline_3d(curve2.points, blue) for i in range(30): pos = curve2.point_at((1 - i / 30) * curve2.length) renderer.draw_string_3d(pos, 1, 1, str(i), renderer.blue()) renderer.draw_string_2d(10, 30, 1, 1, str(int(curve2.length)), renderer.yellow()) renderer.end_rendering() # render the rings of fire orbit for reference renderer.begin_rendering("orbit") points = [dot(axis_to_rotation(vec3(0, 0, i / 30 * pi * 2)), vec3(2200, 0, 1400)) for i in range(30)] renderer.draw_polyline_3d(points, renderer.orange()) renderer.end_rendering() time.sleep(0.02)