@@ -27,20 +27,21 @@ class Bot:
2727 _initialized_bot = False
2828 _has_match_settings = False
2929 _has_field_info = False
30+ _has_player_mapping = False
3031
3132 _latest_packet : Optional [flat .GameTickPacket ] = None
3233 _latest_prediction = flat .BallPrediction ()
3334
3435 def __init__ (self ):
35- spawn_id = os .environ .get ("RLBOT_SPAWN_IDS " )
36+ group_id = os .environ .get ("RLBOT_GROUP_ID " )
3637
37- if spawn_id is None :
38- self .logger .warning ("RLBOT_SPAWN_IDS environment variable not set" )
39- else :
40- self .spawn_id = int (spawn_id )
41- self .logger .info ("Spawn ID: %s" , self .spawn_id )
38+ if group_id is None :
39+ self .logger .critical ("RLBOT_GROUP_ID environment variable is not set" )
40+ exit (1 )
4241
43- self ._game_interface = SocketRelay (logger = self .logger )
42+ self .logger .info (group_id )
43+
44+ self ._game_interface = SocketRelay (group_id , logger = self .logger )
4445 self ._game_interface .match_settings_handlers .append (self ._handle_match_settings )
4546 self ._game_interface .field_info_handlers .append (self ._handle_field_info )
4647 self ._game_interface .match_communication_handlers .append (
@@ -49,11 +50,29 @@ def __init__(self):
4950 self ._game_interface .ball_prediction_handlers .append (
5051 self ._handle_ball_prediction
5152 )
53+ self ._game_interface .team_controllables_handlers .append (
54+ self ._handle_player_mappings
55+ )
5256 self ._game_interface .packet_handlers .append (self ._handle_packet )
5357
5458 self .renderer = Renderer (self ._game_interface )
5559
5660 def _initialize_agent (self ):
61+ # search match settings for our name
62+ for player in self .match_settings .player_configurations :
63+ if player .spawn_id == self .spawn_id :
64+ self .name = player .name
65+ self .logger = get_logger (self .name )
66+ break
67+
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+
5776 try :
5877 self .initialize_agent ()
5978 except Exception as e :
@@ -64,36 +83,42 @@ def _initialize_agent(self):
6483 exit ()
6584
6685 self ._initialized_bot = True
67- self ._game_interface .send_init_complete (flat . InitComplete ( self . spawn_id ) )
86+ self ._game_interface .send_init_complete ()
6887
6988 def _handle_match_settings (self , match_settings : flat .MatchSettings ):
7089 self .match_settings = match_settings
7190 self ._has_match_settings = True
7291
73- # search match settings for our spawn id
74- for player in self .match_settings .player_configurations :
75- if player .spawn_id == self .spawn_id :
76- self .team = player .team
77- self .name = player .name
78- self .logger = get_logger (self .name )
79- break
80-
81- if self .spawn_id == 0 :
82- match player .variety .item :
83- case flat .RLBot ():
84- self .team = player .team
85- self .name = player .name
86- self .logger = get_logger (self .name )
87- break
88-
89- if not self ._initialized_bot and self ._has_field_info :
92+ if (
93+ not self ._initialized_bot
94+ and self ._has_field_info
95+ and self ._has_player_mapping
96+ ):
9097 self ._initialize_agent ()
9198
9299 def _handle_field_info (self , field_info : flat .FieldInfo ):
93100 self .field_info = field_info
94101 self ._has_field_info = True
95102
96- if not self ._initialized_bot and self ._has_match_settings :
103+ if (
104+ not self ._initialized_bot
105+ and self ._has_match_settings
106+ and self ._has_player_mapping
107+ ):
108+ self ._initialize_agent ()
109+
110+ def _handle_player_mappings (self , player_mappings : flat .TeamControllables ):
111+ self .team = player_mappings .team
112+ controllable = player_mappings .controllables [0 ]
113+ self .spawn_id = controllable .spawn_id
114+ self .index = controllable .index
115+ self ._has_player_mapping = True
116+
117+ if (
118+ not self ._initialized_bot
119+ and self ._has_match_settings
120+ and self ._has_field_info
121+ ):
97122 self ._initialize_agent ()
98123
99124 def _handle_ball_prediction (self , ball_prediction : flat .BallPrediction ):
@@ -103,36 +128,8 @@ def _handle_packet(self, packet: flat.GameTickPacket):
103128 self ._latest_packet = packet
104129
105130 def _packet_processor (self , packet : flat .GameTickPacket ):
106- if (
107- self .index == - 1
108- or len (packet .players ) <= self .index
109- or packet .players [self .index ].spawn_id != self .spawn_id
110- ):
111- # spawn id should only be 0 if RLBOT_SPAWN_IDS was not set
112- if self .spawn_id == 0 :
113- # in this case, if there's only one player, we can assume it's us
114- player_index = - 1
115- for i , player in enumerate (packet .players ):
116- # skip human players/psyonix bots
117- if not player .is_bot :
118- continue
119-
120- if player_index != - 1 :
121- self .logger .error (
122- "Multiple bots in the game, please set RLBOT_SPAWN_IDS"
123- )
124- return
125-
126- player_index = i
127- self .index = player_index
128-
129- for i , player in enumerate (packet .players ):
130- if player .spawn_id == self .spawn_id :
131- self .index = i
132- break
133-
134- if self .index == - 1 :
135- return
131+ if len (packet .players ) <= self .index :
132+ return
136133
137134 self .ball_prediction = self ._latest_prediction
138135
@@ -279,9 +276,7 @@ def set_loadout(self, loadout: flat.PlayerLoadout, spawn_id: int):
279276 def initialize_agent (self ):
280277 """
281278 Called for all heaver initialization that needs to happen.
282- Field info and match settings are fully loaded at this point, and won't return garbage data.
283-
284- NOTE: `self.index` is not set at this point, and should not be used. `self.team` and `self.name` _are_ set with correct information.
279+ Field info, match settings, name, index, and team are fully loaded at this point, and won't return garbage data.
285280 """
286281
287282 def retire (self ):
0 commit comments