A fully native Windows desktop app (WinUI 3 / .NET 8 — no Electron, no Tauri, no BakkesMod) that reads live Rocket League data from the game's official Stats API, tracks your session (win/loss, streaks, totals), pulls career stats from ballchasing.com, lets you toggle each widget on/off, and exposes the data as an OBS overlay two ways: a local browser source and a native transparent always-on-top window.
Status: built and verified on Windows. Compiled with the .NET 8 SDK (0 errors), the app was launched and confirmed to run, and the overlay HTTP server was confirmed serving on
http://localhost:8777/. A one-click installer is included.
- Hero animations — scores bounce on every goal; the win-rate ring counts up smoothly.
- Richer session card — last-5 W/L strip, live play-time clock, best-streak and goal-differential chips.
- Players page — shows all players (private-match id bug fixed), sorted by score, your row highlighted, with ⚡ supersonic and 💥 demolished indicators and animated boost bars.
- Status InfoBar, theme selector (System/Dark/Light), window size/position memory, and a Test connection button.
- Overlay options — Glass / Minimal / Bold themes, a scale slider, accent choice, and a goal-explosion callout, all applied live.
- Resume session across restarts, plus JSON export alongside CSV.
The hero is built on the WinUI Composition layer — GPU visuals a web view can't touch:
- Boost energy field — ~46 radial-gradient sprite visuals stream upward in RL blue→orange, each driven by an infinite GPU keyframe animation (zero per-frame CPU). On a goal it fires an expanding burst in the scoring team's colour.
- Spring-physics score pops — scores bounce via
SpringVector3NaturalMotionAnimation(real damped-spring motion, not a canned curve). - Broadcast light sweep — a sheen glides across the hero on a loop.
- Goal flash — a white energy pulse across the scoreboard the instant a team scores.
The interface leans on WinUI 3 features a web view (Electron/Tauri) can't render:
- Mica Alt backdrop — the window material tints with your desktop wallpaper.
- Custom title bar (
ExtendsContentIntoTitleBar) with a brand badge and a pulsing live-connection pill. - NavigationView rail (Session / Players / History / Career / OBS Overlay / Settings) with pinned Live/Stop/Demo/Overlay controls.
- Hero scoreboard with team-colored gradient zones, oversized tabular scores, a real
ThemeShadow, and a determinate ProgressRing win-rate dial. - Composition transitions on page switches and live list add/reorder; animated boost bars per player.
- Dark theme tuned for streaming, with the Rocket League blue/orange accent language.
Double-click dist\RLStats-Setup.exe. It's a per-user installer — no administrator
rights — that copies the app to %LOCALAPPDATA%\Programs\RLStats, adds Start Menu + Desktop
shortcuts, and registers an entry in Add or remove programs (search "Rocket League Stats" to
uninstall). The app is self-contained: the .NET 8 and Windows App SDK runtimes are bundled, so it
runs even on a machine with neither installed.
Prefer portable? The folder dist\RLStats\ is the full app — just run RLStats.exe.
Try it with no game running: click Demo in the top bar to feed synthetic matches through the whole pipeline so you can lay out the dashboard and OBS overlay offline.
The only thing that made this look Electron-shaped is the OBS overlay. This app stays 100% native:
- Live data: Rocket League's official Stats API opens a local raw TCP socket (
127.0.0.1:49123); WinUI consumes it withSystem.Net.Sockets.TcpClient. Despite the docs' "WebSocket" wording the feed is a plain TCP stream of concatenated JSON objects (no delimiter), and each envelope'sDatais a JSON-encoded string parsed a second time. No plugins. - Browser-source overlay: the app hosts a tiny local web server (
System.Net.HttpListener) that serves one static HTML page and pushes live data to it over a WebSocket. OBS adds it as a Browser Source. The app is still native C#; only the overlay surface OBS renders is HTML, which is unavoidable because OBS browser sources are HTML by definition. - Native window overlay: a frameless, click-through, always-on-top WinUI window (styled via Win32
WS_EX_LAYERED | WS_EX_TRANSPARENT) you capture with OBS Window Capture if you'd rather not use a browser source.
Docs: https://www.rocketleague.com/developer/stats-api
The game broadcasts JSON over a local raw TCP socket once you enable it. Every message is
{ "Event": "...", "Data": { ... } }. The app handles:
| Message | Used for |
|---|---|
UpdateState (tick) |
Live scoreboard, clock, per-player goals/assists/saves/shots/demos/boost, ball speed |
GoalScored |
Event feed / overlay goal callouts |
StatfeedEvent |
Event feed (saves, demos, etc.) |
MatchEnded (WinnerTeamNum) |
Win/loss + streak tracking |
MatchCreated / MatchInitialized |
New-match detection |
- Close Rocket League.
- Edit
…\rocketleague\TAGame\Config\DefaultStatsAPI.ini(Steam example:…\steamapps\common\rocketleague\TAGame\Config\DefaultStatsAPI.ini). - Set a send rate above zero, e.g.:
PacketSendRate=60 Port=49123
PacketSendRatemust be> 0to open the socket (max 120). DefaultPortis49123. - Start Rocket League. The socket is now live whenever you're in a match.
Win/loss needs to know which team is "you." Put your in-game display name (or platform id like
Steam|123|0) on the Settings tab so the tracker can match you in the player list.
Prerequisites
- Windows 10 (1809+) or Windows 11
- Visual Studio 2022 with the ".NET Desktop Development" workload and the Windows App SDK component (or the standalone Windows App SDK 1.5)
- .NET 8 SDK
Steps
- Open
RLStatsTracker.slnin Visual Studio 2022. - Set the build platform to x64 (top toolbar).
- Press F5. The project is configured unpackaged (
WindowsPackageType=None), so it runs as a plain.exe— no MSIX signing needed.
Command line alternative (helper scripts are included in the repo root):
build.cmd :: dotnet build, Debug, x64, self-contained → src\RLStats\bin\...
publish.cmd :: dotnet publish, Release, win-x64, self-contained → dist\RLStats\These call the .NET 8 SDK staged at .tools\dotnet\ (installed per-user during the build). A
local nuget.config points restore at nuget.org. To rebuild the installer after publish.cmd,
re-zip dist\RLStats into installer\payload.zip and run IExpress on a .sed that lists the
two scripts + the zip (see git history for the exact SED used).
- Session tab — live scoreboard/clock in the header, session W/L, streak, win rate, running totals, the last event, and a live per-player table (goals/assists/saves/shots/boost/score for everyone in the match). "Reset session" zeroes it for a fresh grind.
- Widgets tab — toggle each element (scoreboard, clock, record, goals, assists, saves, shots, demos, boost, ball speed, career). Toggles apply instantly to both the dashboard and any live OBS overlay.
- History tab — every completed match this session (result, score, your stats, arena) with Export session to CSV (saved to Documents).
- Career tab — aggregates your recent ballchasing.com replays into W/L + core stats. Needs an API key (Settings).
- OBS Overlay tab — start the local server and copy the Browser Source URL. The browser overlay shows live scoreboard, session record, stat chips (incl. your boost + ball speed), and goal/demo callout banners.
- Settings tab — your name/platform id, Stats API port, overlay port, and ballchasing API key.
- Top bar — Start Live / Stop, Demo (offline simulator), and Overlay Window (native transparent overlay).
- On the OBS Overlay tab, click Start overlay server.
- In OBS: Sources → + → Browser.
- URL: the one shown on the tab (default
http://localhost:8777/). Width1920, Height1080. - The overlay has a transparent background and updates live; widgets appear/disappear as you toggle them.
- Click Overlay Window (top-right of the app). A frameless, click-through, always-on-top window appears.
- In OBS: Sources → + → Window Capture and pick "RL Overlay".
- Log in at https://ballchasing.com, open https://ballchasing.com/upload, and generate an API key.
- Paste it into Settings → ballchasing.com API key, set your player name, Save, then Load career stats.
RLStatsTracker.sln
src/RLStats/
App.xaml(.cs) Composition root (AppServices wires the singletons together)
MainWindow.xaml(.cs) Dashboard: status bar + Session/Widgets/Career/OBS/Settings tabs
Views/OverlayWindow.xaml(.cs) Native transparent click-through overlay window
Models/StatsModels.cs Snapshot/session/career data types
Services/
StatsApiClient.cs Official Stats API TCP client (brace-framed JSON) + event parsing
SessionTracker.cs Win/loss, streaks, session totals
BallchasingClient.cs Career stats via ballchasing.com REST
OverlayServer.cs Local HTTP + WebSocket server for the OBS browser source
SettingsService.cs Persisted settings + per-widget toggles
ViewModels/MainViewModel.cs MVVM glue (CommunityToolkit.Mvvm)
Assets/overlay/overlay.html The OBS browser-source overlay page
- The Stats API exposes most per-player detail (boost/speed/positions) only when spectating or for players on your team; in your own ranked games you'll reliably get your own data plus scoreboard/clock for everyone.
- Career W/L from ballchasing is inferred per replay from team goal totals; private/unprocessed replays may be skipped.
- Settings live in
%LOCALAPPDATA%\RLStats\settings.json. - The native overlay window uses layered-window styling for click-through; for the cleanest transparent key in OBS, the browser source is recommended.