Skip to content

Commit bf99cad

Browse files
committed
Update Hivemind & Script
1 parent 602fe40 commit bf99cad

File tree

3 files changed

+99
-57
lines changed

3 files changed

+99
-57
lines changed

rlbot/managers/bot.py

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -65,14 +65,6 @@ def _initialize_agent(self):
6565
self.logger = get_logger(self.name)
6666
break
6767

68-
self.logger.info(
69-
"Bot %s initialized - index %s / team %s / spawn id %s",
70-
self.name,
71-
self.index,
72-
self.team,
73-
self.spawn_id,
74-
)
75-
7668
try:
7769
self.initialize_agent()
7870
except Exception as e:

rlbot/managers/hivemind.py

Lines changed: 35 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ class Hivemind:
2929
_initialized_bot = False
3030
_has_match_settings = False
3131
_has_field_info = False
32+
_has_player_mapping = False
3233

3334
_latest_packet: Optional[flat.GameTickPacket] = None
3435
_latest_prediction = flat.BallPrediction()
@@ -54,6 +55,12 @@ def __init__(self):
5455
self.renderer = Renderer(self._game_interface)
5556

5657
def _initialize_agent(self):
58+
# search match settings for our spawn ids
59+
for player in self.match_settings.player_configurations:
60+
if player.spawn_id in self.spawn_ids:
61+
self.names.append(player.name)
62+
self.loggers.append(get_logger(player.name))
63+
5764
try:
5865
self.initialize_agent()
5966
except Exception as e:
@@ -72,21 +79,37 @@ def _handle_match_settings(self, match_settings: flat.MatchSettings):
7279
self.match_settings = match_settings
7380
self._has_match_settings = True
7481

75-
# search match settings for our spawn ids
76-
for player in self.match_settings.player_configurations:
77-
if player.spawn_id in self.spawn_ids:
78-
self.team = player.team
79-
self.names.append(player.name)
80-
self.loggers.append(get_logger(player.name))
81-
82-
if not self._initialized_bot and self._has_field_info:
82+
if (
83+
not self._initialized_bot
84+
and self._has_field_info
85+
and self._has_player_mapping
86+
):
8387
self._initialize_agent()
8488

8589
def _handle_field_info(self, field_info: flat.FieldInfo):
8690
self.field_info = field_info
8791
self._has_field_info = True
8892

89-
if not self._initialized_bot and self._has_match_settings:
93+
if (
94+
not self._initialized_bot
95+
and self._has_match_settings
96+
and self._has_player_mapping
97+
):
98+
self._initialize_agent()
99+
100+
def _handle_player_mappings(self, player_mappings: flat.TeamControllables):
101+
self.team = player_mappings.team
102+
for controllable in player_mappings.controllables:
103+
self.spawn_ids.append(controllable.spawn_id)
104+
self.indices.append(controllable.index)
105+
106+
self._has_player_mapping = True
107+
108+
if (
109+
not self._initialized_bot
110+
and self._has_match_settings
111+
and self._has_field_info
112+
):
90113
self._initialize_agent()
91114

92115
def _handle_ball_prediction(self, ball_prediction: flat.BallPrediction):
@@ -96,17 +119,8 @@ def _handle_packet(self, packet: flat.GameTickPacket):
96119
self._latest_packet = packet
97120

98121
def _packet_processor(self, packet: flat.GameTickPacket):
99-
if len(self.indices) != len(self.spawn_ids) or any(
100-
packet.players[i].spawn_id not in self.spawn_ids for i in self.indices
101-
):
102-
self.indices = [
103-
i
104-
for i, player in enumerate(packet.players)
105-
if player.spawn_id in self.spawn_ids
106-
]
107-
108-
if len(self.indices) != len(self.spawn_ids):
109-
return
122+
if len(packet.players) <= self.indices[-1]:
123+
return
110124

111125
self.ball_prediction = self._latest_prediction
112126

@@ -137,34 +151,18 @@ def run(
137151
rlbot_server_port=rlbot_server_port,
138152
)
139153

140-
# custom message handling logic
141-
# this reads all data in the socket until there's no more immediately available
142-
# checks if there was a GameTickPacket in the data, and if so, processes it
143-
# then sets the socket to non-blocking and waits for more data
144-
# if there was no GameTickPacket, it sets to blocking and waits for more data
154+
# see bot.py for an explanation of this loop
145155
while True:
146156
try:
147157
self._game_interface.handle_incoming_messages(True)
148-
149-
# a clean exit means that the socket was closed
150158
break
151159
except BlockingIOError:
152-
# the socket was still open,
153-
# but we don't know if data was read
154160
pass
155161

