Skip to content

Commit 139ec32

Browse files
committed
New spec
1 parent 3d554a4 commit 139ec32

File tree

18 files changed

+202
-94
lines changed

18 files changed

+202
-94
lines changed

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ description = "A high performance Python interface for communicating with RLBot
88
dynamic = ["version"]
99
requires-python = ">= 3.11"
1010
dependencies = [
11-
"rlbot_flatbuffers~=0.6.0",
11+
"rlbot_flatbuffers~=0.7.0",
1212
"psutil==6.*",
1313
]
1414
readme = "README.md"

rlbot/interface.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,10 @@ class SocketDataType(IntEnum):
2929
REMOVE_RENDER_GROUP = 8
3030
MATCH_COMMUNICATION = 9
3131
BALL_PREDICTION = 10
32-
READY_MESSAGE = 11
32+
CONNECTION_SETTINGS = 11
3333
STOP_COMMAND = 12
34+
SET_LOADOUT = 13
35+
INIT_COMPLETE = 14
3436

3537

3638
MAX_SIZE_2_BYTES = 2**16 - 1
@@ -91,6 +93,12 @@ def send_bytes(self, data: bytes, data_type: SocketDataType):
9193
message = int_to_bytes(data_type) + int_to_bytes(size) + data
9294
self.socket.sendall(message)
9395

96+
def send_init_complete(self, init_complete: flat.InitComplete):
97+
self.send_bytes(init_complete.pack(), SocketDataType.INIT_COMPLETE)
98+
99+
def send_set_loadout(self, set_loadout: flat.SetLoadout):
100+
self.send_bytes(set_loadout.pack(), SocketDataType.SET_LOADOUT)
101+
94102
def send_match_comm(self, match_comm: flat.MatchComm):
95103
self.send_bytes(match_comm.pack(), SocketDataType.MATCH_COMMUNICATION)
96104

