Пример #1
0
    def start(self):
        while True:
            time.sleep(0.5)

            # Update packet
            packet: GameTickPacket = self.get_game_tick_packet()

            if not packet.game_info.is_round_active:
                continue

            self.set_game_state(
                GameState(game_info=GameInfoState(
                    world_gravity_z=WORLD_GRAVITY)))

            # Renders ball prediction.
            ball_prediction: BallPrediction = self.get_ball_prediction_struct()
            self.renderer.begin_rendering()
            sparse_slices = [
                step.physics.location for step in ball_prediction.slices[::10]
            ]
            self.renderer.draw_polyline_3d(sparse_slices, self.renderer.cyan())
            self.renderer.end_rendering()

            # Places the ball in the air on kickoff.
            if packet.game_info.is_kickoff_pause and round(
                    packet.game_ball.physics.location.z
            ) != KICKOFF_BALL_HEIGHT:
                ball_state = BallState(
                    Physics(location=Vector3(z=KICKOFF_BALL_HEIGHT),
                            velocity=Vector3(0, 0, 0)))
                self.set_game_state(GameState(ball=ball_state))
Пример #2
0
    def set_state_test(self, game_tick_packet: GameTickPacket):

        my_car = game_tick_packet.game_cars[self.index]
        car_location = my_car.physics.location

        car_state = CarState()
        if math.fabs(car_location.x) > 2000 and car_location.z < 100:
            car_state = CarState(
                Physics(velocity=Vector3(z=500, x=-car_location.x * .5), rotation=Rotator(math.pi / 2, 0, 0),
                        angular_velocity=Vector3(0, 0, 0)),
                jumped=False, double_jumped=False, boost_amount=87)

        ball_phys = game_tick_packet.game_ball.physics
        ball_state = BallState()
        if ball_phys.location.z < 500:
            ball_state = BallState(Physics(velocity=Vector3(z=500)))

        if math.fabs(car_location.x) > 1000:
            boost_states = {i: BoostState(1.0) for i in range(34)}
        else:
            boost_states = {i: BoostState(0.0) for i in range(34)}

        game_info_state = GameInfoState(world_gravity_z=-(ball_phys.location.z - 1200), game_speed=0.5)

        game_state = GameState(ball=ball_state, cars={self.index: car_state},
                               boosts=boost_states, game_info=game_info_state)
        self.set_game_state(game_state)
Пример #3
0
def dict_to_game_state(state_dict):
    gs = GameState()
    if 'ball' in state_dict:
        gs.ball = BallState()
        if 'physics' in state_dict['ball']:
            gs.ball.physics = dict_to_physics(state_dict['ball']['physics'])
    if 'cars' in state_dict:
        gs.cars = {}
        for index, car in state_dict['cars'].items():
            car_state = CarState()
            if 'physics' in car:
                car_state.physics = dict_to_physics(car['physics'])
            if 'boost_amount' in car:
                car_state.boost_amount = car['boost_amount']
            gs.cars[int(index)] = car_state
    if 'game_info' in state_dict:
        gs.game_info = GameInfoState()
        if 'paused' in state_dict['game_info']:
            gs.game_info.paused = state_dict['game_info']['paused']
        if 'world_gravity_z' in state_dict['game_info']:
            gs.game_info.world_gravity_z = state_dict['game_info']['world_gravity_z']
        if 'game_speed' in state_dict['game_info']:
            gs.game_info.game_speed = state_dict['game_info']['game_speed']
    if 'console_commands' in state_dict:
        gs.console_commands = state_dict['console_commands']
    return gs
