Input and Output Data

redd edited this page Nov 25, 2022 · 36 revisions

BaseAgent

The base agent has some useful values that we can read from in order to get some basic information about the car that we are controlling, the team our car is on, and even the name of our car in the game.

These values can be accessed at any time from the base agent using the self parameter:

definitialize_agent(self):
# Print the bot's teamprint(self.team)
defget_output(self, packet: GameTickPacket) ->SimpleControllerState:
# Get our carmy_car=packet.game_cars[self.index]

Some useful values to know are:

self.team=0# The team that our bot is onself.name="ExampleBot"# Our bot's in-game nameself.index=2# The index of the car our agent is controlling

GameTickPacket

Every tick, your bot will receive a GameTickPacket from the framework. The packet will contain all the raw values from the game (such as car and ball locations). Your bot receives the packet in the get_output(self, packet) function and you should return a ControllerState which describes what your bot's response is.

Getting values from the packet is simple:

defget_output(self, packet: GameTickPacket) ->SimpleControllerState:
# You can get values out of the packet like this:x_location_of_first_car=packet.game_cars[0].physics.location.x;

NOTE: Some structs/lists in the GameTickPacket has a fixed length. So make sure you use the num_cars and the num_boosts values as lengths if you iterate through the associated lists.

Sample game tick packet

packet: {
'game_cars': [
{
'physics': {
'location': {'x': 0.0, 'y': 0.0, 'z': 0.0},
'rotation': {'pitch': 0.0, 'yaw': 0.0, 'roll': 0.0},
'velocity': {'x': 0.0, 'y': 0.0, 'z': 0.0},
'angular_velocity': {'x': 0.0, 'y': 0.0, 'z': 0.0}
},
'is_demolished': False,
'has_wheel_contact': True,
'is_super_sonic': False,
'is_bot': True,
'jumped': False,
'double_jumped': True,
'name': 'Jupiter',
'team': 0,
'boost': 48.0,
'hitbox': {'length': 118, 'width': 84, 'height': 36},
'hitbox_offset': {'x': 13.88, 'y': 0.0, 'z': 20.75},
'score_info': {
'score': 340,
'goals': 2,
'own_goals': 0,
'assists': 1,
'saves': 1,
'shots': 3,
'demolitions': 1
}
},
{ ... }
],
'num_cars': 2,
'game_boosts': [
{
'is_active': True,
'timer': 0.0
},
{ ... }
],
'num_boost': 36,
'game_ball': {
'physics': {
'location': {'x': 0.0, 'y': 0.0, 'z': 0.0},
'rotation': {'pitch': 0.0, 'yaw': 0.0, 'roll': 0.0},
'velocity': {'x': 0.0, 'y': 0.0, 'z': 0.0},
'angular_velocity': {'x': 0.0, 'y': 0.0, 'z': 0.0}
},
'latest_touch': {
'player_name': 'Beavis',
'time_seconds': 120.63,
'hit_location': {'x': 0.0, 'y': 0.0, 'z': 0.0},
'hit_normal': {'x': 0.0, 'y': 0.0, 'z': 0.0},
'team': 0,
'player_index': 0
},
'drop_shot_info': {
'damage_index': 0,
'absorbed_force': 0,
'force_accum_recent': 0
},
'collision_shape': {
'type': 1,
'box': {'length': 153.0, 'width': 153.0, 'height': 153.0},
'sphere': {'diameter': 184.0},
'cylinder': {'diameter': 184.0, 'height': 30.0}
}
},
'game_info': {
'seconds_elapsed': 405.12,
'game_time_remaining': 34.0,
'is_overtime': False,
'is_unlimited_time': False,
'is_round_active': True,
'is_kickoff_pause': False,
'is_match_ended': False,
'world_gravity_z': -650.0,
'game_speed': 1.0,
'frame_num': 3923
},
'teams': [
{
'team_index': 0,
'score': 7
},
{ ... }
],
'num_teams': 2,
}

ControllerState

A ControllerState is the controller input the bot should perform. Import ControllerState like this: from rlbot.agents.base_agent import SimpleControllerState, and create a new instance with SimpleControllerState()

Example:

fromrlbot.agents.base_agentimportBaseAgent, SimpleControllerStatefromrlbot.utils.structures.game_data_structimportGameTickPacketclassExampleBot(BaseAgent):
definitialize_agent(self):
passdefget_output(self, packet: GameTickPacket) ->SimpleControllerState:
# Make the bot go forwards by setting throttle to 1controller=SimpleControllerState()
controller.throttle=1returncontroller

The ControllerState has the following attributes:

{
throttle:float; /// -1 for full reverse, 1 for full forward
steer:float; /// -1 for full left, 1 for full right
pitch:float; /// -1 for nose down, 1 for nose up
yaw:float; /// -1 for full left, 1 for full right
roll:float; /// -1 for roll left, 1 for roll right
jump:bool; /// true if you want to press the jump button
boost:bool; /// true if you want to press the boost button
handbrake:bool; /// true if you want to press the handbrake button
use_item:bool; /// true if you want to use a rumble item
}

Field Info

A few values are constant, like the locations of boosts and goals. Some of these can be found in the FieldInfo data. FieldInfo contains the following:

field_info: {
'boost_pads': [
{
'location': Vector3,
'is_full_boost': boolean
},
{ ... }
],
'num_boosts': int,
'goals': [
{
'team_num': int,
'location': Vector3,
'direction': Vector3,
'width': float,
'height': float
},
{ ... }
],
'num_goals': int
}

Note: Dropshot tiles can be found in FieldInfo as GoalInfo objects. Note2: Boost pads and Dropshot tiles will be sorted according to y * 100 + x, just like their counterparts (game_boosts and dropshot_tiles that contain their current state) in the game tick packet.

In Python, you can retrieve this information by calling get_field_info() on the BaseAgent:

fromrlbot.agents.base_agentimportBaseAgent, SimpleControllerStatefromrlbot.utils.structures.game_data_structimportGameTickPacketclassExampleBot(BaseAgent):
definitialize_agent(self):
passdefget_output(self, packet: GameTickPacket) ->SimpleControllerState:
# Constant values can be found the the FieldInfo:info=self.get_field_info()
# Manually construct a list of all big boost pads# info.boost_pads has a fixed size but info.num_boosts is how many pads there actually arebig_pads= []
foriinrange(info.num_boosts):
pad=info.boost_pads[i]
ifpad.is_full_boost:
big_pads.append(pad)

Match settings (mutators & gamemode)

Mutators can only be set before the game starts by a human.

To get the current mutators, do something like this:

fromrlbot.messages.flat.BoostOptionimportBoostOptiondefinitialize_agent(self):
# See all of the match settings at https://github.com/RLBot/RLBot/blob/master/src/main/flatbuffers/rlbot.fbs#L784match_settings=self.get_match_settings()
mutators=match_settings.MutatorSettings()
# Examples# Game modegame_mode= (
"soccer",
"hoops",
"dropshot",
"hockey",
"rumble",
"heatseeker"
)
self.gamemode=game_mode[match_settings.GameMode()]
# View all mutator options at https://github.com/RLBot/RLBot/blob/master/src/main/flatbuffers/rlbot.fbs#L753# Boost amountifmutators.BoostOption() ==BoostOption.Unlimited_Boost:
# Do whatever# Boost acceleration# Leverage some known constants to get an acceleration value based on the setting.# These values are from the Physics section of the Useful Game Values wiki -> https://github.com/RLBot/RLBot/wiki/Useful-Game-Values#physicsbase_boost_accel=991+ (2/3)
boost_accel= (
base_boost_accel, # Defaultbase_boost_accel*1.5, # Strength x 1.5base_boost_accel*2, # Strength x 2base_boost_accel*10# Strength x 10
)
self.boost_accel=boost_accel[mutators.BoostStrengthOption()]

Documentation on what it means

You can find descriptions of the tricky values in this file:

https://github.com/RLBot/RLBot/blob/master/src/main/flatbuffers/rlbot.fbs

You will recognize some of the previous mentioned classes as tables. I.e. packet.score_info is a ScoreInfo table.

Clone this wiki locally

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Input and Output Data

