Skip to main content

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.

Installation

From github

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

From PyPi

pip install nixwrap-rl

# With optional extras:
pip install nixwrap-rl[tracker]   # tracker.gg
pip install nixwrap-rl[gui]       # overlay / GUI
pip install nixwrap-rl[input]     # keyboard + controller
pip install nixwrap-rl[all]       # 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

Contributing

Do you want to make this library even better? Contributions are highly encouraged and appreciated.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

nixwrap_rl-0.1.1.tar.gz (143.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

nixwrap_rl-0.1.1-py3-none-any.whl (151.7 kB view details)

Uploaded Python 3

File details

Details for the file nixwrap_rl-0.1.1.tar.gz.

File metadata

  • Download URL: nixwrap_rl-0.1.1.tar.gz
  • Upload date:
  • Size: 143.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.9

File hashes

Hashes for nixwrap_rl-0.1.1.tar.gz
Algorithm Hash digest
SHA256 d8bab2f4a61bc38515014b4ca4d9cf75d655c192711832094e75d295a9679c1d
MD5 f4582d96098cb50b5a3dceec431184ed
BLAKE2b-256 ad4c017702414b7632a441cb03ae93240e44e4abcdc7f6b4a0bef0e8df48aead

See more details on using hashes here.

File details

Details for the file nixwrap_rl-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: nixwrap_rl-0.1.1-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

Hashes for nixwrap_rl-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 12e4e44bbdaf1ca7f64570263ccd4b39c8bb49bddd80d46cc1b940d37b80c6db
MD5 d3eb0bb2bf41e3dd60f006d905edd1f2
BLAKE2b-256 a9c40cc4a1ef328b5a25cea0aa287c85731ac26f067c2de37bd1fffefd370f7d

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page