156-
# check data was read that needs to be processed
157162
if self._latest_packet is None:
158-
# there's no data we need to process
159-
# data is coming, but we haven't gotten it yet - wait for it
160-
# after `handle_incoming_messages` gets it's first message,
161-
# it will set the socket back to non-blocking on its own
162-
# that will ensure that `BlockingIOError` gets raised
163-
# when it's done reading the next batch of messages
164163
self._game_interface.socket.setblocking(True)
165164
continue
166165

167-
# process the packet that we got
168166
self._packet_processor(self._latest_packet)
169167
self._latest_packet = None
170168
finally:

rlbot/managers/script.py

Lines changed: 64 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ class Script:
2626
_initialized_bot = False
2727
_has_match_settings = False
2828
_has_field_info = False
29+
_has_player_mapping = False
30+
31+
_latest_packet: Optional[flat.GameTickPacket] = None
32+
_latest_prediction = flat.BallPrediction()
2933

3034
def __init__(self):
3135
group_id = os.environ.get("RLBOT_GROUP_ID")
@@ -43,11 +47,14 @@ def __init__(self):
4347
self._game_interface.ball_prediction_handlers.append(
4448
self._handle_ball_prediction
4549
)
46-
self._game_interface.packet_handlers.append(self.handle_packet)
50+
self._game_interface.packet_handlers.append(self._handle_packet)
4751

4852
self.renderer = Renderer(self._game_interface)
4953

5054
def _initialize_agent(self):
55+
self.name = self.match_settings.script_configurations[self.index].name
56+
self.logger = get_logger(self.name)
57+
5158
try:
5259
self.initialize_agent()
5360
except Exception as e:
@@ -66,25 +73,55 @@ def _handle_match_settings(self, match_settings: flat.MatchSettings):
6673
self.match_settings = match_settings
6774
self._has_match_settings = True
6875

69-
# search match settings for our spawn id
70-
for script in self.match_settings.script_configurations:
71-
if script.spawn_id == self.spawn_id or self.spawn_id == 0:
72-
self.name = script.name
73-
self.logger = get_logger(self.name)
74-
break
75-
76-
if not self._initialized_bot and self._has_field_info:
76+
if (
77+
not self._initialized_bot
78+
and self._has_field_info
79+
and self._has_player_mapping
80+
):
7781
self._initialize_agent()
7882

7983
def _handle_field_info(self, field_info: flat.FieldInfo):
8084
self.field_info = field_info
8185
self._has_field_info = True
8286

83-
if not self._initialized_bot and self._has_match_settings:
87+
if (
88+
not self._initialized_bot
89+
and self._has_match_settings
90+
and self._has_player_mapping
91+
):
92+
self._initialize_agent()
93+
94+
def _handle_player_mappings(self, player_mappings: flat.TeamControllables):
95+
self.team = player_mappings.team
96+
controllable = player_mappings.controllables[0]
97+
self.spawn_id = controllable.spawn_id
98+
self.index = controllable.index
99+
self._has_player_mapping = True
100+
101+
if (
102+
not self._initialized_bot
103+
and self._has_match_settings
104+
and self._has_field_info
105+
):
84106
self._initialize_agent()
85107

86108
def _handle_ball_prediction(self, ball_prediction: flat.BallPrediction):
87-
self.ball_prediction = ball_prediction
109+
self._latest_prediction = ball_prediction
110+
111+
def _handle_packet(self, packet: flat.GameTickPacket):
112+
self._latest_packet = packet
113+
114+
def _packet_processor(self, packet: flat.GameTickPacket):
115+
if len(packet.players) <= self.index:
116+
return
117+
118+
self.ball_prediction = self._latest_prediction
119+
120+
try:
121+
self.handle_packet(packet)
122+
except Exception as e:
123+
self.logger.error("Script %s returned an error to RLBot: %s", self.name, e)
124+
print_exc()
88125

89126
def run(
90127
self,
@@ -94,11 +131,26 @@ def run(
94131
rlbot_server_port = int(os.environ.get("RLBOT_SERVER_PORT", 23234))
95132

96133
try:
97-
self._game_interface.connect_and_run(
134+
self._game_interface.connect(
98135
wants_match_communications,
99136
wants_ball_predictions,
100137
rlbot_server_port=rlbot_server_port,
101138
)
139+
140+
# see bot.py for an explanation of this loop
141+
while True:
142+
try:
143+
self._game_interface.handle_incoming_messages(True)
144+
break
145+
except BlockingIOError:
146+
pass
147+
148+
if self._latest_packet is None:
149+
self._game_interface.socket.setblocking(True)
150+
continue
151+
152+
self._packet_processor(self._latest_packet)
153+
self._latest_packet = None
102154
finally:
103155
self.retire()
104156
del self._game_interface

0 commit comments

Comments
 (0)