11import os
2+ from threading import Event , Thread
23from traceback import print_exc
34from typing import Optional
45
@@ -29,6 +30,12 @@ class Hivemind:
2930 _has_match_settings = False
3031 _has_field_info = False
3132
33+ _latest_packet = flat .GameTickPacket ()
34+ _lastest_prediction = flat .BallPrediction ()
35+ _packet_event = Event ()
36+ _packet_thread = None
37+ _run_packet_thread = True
38+
3239 def __init__ (self ):
3340 spawn_ids = os .environ .get ("RLBOT_SPAWN_IDS" )
3441
@@ -49,6 +56,9 @@ def __init__(self):
4956 )
5057 self ._game_interface .packet_handlers .append (self ._handle_packet )
5158
59+ self ._packet_thread = Thread (target = self ._packet_processor , daemon = True )
60+ self ._packet_thread .start ()
61+
5262 self .renderer = Renderer (self ._game_interface )
5363
5464 def _initialize_agent (self ):
@@ -76,7 +86,6 @@ def _handle_match_settings(self, match_settings: flat.MatchSettings):
7686 self .team = player .team
7787 self .names .append (player .name )
7888 self .loggers [i ] = get_logger (player .name )
79- break
8089
8190 if not self ._initialized_bot and self ._has_field_info :
8291 self ._initialize_agent ()
@@ -89,9 +98,13 @@ def _handle_field_info(self, field_info: flat.FieldInfo):
8998 self ._initialize_agent ()
9099
91100 def _handle_ball_prediction (self , ball_prediction : flat .BallPrediction ):
92- self .ball_prediction = ball_prediction
101+ self ._lastest_prediction = ball_prediction
93102
94103 def _handle_packet (self , packet : flat .GameTickPacket ):
104+ self ._latest_packet = packet
105+ self ._packet_event .set ()
106+
107+ def _packet_preprocess (self , packet : flat .GameTickPacket ) -> bool :
95108 if len (self .indicies ) != len (self .spawn_ids ) or any (
96109 packet .players [i ].spawn_id not in self .spawn_ids for i in self .indicies
97110 ):
@@ -102,20 +115,35 @@ def _handle_packet(self, packet: flat.GameTickPacket):
102115 ]
103116
104117 if len (self .indicies ) != len (self .spawn_ids ):
105- return
118+ return False
106119
107- try :
108- controller = self .get_outputs (packet )
109- except Exception as e :
110- self ._logger .error (
111- "Hivemind (with %s) returned an error to RLBot: %s" , self .names , e
112- )
113- print_exc ()
114- return
120+ # print([player.name for player in packet.players], self.spawn_ids, self.indicies)
121+ return True
122+
123+ def _packet_processor (self ):
124+ while self ._run_packet_thread :
125+ self ._packet_event .wait ()
126+
127+ self .ball_prediction = self ._lastest_prediction
128+ packet = self ._latest_packet
129+
130+ self ._packet_event .clear ()
131+
132+ if not self ._packet_preprocess (self ._latest_packet ):
133+ continue
134+
135+ try :
136+ controller = self .get_outputs (packet )
137+ except Exception as e :
138+ self ._logger .error (
139+ "Hivemind (with %s) returned an error to RLBot: %s" , self .names , e
140+ )
141+ print_exc ()
142+ continue
115143
116- for index , controller in controller .items ():
117- player_input = flat .PlayerInput (index , controller )
118- self ._game_interface .send_player_input (player_input )
144+ for index , controller in controller .items ():
145+ player_input = flat .PlayerInput (index , controller )
146+ self ._game_interface .send_player_input (player_input )
119147
120148 def run (
121149 self ,
0 commit comments