Пример #4
0
    def ensure_action_menu(self):
        if not self.needs_new_menu:
            return

        if not self.game_tick_packet.game_info.is_round_active:
            if self.broker_settings.pause_on_menu:
                # This seems like overkill, but we keep getting in annoying situations during replays.
                self.set_game_state(
                    GameState(game_info=GameInfoState(game_speed=1)))
            return

        game_seconds = self.game_tick_packet.game_info.seconds_elapsed
        if game_seconds < self.next_menu_moment:
            return

        all_actions = self.aggregator.fetch_all()
        self.menu_id = generate_menu_id()

        # Make sure we've got vote trackers for everything
        for action_group in all_actions:
            for action in action_group.available_actions.available_actions:
                description = action.description
                if action.description not in self.vote_trackers:
                    self.vote_trackers[description] = self.make_vote_tracker(
                        action_group.available_actions.entity_name,
                        self.menu_id, None)

        overlay_data = generate_menu(all_actions, self.menu_id,
                                     self.recent_commands,
                                     self.game_tick_packet, self.vote_trackers)

        if overlay_data.num_actions() == 0:
            return

        if self.broker_settings.pause_on_menu:
            self.set_game_state(
                GameState(game_info=GameInfoState(game_speed=0.01)))

        self.write_json_for_overlay(overlay_data)
        # TODO: consider notifying twitch chat of the new prefix via bot in twitch chat for reduced round trip latency
        # TODO: also look into twitch extensions: https://dev.twitch.tv/extensions

        self.recent_menus.insert(0, overlay_data)
        if len(self.recent_menus
               ) > self.broker_settings.num_old_menus_to_honor + 1:
            self.recent_menus.pop()
        self.needs_new_menu = False
Пример #5
0
 def begin(self):
     self.car = CarState(Physics(Vector3(), Rotator(), Vector3(),
                                 Vector3()))
     self.opponent = CarState(
         Physics(Vector3(), Rotator(), Vector3(), Vector3()))
     self.ball = BallState(Physics(Vector3()))
     self.gameinfo = GameInfoState()
     self._changed = False
Пример #6
0
    def ensure_action_menu(self):
        if not self.needs_new_menu:
            return

        if not self.game_tick_packet.game_info.is_round_active:
            if self.broker_settings.pause_on_menu:
                # This seems like overkill, but we keep getting in annoying situations during replays.
                self.set_game_state(
                    GameState(game_info=GameInfoState(game_speed=1)))
            return

        if self.game_tick_packet.game_info.seconds_elapsed < self.next_menu_moment:
            return

        all_actions = self.aggregator.fetch_all()

        self.menu_id = generate_menu_id()
        overlay_data = generate_menu(all_actions, self.menu_id,
                                     self.recent_commands,
                                     self.game_tick_packet, self.vote_trackers)

        if overlay_data.num_actions() == 0:
            return

        if self.broker_settings.pause_on_menu:
            self.set_game_state(
                GameState(game_info=GameInfoState(game_speed=0.01)))

        self.write_json_for_overlay(overlay_data)
        # TODO: consider notifying twitch chat of the new prefix via bot in twitch chat for reduced round trip latency
        # TODO: also look into twitch extensions: https://dev.twitch.tv/extensions

        self.recent_menus.insert(0, overlay_data)
        if len(self.recent_menus
               ) > self.broker_settings.num_old_menus_to_honor + 1:
            killed_menu = self.recent_menus.pop()
            expired_vote_tracker_keys = [
                key for key, tracker in self.vote_trackers.items()
                if tracker.original_menu_id == killed_menu.menu_id
            ]
            for expired_vt_key in expired_vote_tracker_keys:
                self.vote_trackers.pop(expired_vt_key)
        self.needs_new_menu = False
Пример #7
0
 def setup(self, packet, drones, start_time) -> StepResult:
     """
     Places the ball above the roof of the arena to keep it out of the way.
     """
     self.game_interface.set_game_state(
         GameState(game_info=GameInfoState(world_gravity_z=-1300),
                   ball=BallState(
                       physics=Physics(location=Vector3(0, 0, 3000),
                                       velocity=Vector3(0, 0, 0),
                                       angular_velocity=Vector3(0, 0, 0)))))
     return StepResult(finished=True)
Пример #8
0
    def initialize_agent(self):
        self.first_packet = True
        # Set up information about the boost pads now that the game is active and the info is available

        self.field = Field(self.get_field_info())
        self.scheduler = Scheduler()

        game_info_state = GameInfoState(world_gravity_z=0.0001)
        game_state = GameState(game_info=game_info_state)

        self.set_game_state(game_state)
Пример #9
0
 def make_game_state(self, rng: SeededRandomNumberGenerator) -> GameState:
     self.grader.graders[1].max_duration_seconds = 2
     return GameState(
         game_info=GameInfoState(game_speed=1),
         ball=BallState(physics=Physics(
             location=Vector3(rng.uniform(-100, 100), -500, 800),
             velocity=Vector3(rng.uniform(-100, 100), -1500, 900),  # 
             angular_velocity=Vector3(0, 0, 0))),
         cars={
             0:
             CarState(physics=Physics(location=Vector3(
                 rng.uniform(-300, 300), -3000, 17),
                                      rotation=Rotator(0, pi * -0.5, 0),
                                      velocity=Vector3(0, -1500, 0),
                                      angular_velocity=Vector3(0, 0, 0)),
                      boost_amount=60)
         },
     )
