Unified SDK for Rocket League save file data extraction, Stats API WebSocket client, tracker.gg stats, process detection, input (keyboard/controller), and GUI overlay toolkit.
Project description
Nixwrap
Unified Python SDK for Rocket League: save file data extraction, Stats API WebSocket client, tracker.gg stats, process detection, keyboard/controller input, and a reusable GUI/overlay toolkit.
Built because EAC made traditional plugin development for online matches harder. Intended for streamers, tool developers, and anyone who wants RL data in Python.
pip install git+https://github.com/nixvio64/nixwrap
# With optional extras:
pip install "nixwrap[tracker] @ git+https://github.com/nixvio64/nixwrap" # tracker.gg
pip install "nixwrap[gui] @ git+https://github.com/nixvio64/nixwrap" # overlay / GUI
pip install "nixwrap[input] @ git+https://github.com/nixvio64/nixwrap" # keyboard + controller
pip install "nixwrap[all] @ git+https://github.com/nixvio64/nixwrap" # everything
Modules
| Module | Purpose | Requires |
|---|---|---|
nixwrap.save_file |
Decrypt + extract data from .save files |
pycryptodome |
nixwrap.process |
Detect running RL (Steam vs Epic) | psutil |
nixwrap.stats |
Live Stats API WebSocket events | - |
nixwrap.tracker |
tracker.gg player rank/stats | curl-cffi (optional) |
nixwrap.input |
Keyboard, Xbox, DualSense hotkey detection | dualsense-controller, keyboard (optional) |
nixwrap.gui |
Overlay/GUI toolkit | PySide6 (optional) |
nixwrap.utils |
Constants and helpers | - |
Quick Start
0. Edit your DefaultStatsAPI.ini
Found at <RL Install Dir>\TAGame\Config\DefaultStatsAPI.ini set PacketSendRate value to something like 20 (1-120).
1. Save File Data Extraction
from nixwrap.save_file import load, find_save_file
# Auto-find the active save file
path = find_save_file()
save = load(path)
# Camera
print(save.camera.fov) # 110.0
print(save.camera.stiffness) # 0.55
# Controls (keyboard + gamepad)
print(save.controls.jump) # "SpaceBar"
print(save.gamepad_bindings.boost) # "XboxTypeS_RightShoulder"
# Raw bindings for custom inspection
for b in save.gamepad_bindings.raw_bindings:
print(f" {b['Action']} -> {b['Key']}")
# Stats
print(save.stats.wins) # 1234
print(save.xp.level) # 27
print(save.xp.total_xp) # 348223
# Skill data per playlist
for pid, skill in save.skills.items():
print(f"Playlist {pid}: matches={skill.matches_played}, tier={skill.tier}")
# Inventory
for item in save.inventory:
print(f"Product {item.product_id} (series {item.series_id})")
# Settings
print(save.video.res_width, save.video.res_height)
print(save.gameplay.controller_deadzone)
print(save.sound.master_volume)
# Quick chats, loadout sets, season, achievements, etc.
print(len(save.quick_chats), "quick chat bindings")
print(len(save.loadout_sets), "loadout presets")
2. Process Detection
from nixwrap.process import find_rocket_league, is_rocket_league_focused
rl = find_rocket_league()
if rl:
print(f"PID: {rl.pid}")
print(f"Platform: {rl.platform.value}") # steam or epic
print(f"Root dir: {rl.root_dir}")
print(f"Save path: {rl.save_data_path}")
if is_rocket_league_focused():
print("RL window has focus")
3. Input Detection (Keyboard + Controller)
from nixwrap.input import (
is_hotkey_pressed, is_key_pressed,
get_xinput_state, XINPUT_A,
setup_dualsense, start_dualsense_monitor,
get_button_display,
)
# Keyboard
if is_key_pressed("tab"):
print("Tab is held")
# XInput (Xbox / DS4 via DS4Windows)
state = get_xinput_state()
if state and state.is_pressed(XINPUT_A):
print("A button pressed")
# DualSense (PS5)
controller = setup_dualsense() # auto-finds bundled hidapi.dll
start_dualsense_monitor() # background auto-reconnect
# Unified hotkey check (InGameRank-compatible config format)
config = {"is_controller": True, "controller_type": "xinput",
"controller_button": XINPUT_A}
if is_hotkey_pressed(config):
print("Hotkey held!")
# Button display names
print(get_button_display("xinput", XINPUT_A)) # "A"
print(get_button_display("dualsense", 0)) # "Cross"
4. Stats API (Live Events)
from nixwrap.stats import StatsClient
client = StatsClient()
# Callback mode
client.on("GoalScored", lambda evt: print(f"GOAL! {evt.scorer.name}"))
client.on("StatfeedEvent", lambda evt: print(f"{evt.main_target.name}: {evt.stat_type}"))
client.on_event(lambda evt: print(f"[{evt.event_type}]"))
with client:
import time
time.sleep(300) # listen for 5 minutes
Async mode:
import asyncio
from nixwrap.stats import StatsClient
async def main():
client = StatsClient()
client.start()
async for event in client.events():
print(event.event_type)
if event.event_type == "GoalScored":
print(f" {event.scorer.name} scored!")
asyncio.run(main())
5. Tracker API (Player Ranks)
from nixwrap.tracker import TrackerClient
client = TrackerClient() # random browser fingerprint per request
stats = client.fetch("Steam|123456789|0", "PlayerName")
if stats.error:
print(f"Error: {stats.error}")
else:
print(f"Last updated: {stats.last_updated}")
print(f"Lifetime: {stats.lifetime.wins} wins, {stats.lifetime.goals} goals")
for pid, rank in stats.ranks.items():
print(f" {rank.playlist_name}: {rank.tier_name} {rank.division_name} "
f"({rank.mmr} MMR, #{rank.rank_percentile}%)")
if rank.win_streak:
direction = "^" if rank.win_streak_type == "win" else "v"
print(f" Streak: {direction}{rank.win_streak}")
Results are cached for 5 minutes (tracker.gg update interval).
6. GUI / Overlay
from PySide6.QtWidgets import QApplication
from nixwrap.gui import (
create_overlay, WindowConfig, WindowType,
Painter, Color, THEME_DARK, FadeAnimation,
)
class MyOverlay:
def __init__(self):
self.win = create_overlay(600, 200, corner_radius=12, opacity=0.95)
self.win._paint = self._paint
self.win.snap_to_bottom_center(margin=20)
def _paint(self, painter_q):
p = Painter(painter_q)
p.fill_rect(0, 0, 600, 200,
THEME_DARK.background.with_alpha(216), radius=12)
p.stroke_rect(0, 0, 599, 199,
THEME_DARK.divider, width=1, radius=12)
p.draw_text("Hello Rocket League!", 20, 40,
color=THEME_DARK.text_primary)
app = QApplication([])
overlay = MyOverlay()
app.exec()
Optional Dependencies
| Extra | Packages | What you get |
|---|---|---|
[tracker] |
curl-cffi |
better tracker.gg support |
[gui] |
PySide6 |
Overlay windows, painter, colors, fonts, animations |
[input] |
dualsense-controller, keyboard, bundled hidapi.dll |
Xbox (XInput), PS5 DualSense, keyboard hotkey detection |
[all] |
all of the above | Everything |
Requirements
- Python >= 3.10
- pycryptodome >= 3.18 (save file AES)
- psutil >= 5.9 (process detection)
Acknowledgements
- RocketRP: AES key and binary format research
- tracker.gg: player stats API
- Rocket League Stats API: Psyonix/Epic
Contributing
Do you want to make this library even better? Contributions are highly encouraged and appreciated.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file nixwrap_rl-0.1.0.tar.gz.
File metadata
- Download URL: nixwrap_rl-0.1.0.tar.gz
- Upload date:
- Size: 143.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7632fd327605cab63d7b84fe1b9b0c411a52e88844c65b74240135e7f6a98a50
|
|
| MD5 |
6692e2de6eee1edacb8dcd6ea2eeea8c
|
|
| BLAKE2b-256 |
fa71d5d20aeda2cc66421052e22d7e10cf7bdeba002aa39e5e93a22cf2fb392c
|
File details
Details for the file nixwrap_rl-0.1.0-py3-none-any.whl.
File metadata
- Download URL: nixwrap_rl-0.1.0-py3-none-any.whl
- Upload date:
- Size: 151.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f4087a877930a8a4e67142a81197acddeb9d84fe075fd6892eb4a5fa0abc8990
|
|
| MD5 |
37bae9feffe6446cbff5f38a11ae6e9f
|
|
| BLAKE2b-256 |
109ab4002c6805a4ccf6401372662b52653a72affdb64dc13d01775dd0475c80
|