redd edited this page Nov 25, 2022 · 36 revisions

BaseAgent

The base agent has some useful values that we can read from in order to get some basic information about the car that we are controlling, the team our car is on, and even the name of our car in the game.

These values can be accessed at any time from the base agent using the self parameter:

definitialize_agent(self):
# Print the bot's teamprint(self.team)
defget_output(self, packet: GameTickPacket) ->SimpleControllerState:
# Get our carmy_car=packet.game_cars[self.index]

Some useful values to know are:

self.team=0# The team that our bot is onself.name="ExampleBot"# Our bot's in-game nameself.index=2# The index of the car our agent is controlling

GameTickPacket

Every tick, your bot will receive a GameTickPacket from the framework. The packet will contain all the raw values from the game (such as car and ball locations). Your bot receives the packet in the get_output(self, packet) function and you should return a ControllerState which describes what your bot's response is.

Getting values from the packet is simple:

defget_output(self, packet: GameTickPacket) ->SimpleControllerState:
# You can get values out of the packet like this:x_location_of_first_car=packet.game_cars[0].physics.location.x;

NOTE: Some structs/lists in the GameTickPacket has a fixed length. So make sure you use the num_cars and the num_boosts values as lengths if you iterate through the associated lists.

Sample game tick packet

packet: {
'game_cars': [
{
'physics': {
'location': {'x': 0.0, 'y': 0.0, 'z': 0.0},
'rotation': {'pitch': 0.0, 'yaw': 0.0, 'roll': 0.0},
'velocity': {'x': 0.0, 'y': 0.0, 'z': 0.0},
'angular_velocity': {'x': 0.0, 'y': 0.0, 'z': 0.0}
},
'is_demolished': False,
'has_wheel_contact': True,
'is_super_sonic': False,
'is_bot': True,
'jumped': False,
'double_jumped': True,
'name': 'Jupiter',
'team': 0,
'boost': 48.0,
'hitbox': {'length': 118, 'width': 84, 'height': 36},
'hitbox_offset': {'x': 13.88, 'y': 0.0, 'z': 20.75},
'score_info': {
'score': 340,
'goals': 2,
'own_goals': 0,
'assists': 1,
'saves': 1,
'shots': 3,
'demolitions': 1
}
},
{ ... }
],
'num_cars': 2,
'game_boosts': [
{
'is_active': True,
'timer': 0.0
},
{ ... }
],
'num_boost': 36,
'game_ball': {
'physics': {
'location': {'x': 0.0, 'y': 0.0, 'z': 0.0},
'rotation': {'pitch': 0.0, 'yaw': 0.0, 'roll': 0.0},
'velocity': {'x': 0.0, 'y': 0.0, 'z': 0.0},
'angular_velocity': {'x': 0.0, 'y': 0.0, 'z': 0.0}
},
'latest_touch': {
'player_name': 'Beavis',
'time_seconds': 120.63,
'hit_location': {'x': 0.0, 'y': 0.0, 'z': 0.0},
'hit_normal': {'x': 0.0, 'y': 0.0, 'z': 0.0},
'team': 0,
'player_index': 0
},
'drop_shot_info': {
'damage_index': 0,
'absorbed_force': 0,
'force_accum_recent': 0
},
'collision_shape': {
'type': 1,
'box': {'length': 153.0, 'width': 153.0, 'height': 153.0},
'sphere': {'diameter': 184.0},
'cylinder': {'diameter': 184.0, 'height': 30.0}
}
},
'game_info': {
'seconds_elapsed': 405.12,
'game_time_remaining': 34.0,
'is_overtime': False,
'is_unlimited_time': False,
'is_round_active': True,
'is_kickoff_pause': False,
'is_match_ended': False,
'world_gravity_z': -650.0,
'game_speed': 1.0,
'frame_num': 3923
},
'teams': [
{
'team_index': 0,
'score': 7
},
{ ... }
],
'num_teams': 2,
}

ControllerState

A ControllerState is the controller input the bot should perform. Import ControllerState like this: from rlbot.agents.base_agent import SimpleControllerState, and create a new instance with SimpleControllerState()

Example:

fromrlbot.agents.base_agentimportBaseAgent, SimpleControllerStatefromrlbot.utils.structures.game_data_structimportGameTickPacketclassExampleBot(BaseAgent):
definitialize_agent(self):
passdefget_output(self, packet: GameTickPacket) ->SimpleControllerState:
# Make the bot go forwards by setting throttle to 1controller=SimpleControllerState()
controller.throttle=1returncontroller

The ControllerState has the following attributes:

{
throttle:float; /// -1 for full reverse, 1 for full forward
steer:float; /// -1 for full left, 1 for full right
pitch:float; /// -1 for nose down, 1 for nose up
yaw:float; /// -1 for full left, 1 for full right
roll:float; /// -1 for roll left, 1 for roll right
jump:bool; /// true if you want to press the jump button
boost:bool; /// true if you want to press the boost button
handbrake:bool; /// true if you want to press the handbrake button
use_item:bool; /// true if you want to use a rumble item
}

Field Info

A few values are constant, like the locations of boosts and goals. Some of these can be found in the FieldInfo data. FieldInfo contains the following:

field_info: {
'boost_pads': [
{
'location': Vector3,
'is_full_boost': boolean
},
{ ... }
],
'num_boosts': int,
'goals': [
{
'team_num': int,
'location': Vector3,
'direction': Vector3,
'width': float,
'height': float
},
{ ... }
],
'num_goals': int
}

Note: Dropshot tiles can be found in FieldInfo as GoalInfo objects. Note2: Boost pads and Dropshot tiles will be sorted according to y * 100 + x, just like their counterparts (game_boosts and dropshot_tiles that contain their current state) in the game tick packet.

In Python, you can retrieve this information by calling get_field_info() on the BaseAgent:

fromrlbot.agents.base_agentimportBaseAgent, SimpleControllerStatefromrlbot.utils.structures.game_data_structimportGameTickPacketclassExampleBot(BaseAgent):
definitialize_agent(self):
passdefget_output(self, packet: GameTickPacket) ->SimpleControllerState:
# Constant values can be found the the FieldInfo:info=self.get_field_info()
# Manually construct a list of all big boost pads# info.boost_pads has a fixed size but info.num_boosts is how many pads there actually arebig_pads= []
foriinrange(info.num_boosts):
pad=info.boost_pads[i]
ifpad.is_full_boost:
big_pads.append(pad)

Match settings (mutators & gamemode)

Mutators can only be set before the game starts by a human.

To get the current mutators, do something like this:

fromrlbot.messages.flat.BoostOptionimportBoostOptiondefinitialize_agent(self):
# See all of the match settings at https://github.com/RLBot/RLBot/blob/master/src/main/flatbuffers/rlbot.fbs#L784match_settings=self.get_match_settings()
mutators=match_settings.MutatorSettings()
# Examples# Game modegame_mode= (
"soccer",
"hoops",
"dropshot",
"hockey",
"rumble",
"heatseeker"
)
self.gamemode=game_mode[match_settings.GameMode()]
# View all mutator options at https://github.com/RLBot/RLBot/blob/master/src/main/flatbuffers/rlbot.fbs#L753# Boost amountifmutators.BoostOption() ==BoostOption.Unlimited_Boost:
# Do whatever# Boost acceleration# Leverage some known constants to get an acceleration value based on the setting.# These values are from the Physics section of the Useful Game Values wiki -> https://github.com/RLBot/RLBot/wiki/Useful-Game-Values#physicsbase_boost_accel=991+ (2/3)
boost_accel= (
base_boost_accel, # Defaultbase_boost_accel*1.5, # Strength x 1.5base_boost_accel*2, # Strength x 2base_boost_accel*10# Strength x 10
)
self.boost_accel=boost_accel[mutators.BoostStrengthOption()]

Documentation on what it means

You can find descriptions of the tricky values in this file:

https://github.com/RLBot/RLBot/blob/master/src/main/flatbuffers/rlbot.fbs

You will recognize some of the previous mentioned classes as tables. I.e. packet.score_info is a ScoreInfo table.

Clone this wiki locally

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Input and Output Data