Пример #10
0
 def reset(self):
     #RESET TRAINING ATTRIBUTES AFTER EACH GENOME
     ball_state = BallState(
         Physics(velocity=Vector3(0, 0, 0),
                 location=Vector3(self.pos, 5000, 3000),
                 angular_velocity=Vector3(0, 0, 0)))
     car_state = CarState(jumped=False,
                          double_jumped=False,
                          boost_amount=33,
                          physics=Physics(velocity=Vector3(0, 0, 0),
                                          rotation=Rotator(45, 90, 0),
                                          location=Vector3(0.0, -4608, 500),
                                          angular_velocity=Vector3(0, 0,
                                                                   0)))
     game_info_state = GameInfoState(game_speed=1)
     game_state = GameState(ball=ball_state,
                            cars={self.index: car_state},
                            game_info=game_info_state)
     self.set_game_state(game_state)
Пример #11
0
 def reset(self):
     """Resets game data after each genome"""
     ball_state = BallState(
         Physics(velocity=Vector3(0, 0, 0),
                 location=Vector3(self.pos, 5000, 3000),
                 angular_velocity=Vector3(0, 0, 0)))
     car_state = CarState(jumped=False,
                          double_jumped=False,
                          boost_amount=33,
                          physics=Physics(velocity=Vector3(0, 0, 0),
                                          rotation=Rotator(45, 90, 0),
                                          location=Vector3(0.0, -4608, 500),
                                          angular_velocity=Vector3(0, 0,
                                                                   0)))
     game_info_state = GameInfoState(game_speed=1)
     game_state = GameState(ball=ball_state,
                            cars={self.index: car_state},
                            game_info=game_info_state)
     self.set_game_state(game_state)
Пример #12
0
 def reset(self):
     ball_start = Vec3(
         x=random.randint(-1365, 1365),
         y=random.randint(-1280, -1200),
         z=random.randint(50, 100),
     )
     ball_end = Vec3(
         x=random.randint(-800, 800),
         y=random.randint(-5125, -5120),
         z=random.randint(50, 100),
     )
     ball_speed = (ball_end-ball_start).normalized() * random.randint(1600, 1800)
     car_start = Vec3(
         x=random.randint(-440, 440),
         y=random.randint(-5560, -5120),
         z=50,
     )
     car_rot = Rotator(
         pitch=0,
         yaw=math.pi/2 + (random.random()-0.5)*math.pi/6,
         roll=0,
     )
     self.set_game_state(GameState(
         ball=BallState(physics=Physics(
             location=ball_start.to_vector3(),
             velocity=ball_speed.to_vector3(),
         )),
         cars={0: CarState(physics=Physics(
             location=car_start.to_vector3(),
             rotation=car_rot,
             velocity=Vector3(0, 0, 0),
             angular_velocity=Vector3(0, 0, 0)
         ), 
             boost_amount=random.randint(60, 90),
         )},
         game_info=GameInfoState(
             game_speed=self.speed
         )
     ))
Пример #13
0
    def setup(self, packet, drones, start_time) -> StepResult:
        self.game_interface.set_game_state(
            GameState(game_info=GameInfoState(game_speed=0.25)))

        car_states = {}
        radian_spacing = 2 * math.pi / 60

        for index, drone in enumerate(drones):
            if 61 <= index <= 64:
                car_states[drone.index] = CarState(
                    Physics(location=Vector3(3520, 5100, 0),
                            velocity=Vector3(0, 0, 0)))
                continue

            if index == 60:
                car_states[drone.index] = CarState(
                    Physics(location=Vector3(0, 0, 20),
                            velocity=Vector3(0, 0, 0),
                            rotation=Rotator(0, 0, 0)))
                continue

            progress = index * radian_spacing
            target = Vec3(radius * math.sin(progress),
                          radius * math.cos(progress), 0)

            car_states[drone.index] = CarState(
                Physics(location=Vector3(target.x, target.y, 20),
                        velocity=Vector3(0, 0, 0),
                        rotation=Rotator(0, -progress, 0)))

        self.game_interface.set_game_state(
            GameState(cars=car_states,
                      ball=BallState(
                          physics=Physics(location=Vector3(0, 0, 155),
                                          velocity=Vector3(0, 0, 0),
                                          angular_velocity=Vector3(0, 0, 0)))))

        return StepResult(finished=True)
