CDS-interpret
See what your Rocket League bot is thinking.
Your bot's brain is a neural network: thousands of numbers that somehow turn into saves, shots and demos. CDS-interpret lets you look inside it. You can ask it questions ("does it know the ball is about to go in my goal?"), find the ideas it has learned on its own, switch one off to see what changes - and watch all of it live, on screen, while it plays.
The thoughts panel, drawn in the corner of the screen during a match. (Shown here outside the game.)
CDS-interpret is the interpretability toolkit from the Cat Distribution System (CDS), published on its own while the bigger CDS framework is still being finished. It works with any bot whose brain is a PyTorch network - one trained with RLGym (the Python toolkit most Rocket League bots are trained with), rlgym-ppo, a C++ trainer whose network you can load into PyTorch, or your own code - and shows its thoughts live in RLBot, the framework that runs bots in the real game. It runs on an ordinary CPU; no GPU needed.
Try it in five minutes
You need Python 3.11 or newer. The first install also downloads PyTorch, which takes a while; the five minutes start after that.
python -m venv .venv
.venv\Scripts\activate # on macOS / Linux: source .venv/bin/activate
pip install "cds-interpret[rlgym,rlbot]"
cds-interpret demo
(On Linux, pip picks PyTorch's GPU build, several GB. For the small CPU build, run
pip install torch --index-url https://download.pytorch.org/whl/cpu before the line above.)
The demo takes a tiny built-in bot, records a few games of it in RocketSim (a fast Rocket League simulator), and looks inside it. In a few minutes you'll see something like this:
Step 2 of 4 - asking every layer questions about the game (probes)
concept layer score input random measure steady
Worked out by the network (at least 0.05 better than both):
ball_dist (distance to the ball) body.1 0.89 -0.04 0.50 R2 yes
...
Step 4 of 4 - switching ideas off to see whether the bot uses them (edits)
'goal_side' probe direction removed at body.3: the bot's choice changes on 15% of moments (KL 0.125)
a random direction removed at body.3 (the control; 3 tries): the bot's choice changes on 10% of moments (KL 0.022)
...
All done. The full picture - every probe, the features with their moments drawn on the field, the edits - is in
cds-demo\report.html
How to read it: each row asks the bot one question, here "how far away is the ball?". score is how well its best layer answers, on games it never learned from (for a number that's R2: 0 is a guess, 1 perfect; for a yes / no question, AUROC: 0.5 is a guess, 1 perfect). input and random ask the same question of the bot's raw input and of a copy of the network with random weights - so 0.89 against -0.04 and 0.50 means the network worked the distance out for itself. In step 4, KL measures how far the bot's choices moved when an idea was switched off (0 is not at all): removing the "goal side" direction moves them about six times as much as removing a random one.
Open cds-demo/report.html in your browser. It shows what the bot knows, the ideas it uses, and moments from its games
drawn from above.
On Python 3.13, leave out rlgym (pip install "cds-interpret[rlbot]"): RLGym doesn't support 3.13 yet,
so the demo uses random game moments instead of recorded games. Everything else works.
Then on your own bot
Tell the toolkit three things about your bot: its network, how it builds its input from the game, and its list of actions.
import cds_interpret as ci
policy = ci.Policy(
my_network, # your torch.nn.Module
obs=my_obs, # my_obs(frames, me): your bot's input, built from the game state
actions=ci.lookup_table(), # the controls behind each action number (or your bot's own table)
)
moments = ci.record.rocketsim(policy, games=20, seconds=120) # watch it play 20 games
study = ci.Study(policy, moments)
print(study.probes().summary()) # what each layer knows
study.report("my-bot.html") # everything, on one page
Don't want to write my_obs? Record your bot in the real game instead; the recorder keeps the exact inputs your
network saw. The quickstart walks through both ways, step by step.
What you can do with it
- Ask your bot questions. A probe is a small readout that asks the network one question, like "will the ball land near me?" or "am I first to the ball?". The toolkit asks dozens of them at every layer, scores the answers on games it never trained on, and asks the same of the bot's raw input and of a random copy of the network - so you learn what the network worked out, not what was already in its input.
- Find the ideas it uses. A sparse autoencoder is a tool that finds the separate ideas a network uses - one for "lined up for a shot", another for "about to lose the ball". The toolkit suggests a name for each idea from the game, draws its strongest moments on the field, and keeps your confirmed names in a small names file. Name your bot's features.
- Check that it really uses them. Switch an idea off, or turn it up, and see what the bot does differently - on recorded moments, or over whole games with a proper error bar.
- Watch it think, live. Wrap your RLBot bot in one line and its thoughts appear on screen while it plays: its outlook, its next move and how sure it is, what it is noticing, where it thinks the ball will land. It reads your network without changing it, so your bot plays exactly the same. Watch it think in RLBot.
- See why it makes each move, live. "Why this move" names the ideas pushing the bot toward the move it's about to make (and the one pushing against it); "Looking at" shows what that move rests on - its own car, the ball, the opponents, the team-mates. Why this move, and what it's looking at.
- 2v2 and 3v3 too. Every car gets its own landing ring, and the panel follows the car you watch with the spectator camera - or a fixed car, or one picked for the match. Team modes.
- Watch a bot you can't modify. A small RLBot script draws the same panel over a bot that runs on its own - a compiled bot, one in another language - from its weights and a port of its observation. Thoughts for a bot you can't modify.
- Keep your panel as your bot trains. One command carries a pack's names over to a newer checkpoint, by what the features fire on, and refits the rest. Keep your panel.
- Design your own panel. Pick the rows, names, colours, size and position in a small TOML file, or draw your own rows in Python. Customize the panel.
- Record games three ways. In RocketSim against itself or a scripted opponent, in the real game through RLBot, or in your own RLGym environment.
- See what a decision rests on. Was it the ball, its own car or the opponent? Which of its ideas tipped it? Shapley values - a fair way of splitting credit between things that act together - say, with a score for how far to trust the answer. See what a decision rests on.
- See what your bot learns between checkpoints. What each new checkpoint picked up, in its habits and in its choices on the same moments; how healthy its layers are; and which situations it should practise next. Follow a bot through training.
- Check your tools. Every technique has a quiet way to mislead; the toolkit measures each one - autoencoders true to the bot's choices, features that a second run finds again, probes the bot really uses, and panel readings whose 40% really means 40%. Check your tools.
- Share what you find. Every study becomes one HTML page with charts and field drawings, light and dark.
Documentation
| Quickstart | five minutes on the demo bot, then your own |
| How it works | the ideas behind it, in plain words |
| Bring your own bot | wrapping any network: actor-critics, TorchScript, RLGym observations |
| Record games | RocketSim, the real game, your RLGym env, your own data |
| Ask questions with probes | probing layers, and probes steady enough to show live |
| Find the ideas it uses | sparse autoencoders and their features |
| Name your bot's features | from numbers to names you trust, end to end |
| Test what it relies on | switching ideas off and up, in moments and in games |
| See what a decision rests on | the ball, its car, the opponents; and what each feature does |
| Check your tools | how to tell when a technique is misleading you |
| Watch it think in RLBot | the live thoughts overlay |
| Why this move, and what it's looking at | the panel's two rows about each decision: how to read them, what they cost |
| Team modes | 2v2 and 3v3: a ring for every car, a panel that follows the camera |
| Thoughts for a bot you can't modify | a display-only script over a bot that runs on its own |
| Keep your panel when your bot trains on | a pack carried over to a newer checkpoint, in one command |
| Customize the panel | every option of the panel's TOML file, and Python hooks |
| Reports and drawings | the HTML page, its sections, the drawings |
| See what it learns between checkpoints | checkpoint after checkpoint, and what to practise next |
| Labels | every game-state fact the toolkit works out, and adding your own |
| Coming from rlgym-ppo or GigaLearn | where the things you know fit |
| API reference | every function and class |
| When something goes wrong | error messages and what to do |
Contributing
New techniques, labels, recorders, fixes and docs are all welcome. CONTRIBUTING.md explains where new things slot in. Changes are listed in CHANGELOG.md.
License
MIT - see LICENSE. The libraries it uses keep their own licenses: see THIRD_PARTY.md. Rocket League is a trademark of Psyonix. This project is not affiliated with Psyonix, Epic Games, RLBot or RLGym.
Metadata
Release files for cds-interpret 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| cds_interpret-0.2.0.tar.gz | 1.6 MB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| cds_interpret-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 1.9 MB
Release files / cds_interpret-0.2.0.tar.gz
| Download URL | cds_interpret-0.2.0.tar.gz |
|---|---|
| Size | 1.6 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
0fb3388b6e1899a7fa1273529291cb91372d2e689f17c4ccef6c1688e72ec8fb
|
|
BLAKE2b-256 checksum How to use checksums |
05c12e34de145a977cace099423fbbb5410d2c2de550fcc920eb609e66f68644
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 18, 2026.
Transparency logRelease files / cds_interpret-0.2.0-py3-none-any.whl
| Download URL | cds_interpret-0.2.0-py3-none-any.whl |
|---|---|
| Size | 290.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
ef8330242ca37dbd552f97ad620dd6d894fcda911a592fb9e49429be754cabbc
|
|
BLAKE2b-256 checksum How to use checksums |
56967acfecd206bf5009b7db68d6249d8ee93adc7b935d7a8f92c6c1de05a8d2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 18, 2026.
Transparency logSecurity for cds-interpret 0.2.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for cds_interpret-0.2.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 18, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.