@@ -180,12 +188,12 @@ def connect_and_run(
180188
for handler in self.on_connect_handlers:
181189
handler()
182190

183-
flatbuffer = flat.ReadyMessage(
191+
flatbuffer = flat.ConnectionSettings(
184192
wants_ball_predictions,
185193
wants_match_communcations,
186194
close_after_match,
187195
).pack()
188-
self.send_bytes(flatbuffer, SocketDataType.READY_MESSAGE)
196+
self.send_bytes(flatbuffer, SocketDataType.CONNECTION_SETTINGS)
189197

190198
incoming_message = read_from_socket(self.socket)
191199
self.handle_incoming_message(incoming_message)

rlbot/managers/bot.py

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ def __init__(self):
4141
self._game_interface.match_settings_handlers.append(self._handle_match_settings)
4242
self._game_interface.field_info_handlers.append(self._handle_field_info)
4343
self._game_interface.match_communication_handlers.append(
44-
self._handle_match_communication
44+
self.handle_match_communication
4545
)
4646
self._game_interface.ball_prediction_handlers.append(
4747
self._handle_ball_prediction
@@ -61,6 +61,7 @@ def _initialize_agent(self):
6161
exit()
6262

6363
self._initialized_bot = True
64+
self._game_interface.send_init_complete(flat.InitComplete(self.spawn_id))
6465

6566
def _handle_match_settings(self, match_settings: flat.MatchSettings):
6667
self.match_settings = match_settings
@@ -84,19 +85,10 @@ def _handle_field_info(self, field_info: flat.FieldInfo):
8485
if not self._initialized_bot and self._has_match_settings:
8586
self._initialize_agent()
8687

87-
def _handle_match_communication(self, match_comm: flat.MatchComm):
88-
if match_comm.team_only and self.team != match_comm.team:
89-
return
90-
91-
self.handle_match_communication(match_comm)
92-
9388
def _handle_ball_prediction(self, ball_prediction: flat.BallPrediction):
9489
self.ball_prediction = ball_prediction
9590

9691
def _handle_packet(self, packet: flat.GameTickPacket):
97-
if not self._initialized_bot:
98-
return
99-
10092
if (
10193
self.index == -1
10294
or len(packet.players) <= self.index
@@ -184,6 +176,15 @@ def set_game_state(self, game_state: flat.DesiredGameState):
184176
"""
185177
self._game_interface.send_game_state(game_state)
186178

179+
def set_loadout(self, loadout: flat.PlayerLoadout, spawn_id: int):
180+
"""
181+
Sets the loadout of a bot.
182+
183+
For use as a loadout generator, call inside of `initialize_agent`.
184+
Will be ignored if called outside of `initialize_agent` when state setting is disabled.
185+
"""
186+
self._game_interface.send_set_loadout(flat.SetLoadout(spawn_id, loadout))
187+
187188
def initialize_agent(self):
188189
"""
189190
Called for all heaver initialization that needs to happen.

rlbot/managers/hivemind.py

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ def __init__(self):
4242
self._game_interface.match_settings_handlers.append(self._handle_match_settings)
4343
self._game_interface.field_info_handlers.append(self._handle_field_info)
4444
self._game_interface.match_communication_handlers.append(
45-
self._handle_match_communication
45+
self.handle_match_communication
4646
)
4747
self._game_interface.ball_prediction_handlers.append(
4848
self._handle_ball_prediction
@@ -51,6 +51,21 @@ def __init__(self):
5151

5252
self.renderer = Renderer(self._game_interface)
5353

54+
def _initialize_agent(self):
55+
try:
56+
self.initialize_agent()
57+
except Exception as e:
58+
self._logger.critical(
59+
"Hivemind %s failed to initialize due the following error: %s",
60+
"Unknown" if len(self.names) == 0 else self.names[0],
61+
e,
62+
)
63+
print_exc()
64+
exit()
65+
66+
self._initialized_bot = True
67+
self._game_interface.send_init_complete(flat.InitComplete(self.spawn_ids[0]))
68+
5469
def _handle_match_settings(self, match_settings: flat.MatchSettings):
5570
self.match_settings = match_settings
5671
self._has_match_settings = True
@@ -64,30 +79,19 @@ def _handle_match_settings(self, match_settings: flat.MatchSettings):
6479
break
6580

6681
if not self._initialized_bot and self._has_field_info:
67-
self.initialize_agent()
68-
self._initialized_bot = True
82+
self._initialize_agent()
6983

7084
def _handle_field_info(self, field_info: flat.FieldInfo):
7185
self.field_info = field_info
7286
self._has_field_info = True
7387

7488
if not self._initialized_bot and self._has_match_settings:
75-
self.initialize_agent()
76-
self._initialized_bot = True
77-
78-
def _handle_match_communication(self, match_comm: flat.MatchComm):
79-
if match_comm.team_only and self.team != match_comm.team:
80-
return
81-
82-
self.handle_match_communication(match_comm)
89+
self._initialize_agent()
8390

8491
def _handle_ball_prediction(self, ball_prediction: flat.BallPrediction):
8592
self.ball_prediction = ball_prediction
8693

8794
def _handle_packet(self, packet: flat.GameTickPacket):
88-
if not self._initialized_bot:
89-
return
90-
9195
if len(self.indicies) != len(self.spawn_ids) or any(
9296
packet.players[i].spawn_id not in self.spawn_ids for i in self.indicies
9397
):
@@ -178,6 +182,15 @@ def set_game_state(self, game_state: flat.DesiredGameState):
178182
"""
179183
self._game_interface.send_game_state(game_state)
180184

185+
def set_loadout(self, loadout: flat.PlayerLoadout, spawn_id: int):
186+
"""
187+
Sets the loadout of a bot.
188+
189+
For use as a loadout generator, call inside of `initialize_agent`.
190+
Will be ignored if called outside of `initialize_agent` when state setting is disabled.
191+
"""
192+
self._game_interface.send_set_loadout(flat.SetLoadout(spawn_id, loadout))
193+
181194
def initialize_agent(self):
182195
"""
183196
Called for all heaver initialization that needs to happen.

rlbot/managers/match.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,13 @@ def get_player_config(
7272
if CURRENT_OS == OS.LINUX and "run_command_linux" in settings:
7373
run_command = settings["run_command_linux"]
7474

75-
loadout_path = settings.get("looks_config", None)
75+
loadout_path = settings.get("loadout_config", None)
76+
77+
if loadout_path is None:
78+
loadout_path = settings.get("looks_config", None)
79+
if loadout_path is not None:
80+
DEFAULT_LOGGER.error("looks_config is deprecated, use loadout_config.")
81+
7682
if loadout_path is not None:
7783
loadout_path = parent / loadout_path
7884

@@ -97,7 +103,6 @@ def get_player_config(
97103
class MatchManager:
98104
logger = DEFAULT_LOGGER
99105
packet: Optional[flat.GameTickPacket] = None
100-
game_state = flat.GameStateType.Inactive
101106
rlbot_server_process: Optional[psutil.Process] = None
102107
rlbot_server_port = RLBOT_SERVER_PORT
103108

@@ -143,10 +148,9 @@ def ensure_server_started(self, print_version_info: bool = True):
143148

144149
def _packet_reporter(self, packet: flat.GameTickPacket):
145150
self.packet = packet
146-
self.game_state = packet.game_info.game_state_type
147151

148152
def wait_for_valid_packet(self):
149-
while self.game_state in {
153+
while self.packet is not None and self.packet.game_info.game_state_type in {
150154
flat.GameStateType.Inactive,
151155
flat.GameStateType.Ended,
152156
}:
@@ -157,6 +161,7 @@ def start_match(
157161
):
158162
self.logger.info("Python attempting to start match.")
159163
self.rlbot_interface.start_match(match_config, self.rlbot_server_port)
164+
self.rlbot_interface.send_init_complete(flat.InitComplete())
160165

161166
if wait_for_start:
162167
self.wait_for_valid_packet()

0 commit comments

Comments
 (0)