Пример #14
0
 def make_game_state(self, rng: SeededRandomNumberGenerator) -> GameState:
     self.grader.graders[1].max_duration_seconds = 5
     return GameState(
         game_info=GameInfoState(game_speed=1),
         ball=BallState(
             physics=Physics(location=Vector3(rng.uniform(-500, 500),
                                              rng.uniform(-500, 500), 94),
                             velocity=Vector3(0, rng.uniform(-300, 500),
                                              rng.uniform(0, 600)),
                             angular_velocity=Vector3(0, 0, 0))),
         cars={
             0:
             CarState(physics=Physics(location=Vector3(
                 rng.uniform(-100, -90), -2200, 25),
                                      rotation=Rotator(0, pi / 2, 0),
                                      velocity=Vector3(0, 1000, 0),
                                      angular_velocity=Vector3(0, 0, 0)),
                      boost_amount=80),
             1:
             CarState(physics=Physics(
                 location=Vector3(10000, 10000, 10000)))
         },
     )
Пример #15
0
    def get_output(self, packet: GameTickPacket) -> SimpleControllerState:
        if self.wait:
            if self.timer(packet.game_info.seconds_elapsed) < 0.1:
                self.set_game_state(GameState(game_info=GameInfoState(game_speed=self.speed)))
                return SimpleControllerState()
            self.reset()
            self.wait = False
            self.timer.reset()
            self.controller.timer.reset()
            return SimpleControllerState()

        self.controller.update(packet)

        self.state = game_state_to_torch_state(packet, self.index)

        done, reward = self.get_reward()
        if self.action is not None:
            self.action = self.ai.run_step(self.state, reward, done)
        else:
            self.action = self.ai.init_run(self.state)

        self.reward += reward
        if done:
            if reward < 0:
                self.send_quick_chat(False, QuickChatSelection.Apologies_Whoops)
                self.wait = True
            else:
                self.send_quick_chat(False, QuickChatSelection.Compliments_WhatAPlay)
                self.reset()
            
            self.last_reward = self.reward * 0.05 + self.last_reward * 0.95
            print('Avg Reward:', self.last_reward, 'Replay Size:', len(self.ai.replay))
            self.ai.save('model.pt')
            self.reward = 0
            
        
        return torch_action_to_game_action(self.action)
Пример #16
0
    def set_state(self):
        number = int(self.time) % 20
        enemy_state = CarState(physics=Physics(location=Vector3(
            x=0, y=self.enemy_goal_loc[1], z=100),
                                               rotation=Rotator(0, 0, 0)))

        car_state = CarState(boost_amount=100,
                             physics=Physics(location=Vector3(x=-1500,
                                                              y=-4000,
                                                              z=20),
                                             rotation=Rotator(
                                                 0, math.pi / 2, 0),
                                             velocity=Vector3(x=0, y=1000,
                                                              z=0)))
        ball_state = BallState(
            Physics(location=Vector3(-2000, -3000, 700),
                    velocity=Vector3(x=00, y=500, z=200)))
        game_info_state = GameInfoState(game_speed=0.3)
        game_state = GameState(ball=ball_state,
                               cars={self.index: car_state},
                               game_info=game_info_state)
        # game_state = GameState(cars={self.index: car_state})
        #if keyboardd.is_pressed('t'):
        self.set_game_state(game_state)
