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.2.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.2-py3-none-any.whl (151.8 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: nixwrap_rl-0.1.2.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.2.tar.gz
Algorithm Hash digest
SHA256 73a35429a230b0377d03389de88849793bc1d1e817e9bc9f5c156b88d40e7009
MD5 5fb53ee9e1047d2f98214c4ced5aaaa2
BLAKE2b-256 7d594377f6ca770fb8db71fdc29e57d6626f589cdb5b3b28aaf3b5b62acd7629

See more details on using hashes here.

File details

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

File metadata

  • Download URL: nixwrap_rl-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 151.8 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.2-py3-none-any.whl
Algorithm Hash digest
SHA256 6bc42f12ebc7222ef2909ab68e2da16bf0ad2fef424ce77963aaf3ba197084e7
MD5 2efc561258ef49f3c4f503f4c144a82a
BLAKE2b-256 3e7b46c422dddcf87c4a6ed249607000bcb3ba47d0ad8160683258d31a131f44

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