Skip to content

Beta 48 #34

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 6 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ pyrightconfig.json

# End of https://www.toptal.com/developers/gitignore/api/python

uv.lock
.vscode/
*.obj
RLBotServer*
Expand Down
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,11 @@ The following is how to setup a development environment for this project, NOT ho
- `pip uninstall rlbot_flatbuffers`
- `pip install --editable <path/to/rlbot_flatbuffers>`

This project is formatted using [Black](https://github.com/psf/black).
This project is formatted using [Ruff](https://docs.astral.sh/ruff/formatter/).

- Install: `pip install black`.
- Use: `black .`
- Install: `pip install ruff`.
- Sort imports: `ruff check --select I --fix`
- Format code: `ruff format`

## Testing

Expand Down
9 changes: 9 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,12 @@ Repository = "https://github.com/RLBot/python-interface"

[tool.setuptools.dynamic]
version = {attr = "rlbot.version.__version__"}

[dependency-groups]
dev = [
"ruff>=0.12.5",
"toml>=0.10.2",
]

[tool.ruff.format]
docstring-code-format = true
2 changes: 1 addition & 1 deletion rlbot/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
from .version import __version__
from .version import __version__ as __version__
10 changes: 8 additions & 2 deletions rlbot/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
from typing import Any, Literal

import rlbot.flat as flat
from rlbot.utils.logging import DEFAULT_LOGGER as logger
from rlbot.utils.os_detector import CURRENT_OS, OS


Expand Down Expand Up @@ -112,7 +111,7 @@ def load_match_config(config_path: Path | str) -> flat.MatchConfiguration:
)
)
case "human":
players.append(flat.PlayerConfiguration(flat.Human(), team, 0))
players.append(get_human(team))
case t:
raise ConfigParsingException(
f"Invalid player type {repr(t)} for player {len(players)}."
Expand Down Expand Up @@ -323,6 +322,13 @@ def load_psyonix_config(
)


def get_human(team: int) -> flat.PlayerConfiguration:
"""
Creates a `PlayerConfiguration` for a human player on the given team.
"""
return flat.PlayerConfiguration(flat.Human(), team)


def load_script_config(path: Path | str) -> flat.ScriptConfiguration:
"""
Reads the script toml file at the provided path and creates a `ScriptConfiguration` from it.
Expand Down
6 changes: 3 additions & 3 deletions rlbot/interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ def disconnect(self):
self.logger.critical("RLBot is not responding to our disconnect request!?")
self._running = False

assert (
not self._running
), "Disconnect request or timeout should have set self._running to False"
assert not self._running, (
"Disconnect request or timeout should have set self._running to False"
)
self.is_connected = False
6 changes: 3 additions & 3 deletions rlbot/managers/match.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ def connect(
rlbot_server_ip=rlbot_server_ip,
rlbot_server_port=rlbot_server_port or self.rlbot_server_port,
)
self.rlbot_interface.run(background_thread=True)

def wait_for_first_packet(self):
while self.packet is None or self.packet.match_info.match_phase in {
Expand Down Expand Up @@ -122,7 +123,6 @@ def start_match(
wants_ball_predictions=False,
close_between_matches=False,
)
self.rlbot_interface.run(background_thread=True)

self.rlbot_interface.start_match(config)

Expand All @@ -136,7 +136,7 @@ def start_match(

def disconnect(self):
"""
Disconnect from the RLBotServer.
Disconnect from RLBotServer.
Note that the server will continue running as long as Rocket League does.
"""
self.rlbot_interface.disconnect()
Expand Down Expand Up @@ -167,8 +167,8 @@ def shut_down(self, use_force_if_necessary: bool = True):

self.logger.info("Shutting down RLBot...")

# In theory this is all we need for the server to cleanly shut itself down
try:
# In theory this is all we need for the server to cleanly shut itself down
self.rlbot_interface.stop_match(shutdown_server=True)
except BrokenPipeError:
match gateway.find_server_process(self.main_executable_name)[0]:
Expand Down
4 changes: 2 additions & 2 deletions rlbot/utils/maps.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@
"FuturaGarden": "UF_Day_P",
"DFHStadium_Anniversary": "stadium_10a_p",
"Holyfield": "Labs_Holyfield_Space_P",
"DriftWoods_Night": "woods_night_p"
"DriftWoods_Night": "woods_night_p",
}

STANDARD_MAPS = [
Expand Down Expand Up @@ -138,5 +138,5 @@
"Neotokyo_Arcade",
"FuturaGarden",
"DFHStadium_Anniversary",
"DriftWoods_Night"
"DriftWoods_Night",
]
2 changes: 1 addition & 1 deletion rlbot/version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "2.0.0-beta.47"
__version__ = "2.0.0-beta.48"
2 changes: 1 addition & 1 deletion tests/atba/atba.bot.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ root_dir = ""
run_command = "..\\..\\venv\\Scripts\\python atba.py"
# The command RLBot will call to start your bot on linux
# If this isn't set, RLBot may attempt to run the Windows command under Wine
run_command_linux = "../../venv/bin/python atba.py"
run_command_linux = "../../.venv/bin/python atba.py"

[details]
description = "Made possible by RLBot"
Expand Down
23 changes: 6 additions & 17 deletions tests/atba/atba.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from __future__ import annotations

import math
from typing import Optional

from rlbot import flat
from rlbot.managers import Bot
Expand Down Expand Up @@ -67,9 +66,9 @@ def __init__(self):

def initialize(self):
self.logger.info("Initializing agent!")

num_boost_pads = len(self.field_info.boost_pads)
self.logger.info(f"There are {num_boost_pads} boost pads on the field.")
self.logger.info(
f"There are {len(self.field_info.boost_pads)} boost pads and {len(self.field_info.goals)} goals on the field."
)

if self.rendering:
self.renderer.begin_rendering("custom one-time rendering group")
Expand All @@ -83,16 +82,6 @@ def initialize(self):
)
self.renderer.end_rendering()

def handle_match_comm(
self,
index: int,
team: int,
content: bytes,
display: Optional[str],
team_only: bool,
):
self.logger.info(f"Received match communication from index {index}! {display}")

def get_output(self, packet: flat.GamePacket) -> flat.ControllerState:
if self.rendering:
self.test_rendering(packet)
Expand All @@ -110,10 +99,10 @@ def get_output(self, packet: flat.GamePacket) -> flat.ControllerState:
if self.state_setting:
self.test_state_setting(packet)

if self.match_comms:
if self.match_comms and packet.match_info.match_phase == flat.MatchPhase.Active:
# Limit packet spam
if packet.match_info.frame_num - self.last_send >= 360:
self.send_match_comm(b"", "Hello world!", True)
self.send_match_comm(b"", "Hello world!", False)
self.last_send = packet.match_info.frame_num

ball_location = Vector2(packet.balls[0].physics.location)
Expand Down Expand Up @@ -145,7 +134,7 @@ def test_state_setting(self, packet: flat.GamePacket):
i: flat.DesiredCarState(
flat.DesiredPhysics(rotation=flat.RotatorPartial(yaw=0))
)
for i, car in enumerate(packet.players)
for i in range(len(packet.players))
},
)

Expand Down
6 changes: 3 additions & 3 deletions tests/cfg_to_toml.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,9 @@ def convert_to_toml(self) -> dict[str, dict[str, Any]]:

toml_dict["settings"] = self._convert_settings()
toml_dict["details"] = self._convert_details()
toml_dict["settings"][
"agent_id"
] = f"{toml_dict["details"]["developer"]}/{toml_dict["settings"]["name"]}"
toml_dict["settings"]["agent_id"] = (
f"{toml_dict['details']['developer']}/{toml_dict['settings']['name']}"
)

return toml_dict

Expand Down
2 changes: 1 addition & 1 deletion tests/fashion/bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def get_output(self, packet: flat.GamePacket) -> flat.ControllerState:
),
)

self.logger.info(f"State setting new loadout")
self.logger.info("State setting new loadout")
self.set_loadout(loadout)
self.last_tick = packet.match_info.frame_num

Expand Down
84 changes: 84 additions & 0 deletions tests/many_match.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
from pathlib import Path
from time import sleep

from rlbot import flat
from rlbot.config import load_player_config
from rlbot.managers import MatchManager

DIR = Path(__file__).parent

BOT_PATH = DIR / "atba/atba.bot.toml"
RLBOT_SERVER_FOLDER = DIR / "../../core/RLBotCS/bin/Release/"

num_comms = set()


def handle_match_comm(comm: flat.MatchComm):
global num_comms
if comm.team < 2:
num_comms.add(comm.index)


if __name__ == "__main__":
match_manager = MatchManager(RLBOT_SERVER_FOLDER)
match_manager.rlbot_interface.match_comm_handlers.append(handle_match_comm)
match_manager.ensure_server_started()
match_manager.connect(
wants_match_communications=True,
wants_ball_predictions=False,
close_between_matches=False,
)

current_map = -1

blue_bot = load_player_config(BOT_PATH, 0)
orange_bot = load_player_config(BOT_PATH, 1)

match_settings = flat.MatchConfiguration(
launcher=flat.Launcher.Steam,
auto_start_agents=True,
wait_for_agents=True,
existing_match_behavior=flat.ExistingMatchBehavior.Restart,
game_map_upk="Stadium_P",
instant_start=True,
enable_state_setting=True,
player_configurations=[
blue_bot,
blue_bot,
blue_bot,
blue_bot,
blue_bot,
orange_bot,
orange_bot,
orange_bot,
orange_bot,
orange_bot,
],
)

num_games = 0
paused = False

while not paused:
num_games += 1
print(f"Starting match # {num_games}")

match_manager.start_match(match_settings, ensure_server_started=False)
# when calling start_match, by default it will wait for the first packet
assert match_manager.packet is not None

sleep(2)
num_comms.clear()
while len(num_comms) < 10:
# give an extra 5 seconds for the match to start before calling it a failure
if (
match_manager.packet.match_info.match_phase == flat.MatchPhase.Active
and match_manager.packet.match_info.game_time_remaining < 60 * 4 + 55
):
match_manager.set_game_state(commands=["Pause"])
paused = True
break
sleep(1)

print("Failed to start match. Paused and exiting.")
match_manager.disconnect()
1 change: 0 additions & 1 deletion tests/nexto/bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,6 @@ def toxicity(self, packet: GamePacket):
return

for p in human_opps:

d = math.sqrt(
(p.physics.location.x - bad_goal[0]) ** 2
+ (p.physics.location.y - bad_goal[1]) ** 2
Expand Down
3 changes: 1 addition & 2 deletions tests/nexto/nexto_obs.py
Original file line number Diff line number Diff line change
Expand Up @@ -286,8 +286,7 @@ def batched_build_obs(self, encoded_states: np.ndarray):
for i in range(n_players):
encoded_player = encoded_states[
:,
players_start_index
+ i * player_length : players_start_index
players_start_index + i * player_length : players_start_index
+ (i + 1) * player_length,
]

Expand Down
1 change: 0 additions & 1 deletion tests/run_forever.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@

if __name__ == "__main__":
match_manager = MatchManager(RLBOT_SERVER_FOLDER)
match_manager.ensure_server_started()

current_map = -1

Expand Down
3 changes: 1 addition & 2 deletions tests/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
match_manager = MatchManager(RLBOT_SERVER_FOLDER)

try:
match_manager.ensure_server_started()
match_manager.start_match(MATCH_CONFIG_PATH)

logger.info("Waiting before shutdown...")
Expand All @@ -25,7 +24,7 @@
except KeyboardInterrupt:
logger.warning("Shutting down early due to interrupt")
except Exception:
logger.critical(f"Shutting down early due to the following error:")
logger.critical("Shutting down early due to the following error:")
print_exc()

match_manager.shut_down()