redd edited this page Nov 25, 2022 · 36 revisions

BaseAgent

The base agent has some useful values that we can read from in order to get some basic information about the car that we are controlling, the team our car is on, and even the name of our car in the game.

These values can be accessed at any time from the base agent using the self parameter:

definitialize_agent(self):
# Print the bot's teamprint(self.team)
defget_output(self, packet: GameTickPacket) ->SimpleControllerState:
# Get our carmy_car=packet.game_cars[self.index]

Some useful values to know are:

self.team=0# The team that our bot is onself.name="ExampleBot"# Our bot's in-game nameself.index=2# The index of the car our agent is controlling

GameTickPacket

Every tick, your bot will receive a GameTickPacket from the framework. The packet will contain all the raw values from the game (such as car and ball locations). Your bot receives the packet in the get_output(self, packet) function and you should return a ControllerState which describes what your bot's response is.

Getting values from the packet is simple:

defget_output(self, packet: GameTickPacket) ->SimpleControllerState:
# You can get values out of the packet like this:x_location_of_first_car=packet.game_cars[0].physics.location.x;

NOTE: Some structs/lists in the GameTickPacket has a fixed length. So make sure you use the num_cars and the num_boosts values as lengths if you iterate through the associated lists.

Sample game tick packet

packet: {
'game_cars': [
{
'physics': {
'location': {'x': 0.0, 'y': 0.0, 'z': 0.0},
'rotation': {'pitch': 0.0, 'yaw': 0.0, 'roll': 0.0},
'velocity': {'x': 0.0, 'y': 0.0, 'z': 0.0},
'angular_velocity': {'x': 0.0, 'y': 0.0, 'z': 0.0}
},
'is_demolished': False,
'has_wheel_contact': True,
'is_super_sonic': False,
'is_bot': True,
'jumped': False,
'double_jumped': True,
'name': 'Jupiter',
'team': 0,
'boost': 48.0,
'hitbox': {'length': 118, 'width': 84, 'height': 36},
'hitbox_offset': {'x': 13.88, 'y': 0.0, 'z': 20.75},
'score_info': {
'score': 340,
'goals': 2,
'own_goals': 0,
'assists': 1,
'saves': 1,
'shots': 3,
'demolitions': 1
}
},
{ ... }
],
'num_cars': 2,
'game_boosts': [
{
'is_active': True,
'timer': 0.0
},
{ ... }
],
'num_boost': 36,
'game_ball': {
'physics': {
'location': {'x': 0.0, 'y': 0.0, 'z': 0.0},
'rotation': {'pitch': 0.0, 'yaw': 0.0, 'roll': 0.0},
'velocity': {'x': 0.0, 'y': 0.0, 'z': 0.0},
'angular_velocity': {'x': 0.0, 'y': 0.0, 'z': 0.0}
},
'latest_touch': {
'player_name': 'Beavis',
'time_seconds': 120.63,
'hit_location': {'x': 0.0, 'y': 0.0, 'z': 0.0},
'hit_normal': {'x': 0.0, 'y': 0.0, 'z': 0.0},
'team': 0,
'player_index': 0
},
'drop_shot_info': {
'damage_index': 0,
'absorbed_force': 0,
'force_accum_recent': 0
},
'collision_shape': {
'type': 1,
'box': {'length': 153.0, 'width': 153.0, 'height': 153.0},
'sphere': {'diameter': 184.0},
'cylinder': {'diameter': 184.0, 'height': 30.0}
}
},
'game_info': {
'seconds_elapsed': 405.12,
'game_time_remaining': 34.0,
'is_overtime': False,
'is_unlimited_time': False,
'is_round_active': True,
'is_kickoff_pause': False,
'is_match_ended': False,
'world_gravity_z': -650.0,
'game_speed': 1.0,
'frame_num': 3923
},
'teams': [
{
'team_index': 0,
'score': 7
},
{ ... }
],
'num_teams': 2,
}

ControllerState

A ControllerState is the controller input the bot should perform. Import ControllerState like this: from rlbot.agents.base_agent import SimpleControllerState, and create a new instance with SimpleControllerState()

Example:

fromrlbot.agents.base_agentimportBaseAgent, SimpleControllerStatefromrlbot.utils.structures.game_data_structimportGameTickPacketclassExampleBot(BaseAgent):
definitialize_agent(self):
passdefget_output(self, packet: GameTickPacket) ->SimpleControllerState:
# Make the bot go forwards by setting throttle to 1controller=SimpleControllerState()
controller.throttle=1returncontroller

The ControllerState has the following attributes:

{
throttle:float; /// -1 for full reverse, 1 for full forward
steer:float; /// -1 for full left, 1 for full right
pitch:float; /// -1 for nose down, 1 for nose up
yaw:float; /// -1 for full left, 1 for full right
roll:float; /// -1 for roll left, 1 for roll right
jump:bool; /// true if you want to press the jump button
boost:bool; /// true if you want to press the boost button
handbrake:bool; /// true if you want to press the handbrake button
use_item:bool; /// true if you want to use a rumble item
}

Field Info

A few values are constant, like the locations of boosts and goals. Some of these can be found in the FieldInfo data. FieldInfo contains the following:

field_info: {
'boost_pads': [
{
'location': Vector3,
'is_full_boost': boolean
},
{ ... }
],
'num_boosts': int,
'goals': [
{
'team_num': int,
'location': Vector3,
'direction': Vector3,
'width': float,
'height': float
},
{ ... }
],
'num_goals': int
}

Note: Dropshot tiles can be found in FieldInfo as GoalInfo objects. Note2: Boost pads and Dropshot tiles will be sorted according to y * 100 + x, just like their counterparts (game_boosts and dropshot_tiles that contain their current state) in the game tick packet.

In Python, you can retrieve this information by calling get_field_info() on the BaseAgent:

fromrlbot.agents.base_agentimportBaseAgent, SimpleControllerStatefromrlbot.utils.structures.game_data_structimportGameTickPacketclassExampleBot(BaseAgent):
definitialize_agent(self):
passdefget_output(self, packet: GameTickPacket) ->SimpleControllerState:
# Constant values can be found the the FieldInfo:info=self.get_field_info()
# Manually construct a list of all big boost pads# info.boost_pads has a fixed size but info.num_boosts is how many pads there actually arebig_pads= []
foriinrange(info.num_boosts):
pad=info.boost_pads[i]
ifpad.is_full_boost:
big_pads.append(pad)

Match settings (mutators & gamemode)

Mutators can only be set before the game starts by a human.

To get the current mutators, do something like this:

fromrlbot.messages.flat.BoostOptionimportBoostOptiondefinitialize_agent(self):
# See all of the match settings at https://github.com/RLBot/RLBot/blob/master/src/main/flatbuffers/rlbot.fbs#L784match_settings=self.get_match_settings()
mutators=match_settings.MutatorSettings()
# Examples# Game modegame_mode= (
"soccer",
"hoops",
"dropshot",
"hockey",
"rumble",
"heatseeker"
)
self.gamemode=game_mode[match_settings.GameMode()]
# View all mutator options at https://github.com/RLBot/RLBot/blob/master/src/main/flatbuffers/rlbot.fbs#L753# Boost amountifmutators.BoostOption() ==BoostOption.Unlimited_Boost:
# Do whatever# Boost acceleration# Leverage some known constants to get an acceleration value based on the setting.# These values are from the Physics section of the Useful Game Values wiki -> https://github.com/RLBot/RLBot/wiki/Useful-Game-Values#physicsbase_boost_accel=991+ (2/3)
boost_accel= (
base_boost_accel, # Defaultbase_boost_accel*1.5, # Strength x 1.5base_boost_accel*2, # Strength x 2base_boost_accel*10# Strength x 10
)
self.boost_accel=boost_accel[mutators.BoostStrengthOption()]

Documentation on what it means

You can find descriptions of the tricky values in this file:

https://github.com/RLBot/RLBot/blob/master/src/main/flatbuffers/rlbot.fbs

You will recognize some of the previous mentioned classes as tables. I.e. packet.score_info is a ScoreInfo table.

Clone this wiki locally

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Input and Output Data