Пример #17
0
    def run_loop_with_chat_buffer(self, desired_port: int):
        port = find_usable_port(desired_port)
        broker_server_thread = Thread(target=run_twitch_broker_server,
                                      args=(port, ))
        broker_server_thread.setDaemon(True)
        broker_server_thread.start()
        client_registry.CLIENT_REGISTRY = client_registry.ActionServerRegistry(
        )

        aggregator = AvailableActionAggregator()

        command_count = 0
        recent_commands = []
        recent_menus = []
        stop_list = set()

        overlay_data = OverlayData('', [], [], [])
        self.write_json_for_overlay(overlay_data)

        while True:
            packet = self.get_game_tick_packet()
            while not packet.game_info.is_round_active:
                sleep(.2)
                packet = self.get_game_tick_packet()
            if self.broker_settings.pause_on_menu and overlay_data.num_actions(
            ) > 0:
                self.set_game_state(
                    GameState(game_info=GameInfoState(game_speed=0.01)))

            all_actions = aggregator.fetch_all()
            if len(all_actions) == 0:
                sleep(0.1)
                continue
            self.menu_id = generate_menu_id()
            overlay_data = generate_menu(all_actions, self.menu_id,
                                         recent_commands, packet)
            self.write_json_for_overlay(overlay_data)
            recent_menus.insert(0, overlay_data)
            if len(recent_menus
                   ) > self.broker_settings.num_old_menus_to_honor + 1:
                recent_menus.pop()

            made_selection_on_latest_menu = False
            while not made_selection_on_latest_menu:
                while not self.chat_buffer.has_chat():
                    sleep(0.1)
                chat_line = self.chat_buffer.dequeue_chat()
                text = chat_line.message
                for menu_index, menu in enumerate(recent_menus):
                    match = re.search(menu.menu_id + '([0-9]+)', text,
                                      re.IGNORECASE)
                    stop_string = f'{match}{chat_line.username}'
                    if match is not None and stop_string not in stop_list:
                        choice_num = int(match.group(1))
                        choice = menu.retrieve_choice(choice_num)
                        if not choice:
                            print(f"Invalid choice number {choice_num}")
                            continue
                        action_api = aggregator.get_action_api(
                            choice.action_server_id)
                        result = action_api.choose_action(
                            ActionChoice(action=choice.bot_action))
                        command_count += 1
                        recent_commands.append(
                            CommandAcknowledgement(
                                chat_line.username,
                                choice.bot_action.description, "success",
                                str(command_count)))
                        stop_list.add(stop_string)
                        if len(recent_commands) > 10:
                            recent_commands.pop(
                                0)  # Get rid of the oldest command

                        # This causes the new command acknowledgement to get published. The overlay_data has an
                        # internal reference to recent_commands.
                        self.write_json_for_overlay(overlay_data)
                        if menu_index == 0:
                            made_selection_on_latest_menu = True
                            if self.broker_settings.pause_on_menu:
                                self.set_game_state(
                                    GameState(game_info=GameInfoState(
                                        game_speed=1)))
                                sleep(self.broker_settings.
                                      play_time_between_pauses)
                        break
Пример #18
0
    def process_chat(self):
        if not self.game_tick_packet.game_info.is_round_active:
            self.vote_trackers.clear()
            return

        if not self.chat_buffer.has_chat():
            return

        chat_line = self.chat_buffer.dequeue_chat()
        text = chat_line.message
        for menu_index, menu in enumerate(self.recent_menus):
            match = re.search(menu.menu_id + '([0-9]+)', text, re.IGNORECASE)
            if match is None:
                continue
            stop_string = f'{match.group(0)}{chat_line.username}'
            if stop_string not in self.stop_list:
                choice_num = int(match.group(1))
                choice = menu.retrieve_choice(choice_num)
                if not choice:
                    print(f"Invalid choice number {choice_num}")
                    continue
                votes_needed_key = choice.entity_name.lower()
                if votes_needed_key in self.broker_settings.votes_needed:
                    votes_needed = self.broker_settings.votes_needed[
                        votes_needed_key]
                    if votes_needed > 1:
                        if choice.bot_action.description not in self.vote_trackers:
                            self.vote_trackers[
                                choice.bot_action.description] = VoteTracker(
                                    votes_needed, menu.menu_id, [])
                        vote_tracker = self.vote_trackers[
                            choice.bot_action.description]
                        vote_tracker.register_vote(chat_line.username)
                        self.write_json_for_overlay(self.recent_menus[0])
                        if not vote_tracker.has_needed_votes():
                            continue
                        # Vote successful! Clear out the vote tracker.
                        self.vote_trackers.pop(choice.bot_action.description)
                action_api = self.aggregator.get_action_api(
                    choice.action_server_id)
                self.command_count += 1
                try:
                    result = action_api.choose_action(
                        ActionChoice(action=choice.bot_action,
                                     entity_name=choice.entity_name))
                    status = "success" if result.code == 200 else "error"
                    description = choice.bot_action.description if result.code == 200 else result.reason
                    self.recent_commands.append(
                        CommandAcknowledgement(chat_line.username,
                                               description, status,
                                               str(self.command_count)))
                    if result.code == 200:
                        self.stop_list.add(stop_string)
                except Exception as e:
                    self.recent_commands.append(
                        CommandAcknowledgement(chat_line.username,
                                               str(e), "error",
                                               str(self.command_count)))
                    print(e)
                if len(self.recent_commands) > 10:
                    self.recent_commands.pop(
                        0)  # Get rid of the oldest command

                # This causes the new command acknowledgement to get published. The overlay_data has an
                # internal reference to recent_commands.
                self.write_json_for_overlay(self.recent_menus[0])
                if menu_index == 0:
                    self.needs_new_menu = True
                    if self.broker_settings.pause_on_menu:
                        self.set_game_state(
                            GameState(game_info=GameInfoState(game_speed=1)))
                        self.next_menu_moment = self.game_tick_packet.game_info.seconds_elapsed + self.broker_settings.play_time_between_pauses
                break
