rlbot-flatbuffers 0.18.6
A Python module implemented in Rust for serializing and deserializing RLBot's flatbuffers
Requires Python: >=3.10

## rlbot-flatbuffers

A Python module implemented in Rust for fast and safe serialization and deserialization of RLBot's flatbuffers

### The goal of this project

A majority of the code is auto-generated by `codegen/` upon first compile
using the RLBot's schema as defined by the `flatbuffers-schema` submodule.

This includes the code generated by Planus (`src/planus_flat.rs`),
the Python wrapper binds to the generated Rust code (`src/python/`),
and the Python type hints (`rlbot_flatbuffers.pyi`).

Usage of this API should not significantly differ from RLBot v4 to reduce developer confusion, while not holding back changes that would make the API easier to work with.

### Minimum support Python version

The crate used to generate Python binds (PyO3) supports all the way back to Python 3.7, however the minimum supported Python version is 3.10 for a few reasons:

1. RLBot v4 currently runs Python 3.11
1. The RLBot v5's [Python interface](https://github.com/RLBot/python-interface) has a minimum Python version of 3.11, but the difference between 3.10 and 3.11 doesn't mean much for these binds specifically.
1. Python 3.10 is the version of Python that added `match`/`case`
1. [Python 3.7 & 3.8 are EOL, with 3.9's EOL date being 2025-10](https://devguide.python.org/versions/)

### Dev setup

- Ensure Python 3.10+ is installed
- Create a virtual Python environment
    - `python3 -m venv venv`
- Activate the virtual environment
    - Windows: `venv\Scripts\activate.bat`
    - Linux: `source venv/bin/activate`
- Install maturin
    - `pip install maturin`
- Build & install for testing
    - `maturin develop --release`

To use in another Python environment, like if testing [python-interface](https://github.com/RLBot/python-interface), you can build the wheel:

- `maturin build --release`
- (In another environment) `pip install path/to/file.whl`

The exact path of the wheel will be printed by maturin, just copy+paste it.

### Basic usage

All classes and methods should have types hints readable by your IDE, removing the guesswork of common operations.

#### Creating

```python
import rlbot_flatbuffers as flat

desired_ball = flat.DesiredBallState(
    physics=flat.Physics(
        location=flat.Vector3Partial(z=200),
        velocity=flat.Vector3Partial(x=1500, y=1500),
        angular_velocity=flat.Vector3Partial(),
    ),
)

desired_game_info = flat.DesiredGameInfoState(
    world_gravity_z=-100,
    game_speed=2,
)

desired_game_state = flat.DesiredGameState(
    ball_state=desired_ball,
    game_info_state=desired_game_info,
)
```

In the above code, we:

- Set the ball to:
    - Location (0, 0, 200)
    - Velocity (1500, 1500, 0)
    - Angular velocity of (0, 0, 0)
- Don't set the car states
- Set the game info state:
    - World gravity to -100
    - Game speed to 2x default
    - Don't set end match or paused
- Don't set any console commands

All values are optional when creating a class and have the proper defaults.

#### Reading values

```python
import rlbot_flatbuffers as flat

def handle_packet(packet: flat.GamePacket):
    if packet.match_info.match_phase not in {
        flat.MatchPhase.Active,
        flat.MatchPhase.Kickoff,
    }:
        # Return early if the game isn't active
        return

    # Print the ball's location
    print(packet.ball.physics.location)

    for car in packet.players:
        # Print the every car's location
        print(car.physics.location)
```

The goal of the above was to feel familiar to RLBot v4 while providing a more Pythonic interface.

- Unions aren't custom types, rather a normal Python variable that can be 1 of a few types.
    - For example, previously [`BallInfo.shape` had the separate type `CollisionShape` which contained the union's data](https://github.com/RLBot/RLBot/blob/e34dd4598bc643e2b8e50b77f7ffe4ca38e335de/src/main/python/rlbot/utils/structures/game_data_struct.pyi#L65-L95) but the type is now just `BoxShape | CylinderShape | SphereShape`

- Classes implement `__match_args__` for easy destructuring via the `match`/`case` pattern.
    - Enums can still be used to match against the type,
      they just can't be destructured.
- Classes and enums properly implement `__repr__`, with `__str__` being an alias.
- Enums implement `__hash__`, `__int__` and `__eq__`.
- Lists no longer have `num_x` fields accompanying them,
  they are just Python lists of the appropriate length.
- Classes implement `pack` and `unpack`,
  which are used to serialize and deserialize data.
    - These are public methods that can be used directly for any purpose,
      for example saving `flat.GamePacket` to a file.

- Auto-generated python type stub (`.pyi`) generation that includes doc comments from the Flatbuffers schema