redd edited this page Nov 25, 2022 · 36 revisions

BaseAgent

The base agent has some useful values that we can read from in order to get some basic information about the car that we are controlling, the team our car is on, and even the name of our car in the game.

These values can be accessed at any time from the base agent using the self parameter:

definitialize_agent(self):
# Print the bot's teamprint(self.team)
defget_output(self, packet: GameTickPacket) ->SimpleControllerState:
# Get our carmy_car=packet.game_cars[self.index]

Some useful values to know are:

self.team=0# The team that our bot is onself.name="ExampleBot"# Our bot's in-game nameself.index=2# The index of the car our agent is controlling

GameTickPacket

Every tick, your bot will receive a GameTickPacket from the framework. The packet will contain all the raw values from the game (such as car and ball locations). Your bot receives the packet in the get_output(self, packet) function and you should return a ControllerState which describes what your bot's response is.

Getting values from the packet is simple:

defget_output(self, packet: GameTickPacket) ->SimpleControllerState:
# You can get values out of the packet like this:x_location_of_first_car=packet.game_cars[0].physics.location.x;

NOTE: Some structs/lists in the GameTickPacket has a fixed length. So make sure you use the num_cars and the num_boosts values as lengths if you iterate through the associated lists.

Sample game tick packet

packet: {
'game_cars': [
{
'physics': {
'location': {'x': 0.0, 'y': 0.0, 'z': 0.0},
'rotation': {'pitch': 0.0, 'yaw': 0.0, 'roll': 0.0},
'velocity': {'x': 0.0, 'y': 0.0, 'z': 0.0},
'angular_velocity': {'x': 0.0, 'y': 0.0, 'z': 0.0}
},
'is_demolished': False,
'has_wheel_contact': True,
'is_super_sonic': False,
'is_bot': True,
'jumped': False,
'double_jumped': True,
'name': 'Jupiter',
'team': 0,
'boost': 48.0,
'hitbox': {'length': 118, 'width': 84, 'height': 36},
'hitbox_offset': {'x': 13.88, 'y': 0.0, 'z': 20.75},
'score_info': {
'score': 340,
'goals': 2,
'own_goals': 0,
'assists': 1,
'saves': 1,
'shots': 3,
'demolitions': 1
}
},
{ ... }
],
'num_cars': 2,
'game_boosts': [
{
'is_active': True,
'timer': 0.0
},
{ ... }
],
'num_boost': 36,
'game_ball': {
'physics': {
'location': {'x': 0.0, 'y': 0.0, 'z': 0.0},
'rotation': {'pitch': 0.0, 'yaw': 0.0, 'roll': 0.0},
'velocity': {'x': 0.0, 'y': 0.0, 'z': 0.0},
'angular_velocity': {'x': 0.0, 'y': 0.0, 'z': 0.0}
},
'latest_touch': {
'player_name': 'Beavis',
'time_seconds': 120.63,
'hit_location': {'x': 0.0, 'y': 0.0, 'z': 0.0},
'hit_normal': {'x': 0.0, 'y': 0.0, 'z': 0.0},
'team': 0,
'player_index': 0
},
'drop_shot_info': {
'damage_index': 0,
'absorbed_force': 0,
'force_accum_recent': 0
},
'collision_shape': {
'type': 1,
'box': {'length': 153.0, 'width': 153.0, 'height': 153.0},
'sphere': {'diameter': 184.0},
'cylinder': {'diameter': 184.0, 'height': 30.0}
}
},
'game_info': {
'seconds_elapsed': 405.12,
'game_time_remaining': 34.0,
'is_overtime': False,
'is_unlimited_time': False,
'is_round_active': True,
'is_kickoff_pause': False,
'is_match_ended': False,
'world_gravity_z': -650.0,
'game_speed': 1.0,
'frame_num': 3923
},
'teams': [
{
'team_index': 0,
'score': 7
},
{ ... }
],
'num_teams': 2,
}

ControllerState

A ControllerState is the controller input the bot should perform. Import ControllerState like this: from rlbot.agents.base_agent import SimpleControllerState, and create a new instance with SimpleControllerState()

Example:

fromrlbot.agents.base_agentimportBaseAgent, SimpleControllerStatefromrlbot.utils.structures.game_data_structimportGameTickPacketclassExampleBot(BaseAgent):
definitialize_agent(self):
passdefget_output(self, packet: GameTickPacket) ->SimpleControllerState:
# Make the bot go forwards by setting throttle to 1controller=SimpleControllerState()
controller.throttle=1returncontroller

The ControllerState has the following attributes:

{
throttle:float; /// -1 for full reverse, 1 for full forward
steer:float; /// -1 for full left, 1 for full right
pitch:float; /// -1 for nose down, 1 for nose up
yaw:float; /// -1 for full left, 1 for full right
roll:float; /// -1 for roll left, 1 for roll right
jump:bool; /// true if you want to press the jump button
boost:bool; /// true if you want to press the boost button
handbrake:bool; /// true if you want to press the handbrake button
use_item:bool; /// true if you want to use a rumble item
}

Field Info

A few values are constant, like the locations of boosts and goals. Some of these can be found in the FieldInfo data. FieldInfo contains the following:

field_info: {
'boost_pads': [
{
'location': Vector3,
'is_full_boost': boolean
},
{ ... }
],
'num_boosts': int,
'goals': [
{
'team_num': int,
'location': Vector3,
'direction': Vector3,
'width': float,
'height': float
},
{ ... }
],
'num_goals': int
}

Note: Dropshot tiles can be found in FieldInfo as GoalInfo objects. Note2: Boost pads and Dropshot tiles will be sorted according to y * 100 + x, just like their counterparts (game_boosts and dropshot_tiles that contain their current state) in the game tick packet.

In Python, you can retrieve this information by calling get_field_info() on the BaseAgent:

fromrlbot.agents.base_agentimportBaseAgent, SimpleControllerStatefromrlbot.utils.structures.game_data_structimportGameTickPacketclassExampleBot(BaseAgent):
definitialize_agent(self):
passdefget_output(self, packet: GameTickPacket) ->SimpleControllerState:
# Constant values can be found the the FieldInfo:info=self.get_field_info()
# Manually construct a list of all big boost pads# info.boost_pads has a fixed size but info.num_boosts is how many pads there actually arebig_pads= []
foriinrange(info.num_boosts):
pad=info.boost_pads[i]
ifpad.is_full_boost:
big_pads.append(pad)

Match settings (mutators & gamemode)

Mutators can only be set before the game starts by a human.

To get the current mutators, do something like this:

fromrlbot.messages.flat.BoostOptionimportBoostOptiondefinitialize_agent(self):
# See all of the match settings at https://github.com/RLBot/RLBot/blob/master/src/main/flatbuffers/rlbot.fbs#L784match_settings=self.get_match_settings()
mutators=match_settings.MutatorSettings()
# Examples# Game modegame_mode= (
"soccer",
"hoops",
"dropshot",
"hockey",
"rumble",
"heatseeker"
)
self.gamemode=game_mode[match_settings.GameMode()]
# View all mutator options at https://github.com/RLBot/RLBot/blob/master/src/main/flatbuffers/rlbot.fbs#L753# Boost amountifmutators.BoostOption() ==BoostOption.Unlimited_Boost:
# Do whatever# Boost acceleration# Leverage some known constants to get an acceleration value based on the setting.# These values are from the Physics section of the Useful Game Values wiki -> https://github.com/RLBot/RLBot/wiki/Useful-Game-Values#physicsbase_boost_accel=991+ (2/3)
boost_accel= (
base_boost_accel, # Defaultbase_boost_accel*1.5, # Strength x 1.5base_boost_accel*2, # Strength x 2base_boost_accel*10# Strength x 10
)
self.boost_accel=boost_accel[mutators.BoostStrengthOption()]

Documentation on what it means

You can find descriptions of the tricky values in this file:

https://github.com/RLBot/RLBot/blob/master/src/main/flatbuffers/rlbot.fbs

You will recognize some of the previous mentioned classes as tables. I.e. packet.score_info is a ScoreInfo table.

Clone this wiki locally

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Input and Output Data