Пример #19
0
def zero_g(s):
    from rlbot.utils.game_state_util import GameState, GameInfoState

    game_info_state = GameInfoState(world_gravity_z=-0.1, game_speed=1.5)
    game_state = GameState(game_info=game_info_state)
    s.set_game_state(game_state)
Пример #20
0
    def __init__(self, car, training_name="Diagonal_Kickoff"):
        self.car_state = CarState()
        self.ball_state = BallState()
        self.game_info_state = GameInfoState(game_speed=1)
        self.game_state = GameState()
        self.training_name = training_name
        self.car = car

        # Default values
        self.car_loc = None
        self.car_rot = None
        self.car_vel = None
        self.car_av = None
        self.car_boost = 100

        self.ball_loc = None
        self.ball_vel = None
        self.ball_av = None

        def reset_car():
            self.car_loc = Vector3(0, 3000, 18)
            self.car_rot = gsu_rot(-0.016, 0, 0)
            self.car_vel = Vector3(0, 0, 0)
            self.car_av = Vector3(0, 0, 0)
            self.car_boost = 33

        def reset_ball():
            self.ball_loc = Vector3(0, 0, 93)
            self.ball_vel = Vector3(0, 0, 0)
            self.ball_av = Vector3(0, 0, 0)

        if (training_name == "Diagonal Kickoff"):
            reset_car()
            reset_ball()
            self.car_loc = Vector3(-2047, 2559, 18)
            self.car_rot = gsu_rot(-0.016, -0.785, 0)

        elif (training_name == "Straight Kickoff"):
            reset_car()
            reset_ball()
            self.car_loc = Vector3(256, 3839, 18)
            self.car_rot = gsu_rot(-0.016, -1.570, 0)

        elif (training_name == "Prediction 1"):
            reset_car()
            reset_ball()
            self.ball_loc = Vector3(2300, 0, 93)
            self.car_rot = gsu_rot(-0.016, -1.570, 0)

        elif (training_name == "Random Ground"):
            reset_car()
            reset_ball()
            self.ball_loc = Vector3(random.random() * arena.x * 0.8,
                                    random.random() * arena.y * 0.8, 93)
            self.car_loc = Vector3(random.random() * arena.x * 0.8,
                                   random.random() * arena.y * 0.8, 18)

        elif (training_name == "Random Ball Impulse"):
            self.ball_vel = Vector3(random.random() * 1000000,
                                    random.random() * 1000000,
                                    random.random() * 1000000)
            self.car_loc = None
            self.ball_loc = None
        else:
            print("Invalid training name: " + training_name)

        self.reset()
Пример #21
0
    def keyboard_input(self):
        # Controls
        # x: Toggle taking control of Botato.
        # WASD to move, Space to jump, N to boost, Left Shift to Powerslide/Air Roll.
        # Numpad /: Save game state
        # Numpad *: Load saved state
        # Numpad +/-: Speed/Slow game
        # Numpad 0-9 to load trainings.

        # Take control of the ball
        if Keyboard.toggles['b']:
            game_state = GameState.create_from_gametickpacket(self.packet)
            # ball_state = game_state.ball_state

            ball_vel = game_state.ball.physics.velocity
            ball_vel.y += Keyboard.is_key_down("t") * 10
            ball_vel.y -= Keyboard.is_key_down("g") * 10
            ball_vel.x += Keyboard.is_key_down("f") * 10
            ball_vel.x -= Keyboard.is_key_down("h") * 10
            ball_state = BallState(Physics(velocity=copy.copy(ball_vel)))

            game_state = GameState(ball=ball_state)
            self.set_game_state(game_state)

        # Take control of Botato
        if Keyboard.toggles['x']:
            self.controller.throttle = Keyboard.is_key_down(
                "w") - Keyboard.is_key_down("s")
            self.controller.pitch = -self.controller.throttle

            self.controller.steer = Keyboard.is_key_down(
                "d") - Keyboard.is_key_down("a")
            self.controller.handbrake = Keyboard.is_key_down("shift")
            if self.controller.handbrake:
                self.controller.roll = self.controller.steer
            else:
                self.controller.yaw = self.controller.steer

            self.controller.jump = Keyboard.is_key_down("space")
            self.controller.boost = Keyboard.is_key_down("n")

        # Go back a snapshot and delete it.
        if Keyboard.was_key_pressed("left"):
            if len(self.snapshots) > 0:
                snapshot = self.snapshots.pop()
                print("Loading snapshot from time: %f" % snapshot[1])
                self.set_game_state(snapshot[0])
                self.last_snapshot = self.game_seconds

        # Load Hard Coded Training scenarios
        if Keyboard.was_key_pressed("2"):
            self.training = Training(self, "Diagonal Kickoff")
        elif Keyboard.was_key_pressed("3"):
            self.training = Training(self, "Straight Kickoff")
        elif Keyboard.was_key_pressed("4"):
            self.training = Training(self, "Prediction 1")
        elif Keyboard.was_key_pressed("`"):
            self.training = Training(self, "Random Ball Impulse")
        # Reset current training, without changing randomization.
        if Keyboard.was_key_pressed("r"):
            if self.training:
                self.training.reset()

        ### Choose and load scenario
        # Check which numpad keys were pressed this tick

        numpad_keys = [
            "[0]", "[1]", "[2]", "[3]", "[4]", "[5]", "[6]", "[7]", "[8]",
            "[9]"
        ]
        numpad_keys_pressed = {
            key: Keyboard.was_key_pressed(key)
            for key in numpad_keys
        }
        for key_name in list(numpad_keys_pressed.keys()):
            if numpad_keys_pressed[key_name]:
                self.scenario_number = int(
                    str(self.scenario_number) + key_name[1])

        if Keyboard.was_key_pressed("up"):
            self.scenario_number += 1
        if Keyboard.was_key_pressed("down"):
            self.scenario_number -= 1
            if self.scenario_number < 0:
                self.scenario_number = 0

        if Keyboard.was_key_pressed("backspace"):
            string_number = str(self.scenario_number)
            if len(string_number) == 1:
                self.scenario_number = 0
            else:
                self.scenario_number = int(string_number[:-1])

        filepath = os.path.dirname(
            os.path.abspath(__file__)) + "\\Scenarios\\" + str(
                self.scenario_number) + ".json"
        # Save scenario to file
        if Keyboard.was_key_pressed("/"):
            print("Saving game state...")
            save_load.save_for_team(self.packet, filepath, self.team)

        # Load scenario from file
        if Keyboard.was_key_pressed("enter"):
            print("Loading game state...")

            packet_from_file = save_load.load_for_team(self.packet, filepath,
                                                       self.team)
            game_state_from_file = GameState.create_from_gametickpacket(
                packet_from_file)

            self.set_game_state(game_state_from_file)

        # Change Game Speed
        if Keyboard.was_key_pressed("-"):
            self.game_speed = max(self.game_speed - 0.2, 0.2)
            game_info_state = GameInfoState(game_speed=self.game_speed)
            game_state = GameState(game_info=game_info_state)
            self.set_game_state(game_state)
            print("Slowing to %f" % self.game_speed)
        if Keyboard.was_key_pressed("+"):
            self.game_speed += 0.2
            game_info_state = GameInfoState(game_speed=self.game_speed)
            game_state = GameState(game_info=game_info_state)
            self.set_game_state(game_state)
            print("Speeding to %f" % self.game_speed)

        Keyboard.wipe_buttons_pressed()