redd edited this page Nov 25, 2022 · 36 revisions

BaseAgent

The base agent has some useful values that we can read from in order to get some basic information about the car that we are controlling, the team our car is on, and even the name of our car in the game.

These values can be accessed at any time from the base agent using the self parameter:

definitialize_agent(self):
# Print the bot's teamprint(self.team)
defget_output(self, packet: GameTickPacket) ->SimpleControllerState:
# Get our carmy_car=packet.game_cars[self.index]

Some useful values to know are:

self.team=0# The team that our bot is onself.name="ExampleBot"# Our bot's in-game nameself.index=2# The index of the car our agent is controlling

GameTickPacket

Every tick, your bot will receive a GameTickPacket from the framework. The packet will contain all the raw values from the game (such as car and ball locations). Your bot receives the packet in the get_output(self, packet) function and you should return a ControllerState which describes what your bot's response is.

Getting values from the packet is simple:

defget_output(self, packet: GameTickPacket) ->SimpleControllerState:
# You can get values out of the packet like this:x_location_of_first_car=packet.game_cars[0].physics.location.x;

NOTE: Some structs/lists in the GameTickPacket has a fixed length. So make sure you use the num_cars and the num_boosts values as lengths if you iterate through the associated lists.

Sample game tick packet

packet: {
'game_cars': [
{
'physics': {
'location': {'x': 0.0, 'y': 0.0, 'z': 0.0},
'rotation': {'pitch': 0.0, 'yaw': 0.0, 'roll': 0.0},
'velocity': {'x': 0.0, 'y': 0.0, 'z': 0.0},
'angular_velocity': {'x': 0.0, 'y': 0.0, 'z': 0.0}
},
'is_demolished': False,
'has_wheel_contact': True,
'is_super_sonic': False,
'is_bot': True,
'jumped': False,
'double_jumped': True,
'name': 'Jupiter',
'team': 0,
'boost': 48.0,
'hitbox': {'length': 118, 'width': 84, 'height': 36},
'hitbox_offset': {'x': 13.88, 'y': 0.0, 'z': 20.75},
'score_info': {
'score': 340,
'goals': 2,
'own_goals': 0,
'assists': 1,
'saves': 1,
'shots': 3,
'demolitions': 1
}
},
{ ... }
],
'num_cars': 2,
'game_boosts': [
{
'is_active': True,
'timer': 0.0
},
{ ... }
],
'num_boost': 36,
'game_ball': {
'physics': {
'location': {'x': 0.0, 'y': 0.0, 'z': 0.0},
'rotation': {'pitch': 0.0, 'yaw': 0.0, 'roll': 0.0},
'velocity': {'x': 0.0, 'y': 0.0, 'z': 0.0},
'angular_velocity': {'x': 0.0, 'y': 0.0, 'z': 0.0}
},
'latest_touch': {
'player_name': 'Beavis',
'time_seconds': 120.63,
'hit_location': {'x': 0.0, 'y': 0.0, 'z': 0.0},
'hit_normal': {'x': 0.0, 'y': 0.0, 'z': 0.0},
'team': 0,
'player_index': 0
},
'drop_shot_info': {
'damage_index': 0,
'absorbed_force': 0,
'force_accum_recent': 0
},
'collision_shape': {
'type': 1,
'box': {'length': 153.0, 'width': 153.0, 'height': 153.0},
'sphere': {'diameter': 184.0},
'cylinder': {'diameter': 184.0, 'height': 30.0}
}
},
'game_info': {
'seconds_elapsed': 405.12,
'game_time_remaining': 34.0,
'is_overtime': False,
'is_unlimited_time': False,
'is_round_active': True,
'is_kickoff_pause': False,
'is_match_ended': False,
'world_gravity_z': -650.0,
'game_speed': 1.0,
'frame_num': 3923
},
'teams': [
{
'team_index': 0,
'score': 7
},
{ ... }
],
'num_teams': 2,
}

ControllerState

A ControllerState is the controller input the bot should perform. Import ControllerState like this: from rlbot.agents.base_agent import SimpleControllerState, and create a new instance with SimpleControllerState()

Example:

fromrlbot.agents.base_agentimportBaseAgent, SimpleControllerStatefromrlbot.utils.structures.game_data_structimportGameTickPacketclassExampleBot(BaseAgent):
definitialize_agent(self):
passdefget_output(self, packet: GameTickPacket) ->SimpleControllerState:
# Make the bot go forwards by setting throttle to 1controller=SimpleControllerState()
controller.throttle=1returncontroller

The ControllerState has the following attributes:

{
throttle:float; /// -1 for full reverse, 1 for full forward
steer:float; /// -1 for full left, 1 for full right
pitch:float; /// -1 for nose down, 1 for nose up
yaw:float; /// -1 for full left, 1 for full right
roll:float; /// -1 for roll left, 1 for roll right
jump:bool; /// true if you want to press the jump button
boost:bool; /// true if you want to press the boost button
handbrake:bool; /// true if you want to press the handbrake button
use_item:bool; /// true if you want to use a rumble item
}

Field Info

A few values are constant, like the locations of boosts and goals. Some of these can be found in the FieldInfo data. FieldInfo contains the following:

field_info: {
'boost_pads': [
{
'location': Vector3,
'is_full_boost': boolean
},
{ ... }
],
'num_boosts': int,
'goals': [
{
'team_num': int,
'location': Vector3,
'direction': Vector3,
'width': float,
'height': float
},
{ ... }
],
'num_goals': int
}

Note: Dropshot tiles can be found in FieldInfo as GoalInfo objects. Note2: Boost pads and Dropshot tiles will be sorted according to y * 100 + x, just like their counterparts (game_boosts and dropshot_tiles that contain their current state) in the game tick packet.

In Python, you can retrieve this information by calling get_field_info() on the BaseAgent:

fromrlbot.agents.base_agentimportBaseAgent, SimpleControllerStatefromrlbot.utils.structures.game_data_structimportGameTickPacketclassExampleBot(BaseAgent):
definitialize_agent(self):
passdefget_output(self, packet: GameTickPacket) ->SimpleControllerState:
# Constant values can be found the the FieldInfo:info=self.get_field_info()
# Manually construct a list of all big boost pads# info.boost_pads has a fixed size but info.num_boosts is how many pads there actually arebig_pads= []
foriinrange(info.num_boosts):
pad=info.boost_pads[i]
ifpad.is_full_boost:
big_pads.append(pad)

Match settings (mutators & gamemode)

Mutators can only be set before the game starts by a human.

To get the current mutators, do something like this:

fromrlbot.messages.flat.BoostOptionimportBoostOptiondefinitialize_agent(self):
# See all of the match settings at https://github.com/RLBot/RLBot/blob/master/src/main/flatbuffers/rlbot.fbs#L784match_settings=self.get_match_settings()
mutators=match_settings.MutatorSettings()
# Examples# Game modegame_mode= (
"soccer",
"hoops",
"dropshot",
"hockey",
"rumble",
"heatseeker"
)
self.gamemode=game_mode[match_settings.GameMode()]
# View all mutator options at https://github.com/RLBot/RLBot/blob/master/src/main/flatbuffers/rlbot.fbs#L753# Boost amountifmutators.BoostOption() ==BoostOption.Unlimited_Boost:
# Do whatever# Boost acceleration# Leverage some known constants to get an acceleration value based on the setting.# These values are from the Physics section of the Useful Game Values wiki -> https://github.com/RLBot/RLBot/wiki/Useful-Game-Values#physicsbase_boost_accel=991+ (2/3)
boost_accel= (
base_boost_accel, # Defaultbase_boost_accel*1.5, # Strength x 1.5base_boost_accel*2, # Strength x 2base_boost_accel*10# Strength x 10
)
self.boost_accel=boost_accel[mutators.BoostStrengthOption()]

Documentation on what it means

You can find descriptions of the tricky values in this file:

https://github.com/RLBot/RLBot/blob/master/src/main/flatbuffers/rlbot.fbs

You will recognize some of the previous mentioned classes as tables. I.e. packet.score_info is a ScoreInfo table.

Clone this wiki locally

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Input and Output Data

redd edited this page Nov 25, 2022 · 36 revisions

BaseAgent

The base agent has some useful values that we can read from in order to get some basic information about the car that we are controlling, the team our car is on, and even the name of our car in the game.

These values can be accessed at any time from the base agent using the self parameter:

definitialize_agent(self):
# Print the bot's teamprint(self.team)
defget_output(self, packet: GameTickPacket) ->SimpleControllerState:
# Get our carmy_car=packet.game_cars[self.index]

Some useful values to know are:

self.team=0# The team that our bot is onself.name="ExampleBot"# Our bot's in-game nameself.index=2# The index of the car our agent is controlling

GameTickPacket

Every tick, your bot will receive a GameTickPacket from the framework. The packet will contain all the raw values from the game (such as car and ball locations). Your bot receives the packet in the get_output(self, packet) function and you should return a ControllerState which describes what your bot's response is.

Getting values from the packet is simple:

defget_output(self, packet: GameTickPacket) ->SimpleControllerState:
# You can get values out of the packet like this:x_location_of_first_car=packet.game_cars[0].physics.location.x;

NOTE: Some structs/lists in the GameTickPacket has a fixed length. So make sure you use the num_cars and the num_boosts values as lengths if you iterate through the associated lists.

Sample game tick packet

packet: {
'game_cars': [
{
'physics': {
'location': {'x': 0.0, 'y': 0.0, 'z': 0.0},
'rotation': {'pitch': 0.0, 'yaw': 0.0, 'roll': 0.0},
'velocity': {'x': 0.0, 'y': 0.0, 'z': 0.0},
'angular_velocity': {'x': 0.0, 'y': 0.0, 'z': 0.0}
},
'is_demolished': False,
'has_wheel_contact': True,
'is_super_sonic': False,
'is_bot': True,
'jumped': False,
'double_jumped': True,
'name': 'Jupiter',
'team': 0,
'boost': 48.0,
'hitbox': {'length': 118, 'width': 84, 'height': 36},
'hitbox_offset': {'x': 13.88, 'y': 0.0, 'z': 20.75},
'score_info': {
'score': 340,
'goals': 2,
'own_goals': 0,
'assists': 1,
'saves': 1,
'shots': 3,
'demolitions': 1
}
},
{ ... }
],
'num_cars': 2,
'game_boosts': [
{
'is_active': True,
'timer': 0.0
},
{ ... }
],
'num_boost': 36,
'game_ball': {
'physics': {
'location': {'x': 0.0, 'y': 0.0, 'z': 0.0},
'rotation': {'pitch': 0.0, 'yaw': 0.0, 'roll': 0.0},
'velocity': {'x': 0.0, 'y': 0.0, 'z': 0.0},
'angular_velocity': {'x': 0.0, 'y': 0.0, 'z': 0.0}
},
'latest_touch': {
'player_name': 'Beavis',
'time_seconds': 120.63,
'hit_location': {'x': 0.0, 'y': 0.0, 'z': 0.0},
'hit_normal': {'x': 0.0, 'y': 0.0, 'z': 0.0},
'team': 0,
'player_index': 0
},
'drop_shot_info': {
'damage_index': 0,
'absorbed_force': 0,
'force_accum_recent': 0
},
'collision_shape': {
'type': 1,
'box': {'length': 153.0, 'width': 153.0, 'height': 153.0},
'sphere': {'diameter': 184.0},
'cylinder': {'diameter': 184.0, 'height': 30.0}
}
},
'game_info': {
'seconds_elapsed': 405.12,
'game_time_remaining': 34.0,
'is_overtime': False,
'is_unlimited_time': False,
'is_round_active': True,
'is_kickoff_pause': False,
'is_match_ended': False,
'world_gravity_z': -650.0,
'game_speed': 1.0,
'frame_num': 3923
},
'teams': [
{
'team_index': 0,
'score': 7
},
{ ... }
],
'num_teams': 2,
}

ControllerState

A ControllerState is the controller input the bot should perform. Import ControllerState like this: from rlbot.agents.base_agent import SimpleControllerState, and create a new instance with SimpleControllerState()

Example:

fromrlbot.agents.base_agentimportBaseAgent, SimpleControllerStatefromrlbot.utils.structures.game_data_structimportGameTickPacketclassExampleBot(BaseAgent):
definitialize_agent(self):
passdefget_output(self, packet: GameTickPacket) ->SimpleControllerState:
# Make the bot go forwards by setting throttle to 1controller=SimpleControllerState()
controller.throttle=1returncontroller

The ControllerState has the following attributes:

{
throttle:float; /// -1 for full reverse, 1 for full forward
steer:float; /// -1 for full left, 1 for full right
pitch:float; /// -1 for nose down, 1 for nose up
yaw:float; /// -1 for full left, 1 for full right
roll:float; /// -1 for roll left, 1 for roll right
jump:bool; /// true if you want to press the jump button
boost:bool; /// true if you want to press the boost button
handbrake:bool; /// true if you want to press the handbrake button
use_item:bool; /// true if you want to use a rumble item
}

Field Info

A few values are constant, like the locations of boosts and goals. Some of these can be found in the FieldInfo data. FieldInfo contains the following:

field_info: {
'boost_pads': [
{
'location': Vector3,
'is_full_boost': boolean
},
{ ... }
],
'num_boosts': int,
'goals': [
{
'team_num': int,
'location': Vector3,
'direction': Vector3,
'width': float,
'height': float
},
{ ... }
],
'num_goals': int
}

Note: Dropshot tiles can be found in FieldInfo as GoalInfo objects. Note2: Boost pads and Dropshot tiles will be sorted according to y * 100 + x, just like their counterparts (game_boosts and dropshot_tiles that contain their current state) in the game tick packet.

In Python, you can retrieve this information by calling get_field_info() on the BaseAgent:

fromrlbot.agents.base_agentimportBaseAgent, SimpleControllerStatefromrlbot.utils.structures.game_data_structimportGameTickPacketclassExampleBot(BaseAgent):
definitialize_agent(self):
passdefget_output(self, packet: GameTickPacket) ->SimpleControllerState:
# Constant values can be found the the FieldInfo:info=self.get_field_info()
# Manually construct a list of all big boost pads# info.boost_pads has a fixed size but info.num_boosts is how many pads there actually arebig_pads= []
foriinrange(info.num_boosts):
pad=info.boost_pads[i]
ifpad.is_full_boost:
big_pads.append(pad)

Match settings (mutators & gamemode)

Mutators can only be set before the game starts by a human.

To get the current mutators, do something like this:

fromrlbot.messages.flat.BoostOptionimportBoostOptiondefinitialize_agent(self):
# See all of the match settings at https://github.com/RLBot/RLBot/blob/master/src/main/flatbuffers/rlbot.fbs#L784match_settings=self.get_match_settings()
mutators=match_settings.MutatorSettings()
# Examples# Game modegame_mode= (
"soccer",
"hoops",
"dropshot",
"hockey",
"rumble",
"heatseeker"
)
self.gamemode=game_mode[match_settings.GameMode()]
# View all mutator options at https://github.com/RLBot/RLBot/blob/master/src/main/flatbuffers/rlbot.fbs#L753# Boost amountifmutators.BoostOption() ==BoostOption.Unlimited_Boost:
# Do whatever# Boost acceleration# Leverage some known constants to get an acceleration value based on the setting.# These values are from the Physics section of the Useful Game Values wiki -> https://github.com/RLBot/RLBot/wiki/Useful-Game-Values#physicsbase_boost_accel=991+ (2/3)
boost_accel= (
base_boost_accel, # Defaultbase_boost_accel*1.5, # Strength x 1.5base_boost_accel*2, # Strength x 2base_boost_accel*10# Strength x 10
)
self.boost_accel=boost_accel[mutators.BoostStrengthOption()]

Documentation on what it means

You can find descriptions of the tricky values in this file:

https://github.com/RLBot/RLBot/blob/master/src/main/flatbuffers/rlbot.fbs

You will recognize some of the previous mentioned classes as tables. I.e. packet.score_info is a ScoreInfo table.

Clone this wiki locally

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Input and Output Data

redd edited this page Nov 25, 2022 · 36 revisions

BaseAgent

The base agent has some useful values that we can read from in order to get some basic information about the car that we are controlling, the team our car is on, and even the name of our car in the game.

These values can be accessed at any time from the base agent using the self parameter:

definitialize_agent(self):
# Print the bot's teamprint(self.team)
defget_output(self, packet: GameTickPacket) ->SimpleControllerState:
# Get our carmy_car=packet.game_cars[self.index]

Some useful values to know are:

self.team=0# The team that our bot is onself.name="ExampleBot"# Our bot's in-game nameself.index=2# The index of the car our agent is controlling

GameTickPacket

Every tick, your bot will receive a GameTickPacket from the framework. The packet will contain all the raw values from the game (such as car and ball locations). Your bot receives the packet in the get_output(self, packet) function and you should return a ControllerState which describes what your bot's response is.

Getting values from the packet is simple:

defget_output(self, packet: GameTickPacket) ->SimpleControllerState:
# You can get values out of the packet like this:x_location_of_first_car=packet.game_cars[0].physics.location.x;

NOTE: Some structs/lists in the GameTickPacket has a fixed length. So make sure you use the num_cars and the num_boosts values as lengths if you iterate through the associated lists.

Sample game tick packet

packet: {
'game_cars': [
{
'physics': {
'location': {'x': 0.0, 'y': 0.0, 'z': 0.0},
'rotation': {'pitch': 0.0, 'yaw': 0.0, 'roll': 0.0},
'velocity': {'x': 0.0, 'y': 0.0, 'z': 0.0},
'angular_velocity': {'x': 0.0, 'y': 0.0, 'z': 0.0}
},
'is_demolished': False,
'has_wheel_contact': True,
'is_super_sonic': False,
'is_bot': True,
'jumped': False,
'double_jumped': True,
'name': 'Jupiter',
'team': 0,
'boost': 48.0,
'hitbox': {'length': 118, 'width': 84, 'height': 36},
'hitbox_offset': {'x': 13.88, 'y': 0.0, 'z': 20.75},
'score_info': {
'score': 340,
'goals': 2,
'own_goals': 0,
'assists': 1,
'saves': 1,
'shots': 3,
'demolitions': 1
}
},
{ ... }
],
'num_cars': 2,
'game_boosts': [
{
'is_active': True,
'timer': 0.0
},
{ ... }
],
'num_boost': 36,
'game_ball': {
'physics': {
'location': {'x': 0.0, 'y': 0.0, 'z': 0.0},
'rotation': {'pitch': 0.0, 'yaw': 0.0, 'roll': 0.0},
'velocity': {'x': 0.0, 'y': 0.0, 'z': 0.0},
'angular_velocity': {'x': 0.0, 'y': 0.0, 'z': 0.0}
},
'latest_touch': {
'player_name': 'Beavis',
'time_seconds': 120.63,
'hit_location': {'x': 0.0, 'y': 0.0, 'z': 0.0},
'hit_normal': {'x': 0.0, 'y': 0.0, 'z': 0.0},
'team': 0,
'player_index': 0
},
'drop_shot_info': {
'damage_index': 0,
'absorbed_force': 0,
'force_accum_recent': 0
},
'collision_shape': {
'type': 1,
'box': {'length': 153.0, 'width': 153.0, 'height': 153.0},
'sphere': {'diameter': 184.0},
'cylinder': {'diameter': 184.0, 'height': 30.0}
}
},
'game_info': {
'seconds_elapsed': 405.12,
'game_time_remaining': 34.0,
'is_overtime': False,
'is_unlimited_time': False,
'is_round_active': True,
'is_kickoff_pause': False,
'is_match_ended': False,
'world_gravity_z': -650.0,
'game_speed': 1.0,
'frame_num': 3923
},
'teams': [
{
'team_index': 0,
'score': 7
},
{ ... }
],
'num_teams': 2,
}

ControllerState

A ControllerState is the controller input the bot should perform. Import ControllerState like this: from rlbot.agents.base_agent import SimpleControllerState, and create a new instance with SimpleControllerState()

Example:

fromrlbot.agents.base_agentimportBaseAgent, SimpleControllerStatefromrlbot.utils.structures.game_data_structimportGameTickPacketclassExampleBot(BaseAgent):
definitialize_agent(self):
passdefget_output(self, packet: GameTickPacket) ->SimpleControllerState:
# Make the bot go forwards by setting throttle to 1controller=SimpleControllerState()
controller.throttle=1returncontroller

The ControllerState has the following attributes:

{
throttle:float; /// -1 for full reverse, 1 for full forward
steer:float; /// -1 for full left, 1 for full right
pitch:float; /// -1 for nose down, 1 for nose up
yaw:float; /// -1 for full left, 1 for full right
roll:float; /// -1 for roll left, 1 for roll right
jump:bool; /// true if you want to press the jump button
boost:bool; /// true if you want to press the boost button
handbrake:bool; /// true if you want to press the handbrake button
use_item:bool; /// true if you want to use a rumble item
}

Field Info

A few values are constant, like the locations of boosts and goals. Some of these can be found in the FieldInfo data. FieldInfo contains the following:

field_info: {
'boost_pads': [
{
'location': Vector3,
'is_full_boost': boolean
},
{ ... }
],
'num_boosts': int,
'goals': [
{
'team_num': int,
'location': Vector3,
'direction': Vector3,
'width': float,
'height': float
},
{ ... }
],
'num_goals': int
}

Note: Dropshot tiles can be found in FieldInfo as GoalInfo objects. Note2: Boost pads and Dropshot tiles will be sorted according to y * 100 + x, just like their counterparts (game_boosts and dropshot_tiles that contain their current state) in the game tick packet.

In Python, you can retrieve this information by calling get_field_info() on the BaseAgent:

fromrlbot.agents.base_agentimportBaseAgent, SimpleControllerStatefromrlbot.utils.structures.game_data_structimportGameTickPacketclassExampleBot(BaseAgent):
definitialize_agent(self):
passdefget_output(self, packet: GameTickPacket) ->SimpleControllerState:
# Constant values can be found the the FieldInfo:info=self.get_field_info()
# Manually construct a list of all big boost pads# info.boost_pads has a fixed size but info.num_boosts is how many pads there actually arebig_pads= []
foriinrange(info.num_boosts):
pad=info.boost_pads[i]
ifpad.is_full_boost:
big_pads.append(pad)

Match settings (mutators & gamemode)

Mutators can only be set before the game starts by a human.

To get the current mutators, do something like this:

fromrlbot.messages.flat.BoostOptionimportBoostOptiondefinitialize_agent(self):
# See all of the match settings at https://github.com/RLBot/RLBot/blob/master/src/main/flatbuffers/rlbot.fbs#L784match_settings=self.get_match_settings()
mutators=match_settings.MutatorSettings()
# Examples# Game modegame_mode= (
"soccer",
"hoops",
"dropshot",
"hockey",
"rumble",
"heatseeker"
)
self.gamemode=game_mode[match_settings.GameMode()]
# View all mutator options at https://github.com/RLBot/RLBot/blob/master/src/main/flatbuffers/rlbot.fbs#L753# Boost amountifmutators.BoostOption() ==BoostOption.Unlimited_Boost:
# Do whatever# Boost acceleration# Leverage some known constants to get an acceleration value based on the setting.# These values are from the Physics section of the Useful Game Values wiki -> https://github.com/RLBot/RLBot/wiki/Useful-Game-Values#physicsbase_boost_accel=991+ (2/3)
boost_accel= (
base_boost_accel, # Defaultbase_boost_accel*1.5, # Strength x 1.5base_boost_accel*2, # Strength x 2base_boost_accel*10# Strength x 10
)
self.boost_accel=boost_accel[mutators.BoostStrengthOption()]

Documentation on what it means

You can find descriptions of the tricky values in this file:

https://github.com/RLBot/RLBot/blob/master/src/main/flatbuffers/rlbot.fbs

You will recognize some of the previous mentioned classes as tables. I.e. packet.score_info is a ScoreInfo table.

Clone this wiki locally

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Input and Output Data

redd edited this page Nov 25, 2022 · 36 revisions

BaseAgent

The base agent has some useful values that we can read from in order to get some basic information about the car that we are controlling, the team our car is on, and even the name of our car in the game.

These values can be accessed at any time from the base agent using the self parameter:

definitialize_agent(self):
# Print the bot's teamprint(self.team)
defget_output(self, packet: GameTickPacket) ->SimpleControllerState:
# Get our carmy_car=packet.game_cars[self.index]

Some useful values to know are:

self.team=0# The team that our bot is onself.name="ExampleBot"# Our bot's in-game nameself.index=2# The index of the car our agent is controlling

GameTickPacket

Every tick, your bot will receive a GameTickPacket from the framework. The packet will contain all the raw values from the game (such as car and ball locations). Your bot receives the packet in the get_output(self, packet) function and you should return a ControllerState which describes what your bot's response is.

Getting values from the packet is simple:

defget_output(self, packet: GameTickPacket) ->SimpleControllerState:
# You can get values out of the packet like this:x_location_of_first_car=packet.game_cars[0].physics.location.x;

NOTE: Some structs/lists in the GameTickPacket has a fixed length. So make sure you use the num_cars and the num_boosts values as lengths if you iterate through the associated lists.

Sample game tick packet

packet: {
'game_cars': [
{
'physics': {
'location': {'x': 0.0, 'y': 0.0, 'z': 0.0},
'rotation': {'pitch': 0.0, 'yaw': 0.0, 'roll': 0.0},
'velocity': {'x': 0.0, 'y': 0.0, 'z': 0.0},
'angular_velocity': {'x': 0.0, 'y': 0.0, 'z': 0.0}
},
'is_demolished': False,
'has_wheel_contact': True,
'is_super_sonic': False,
'is_bot': True,
'jumped': False,
'double_jumped': True,
'name': 'Jupiter',
'team': 0,
'boost': 48.0,
'hitbox': {'length': 118, 'width': 84, 'height': 36},
'hitbox_offset': {'x': 13.88, 'y': 0.0, 'z': 20.75},
'score_info': {
'score': 340,
'goals': 2,
'own_goals': 0,
'assists': 1,
'saves': 1,
'shots': 3,
'demolitions': 1
}
},
{ ... }
],
'num_cars': 2,
'game_boosts': [
{
'is_active': True,
'timer': 0.0
},
{ ... }
],
'num_boost': 36,
'game_ball': {
'physics': {
'location': {'x': 0.0, 'y': 0.0, 'z': 0.0},
'rotation': {'pitch': 0.0, 'yaw': 0.0, 'roll': 0.0},
'velocity': {'x': 0.0, 'y': 0.0, 'z': 0.0},
'angular_velocity': {'x': 0.0, 'y': 0.0, 'z': 0.0}
},
'latest_touch': {
'player_name': 'Beavis',
'time_seconds': 120.63,
'hit_location': {'x': 0.0, 'y': 0.0, 'z': 0.0},
'hit_normal': {'x': 0.0, 'y': 0.0, 'z': 0.0},
'team': 0,
'player_index': 0
},
'drop_shot_info': {
'damage_index': 0,
'absorbed_force': 0,
'force_accum_recent': 0
},
'collision_shape': {
'type': 1,
'box': {'length': 153.0, 'width': 153.0, 'height': 153.0},
'sphere': {'diameter': 184.0},
'cylinder': {'diameter': 184.0, 'height': 30.0}
}
},
'game_info': {
'seconds_elapsed': 405.12,
'game_time_remaining': 34.0,
'is_overtime': False,
'is_unlimited_time': False,
'is_round_active': True,
'is_kickoff_pause': False,
'is_match_ended': False,
'world_gravity_z': -650.0,
'game_speed': 1.0,
'frame_num': 3923
},
'teams': [
{
'team_index': 0,
'score': 7
},
{ ... }
],
'num_teams': 2,
}

ControllerState

A ControllerState is the controller input the bot should perform. Import ControllerState like this: from rlbot.agents.base_agent import SimpleControllerState, and create a new instance with SimpleControllerState()

Example:

fromrlbot.agents.base_agentimportBaseAgent, SimpleControllerStatefromrlbot.utils.structures.game_data_structimportGameTickPacketclassExampleBot(BaseAgent):
definitialize_agent(self):
passdefget_output(self, packet: GameTickPacket) ->SimpleControllerState:
# Make the bot go forwards by setting throttle to 1controller=SimpleControllerState()
controller.throttle=1returncontroller

The ControllerState has the following attributes:

{
throttle:float; /// -1 for full reverse, 1 for full forward
steer:float; /// -1 for full left, 1 for full right
pitch:float; /// -1 for nose down, 1 for nose up
yaw:float; /// -1 for full left, 1 for full right
roll:float; /// -1 for roll left, 1 for roll right
jump:bool; /// true if you want to press the jump button
boost:bool; /// true if you want to press the boost button
handbrake:bool; /// true if you want to press the handbrake button
use_item:bool; /// true if you want to use a rumble item
}

Field Info

A few values are constant, like the locations of boosts and goals. Some of these can be found in the FieldInfo data. FieldInfo contains the following:

field_info: {
'boost_pads': [
{
'location': Vector3,
'is_full_boost': boolean
},
{ ... }
],
'num_boosts': int,
'goals': [
{
'team_num': int,
'location': Vector3,
'direction': Vector3,
'width': float,
'height': float
},
{ ... }
],
'num_goals': int
}

Note: Dropshot tiles can be found in FieldInfo as GoalInfo objects. Note2: Boost pads and Dropshot tiles will be sorted according to y * 100 + x, just like their counterparts (game_boosts and dropshot_tiles that contain their current state) in the game tick packet.

In Python, you can retrieve this information by calling get_field_info() on the BaseAgent:

fromrlbot.agents.base_agentimportBaseAgent, SimpleControllerStatefromrlbot.utils.structures.game_data_structimportGameTickPacketclassExampleBot(BaseAgent):
definitialize_agent(self):
passdefget_output(self, packet: GameTickPacket) ->SimpleControllerState:
# Constant values can be found the the FieldInfo:info=self.get_field_info()
# Manually construct a list of all big boost pads# info.boost_pads has a fixed size but info.num_boosts is how many pads there actually arebig_pads= []
foriinrange(info.num_boosts):
pad=info.boost_pads[i]
ifpad.is_full_boost:
big_pads.append(pad)

Match settings (mutators & gamemode)

Mutators can only be set before the game starts by a human.

To get the current mutators, do something like this:

fromrlbot.messages.flat.BoostOptionimportBoostOptiondefinitialize_agent(self):
# See all of the match settings at https://github.com/RLBot/RLBot/blob/master/src/main/flatbuffers/rlbot.fbs#L784match_settings=self.get_match_settings()
mutators=match_settings.MutatorSettings()
# Examples# Game modegame_mode= (
"soccer",
"hoops",
"dropshot",
"hockey",
"rumble",
"heatseeker"
)
self.gamemode=game_mode[match_settings.GameMode()]
# View all mutator options at https://github.com/RLBot/RLBot/blob/master/src/main/flatbuffers/rlbot.fbs#L753# Boost amountifmutators.BoostOption() ==BoostOption.Unlimited_Boost:
# Do whatever# Boost acceleration# Leverage some known constants to get an acceleration value based on the setting.# These values are from the Physics section of the Useful Game Values wiki -> https://github.com/RLBot/RLBot/wiki/Useful-Game-Values#physicsbase_boost_accel=991+ (2/3)
boost_accel= (
base_boost_accel, # Defaultbase_boost_accel*1.5, # Strength x 1.5base_boost_accel*2, # Strength x 2base_boost_accel*10# Strength x 10
)
self.boost_accel=boost_accel[mutators.BoostStrengthOption()]

Documentation on what it means

You can find descriptions of the tricky values in this file:

https://github.com/RLBot/RLBot/blob/master/src/main/flatbuffers/rlbot.fbs

You will recognize some of the previous mentioned classes as tables. I.e. packet.score_info is a ScoreInfo table.

Clone this wiki locally