A cross-platform OBS Studio plugin that displays real-time Xbox Live achievement progress and gamer score for the currently signed-in Xbox user.
- Xbox Live Authentication: Secure OAuth 2.0 authentication flow with Microsoft accounts
- Real-time Achievement Tracking: Monitor achievement unlocks as they happen
- Profile Display: Show gamertag, gamerpic, and gamerscore
- Game Information: Display currently active game cover art
- Achievement Details: Show achievement name, description, icon, and count
- Customizable Text Sources: Configurable font, color, and size for all text-based sources
- Customizable Image Sources: Adjustable dimensions for image-based sources
- Automatic Updates: Real-time synchronization with Xbox Live services
- Cross-platform: Supports Windows, macOS, and Linux
- Download the latest release for your platform from the Releases page
- Extract the archive to your OBS Studio plugins directory:
- Windows:
%ProgramFiles%\obs-studio\obs-plugins\64bit\ - macOS:
~/Library/Application Support/obs-studio/plugins/ - Linux:
~/.config/obs-studio/plugins/
- Windows:
- Restart OBS Studio
- Sign in to Xbox Live:
- Open OBS Studio
- Add a new Source → Xbox Account
- Click the Sign in with Xbox Live button in the source properties
- A browser window will open; sign in with your Microsoft account
- Grant the requested permissions
- The plugin will automatically retrieve and cache your XSTS token
Once configured, the plugin provides the following OBS sources:
- Xbox Account: Authentication source for signing into Xbox Live. Add this first to authenticate with your Microsoft account.
- Xbox Gamertag: Displays your Xbox gamertag as customizable text.
- Xbox Gamerpic: Shows your Xbox profile picture (avatar).
- Xbox Gamerscore: Displays your total gamerscore as customizable text.
- Xbox Game Cover: Shows the cover art/box art of the currently active game on your Xbox console.
- Xbox Achievement (Name): Displays the name and gamerscore value of the current achievement (e.g., "50G - Master Explorer").
- Xbox Achievement (Description): Shows the description text of the current achievement.
- Xbox Achievement (Icon): Displays the achievement icon/badge image.
- Xbox Achievements Count: Shows the total number of achievements for the current game (e.g., "50 achievements").
The plugin automatically subscribes to Xbox Live for real-time updates:
- Currently active game changes
- Achievement unlock events
- Profile information updates
achievements-tracker-plugin/
├── src/
│ ├── main.c # Plugin entry point, module registration
│ ├── common/ # Shared data types and utilities
│ │ ├── achievement.c/h # Achievement type (copy/free/count)
│ │ ├── achievement_progress.c/h # Achievement progress tracking
│ │ ├── device.h # Device identity (UUID, keys)
│ │ ├── game.c/h # Game descriptor (id, title)
│ │ ├── gamerscore.c/h # Gamerscore container & computation
│ │ ├── memory.h # Memory allocation helpers (FREE, free_memory)
│ │ ├── token.c/h # Auth token with expiration
│ │ ├── types.h # Umbrella header, macros, platform helpers
│ │ ├── unlocked_achievement.c/h # Unlocked achievement tracking
│ │ ├── xbox_identity.c/h # Xbox identity (gamertag, xuid, uhs, token)
│ │ └── xbox_session.c/h # Xbox session state container
│ ├── crypto/
│ │ └── crypto.c/h # EC key generation, signing (Proof-of-Possession)
│ ├── diagnostics/
│ │ ├── log.c.in # Logging (CMake-configured)
│ │ └── log.h # Logging API
│ ├── drawing/
│ │ ├── color.c/h # Color handling utilities
│ │ ├── image.c/h # Image rendering helpers
│ │ └── text.c/h # Text rendering helpers
│ ├── encoding/
│ │ └── base64.c/h # Base64 URL-safe encoding
│ ├── io/
│ │ └── state.c/h # Persistent state (tokens, device keys)
│ ├── net/
│ │ ├── browser/browser.c/h # Platform-specific browser launch
│ │ ├── http/http.c/h # libcurl HTTP GET/POST wrappers
│ │ └── json/json.c/h # JSON parsing helpers
│ ├── oauth/
│ │ ├── util.c/h # OAuth helpers (PKCE, code exchange)
│ │ └── xbox-live.c/h # Xbox Live OAuth & XSTS token flows
│ ├── sources/ # OBS source implementations
│ │ ├── common/ # Shared source utilities
│ │ │ ├── achievement_cycle.c/h # Achievement display rotation logic
│ │ │ ├── image_source.c/h # Common image source functionality
│ │ │ └── text_source.c/h # Common text source functionality
│ │ └── xbox/ # Xbox-specific sources
│ │ ├── account.c/h # Xbox Account source (authentication)
│ │ ├── achievement_description.c/h # Achievement description text source
│ │ ├── achievement_icon.c/h # Achievement icon image source
│ │ ├── achievement_name.c/h # Achievement name text source
│ │ ├── achievements_count.c/h # Achievements count text source
│ │ ├── game_cover.c/h # Xbox Game Cover image source
│ │ ├── gamerpic.c/h # Xbox Gamerpic image source
│ │ ├── gamerscore.c/h # Xbox Gamerscore text source
│ │ └── gamertag.c/h # Xbox Gamertag text source
│ ├── system/
│ │ └── font.c/h # System font discovery
│ ├── text/
│ │ ├── convert.c/h # Text conversion utilities
│ │ └── parsers.c/h # Text/response parsing utilities
│ ├── time/
│ │ └── time.c/h # ISO-8601 timestamp parsing
│ ├── util/
│ │ └── uuid.c/h # Cross-platform UUID generation
│ └── xbox/
│ ├── xbox_client.c/h # Xbox Live API client (profile, achievements)
│ ├── xbox_monitor.c/h # Real-time activity monitoring
│ └── xbox_session.c/h # Session management
├── test/
│ ├── test_convert.c # Text conversion tests
│ ├── test_crypto.c # Cryptographic signing tests
│ ├── test_encoder.c # Base64 encoding tests
│ ├── test_parsers.c # Text parser tests
│ ├── test_types.c # Common types tests
│ ├── test_xbox_session.c # Xbox session tests
│ ├── unity_config.h # Unity test framework config
│ └── stubs/ # Test stubs (bmem_stub.c, mocks, etc.)
├── cmake/ # Build configuration helpers
├── data/locale/ # Localization files
├── external/cjson/ # cJSON library (vendored)
└── CMakeLists.txt # Main build configuration
The plugin implements the Xbox Live authentication flow with Proof-of-Possession (PoP) signing:
- POST to
https://login.live.com/oauth20_connect.srfwith:client_id: Application client IDresponse_type:device_codescope:service::user.auth.xboxlive.com::MBI_SSL
- Receive
device_code,user_code,interval, andexpires_in - Open system browser to
https://login.live.com/oauth20_remoteconnect.srf?otc=<user_code> - User signs in and enters the displayed code
- Plugin polls
https://login.live.com/oauth20_token.srfat the specified interval until:- User completes authentication → receive Access Token and Refresh Token
- Or timeout expires
- Generate an EC P-256 key pair (device Proof-of-Possession key)
- POST to
https://device.auth.xboxlive.com/device/authenticatewith:- Device UUID and serial number (random, cached)
- Public key (JWK format) in
ProofKey signatureheader (request signed with private key)
- Receive Device Token (JWT) with expiration (
NotAfter)
- POST to
https://sisu.xboxlive.com/authorizewith:- Microsoft Access Token (as
AccessToken:t=<token>) - Device Token
- App ID (client ID)
- Public key (JWK) in
ProofKey signatureheader (request signed with private key)
- Microsoft Access Token (as
- Receive:
- Authorization Token (XSTS token at
AuthorizationToken.Token) - User identity:
gtg(gamertag),xid(Xbox User ID),uhs(User Hash) - Token expiration (
NotAfter)
- Authorization Token (XSTS token at
- All tokens are cached in
~/.config/obs-studio/plugin_config/achievements-tracker/state.json - Device keys are persisted (EC private key, PEM format)
- On startup:
- If valid User Token exists → use it
- Else if Refresh Token exists → exchange for new Access Token via token endpoint
- Else → start Device Code Flow from step 1
- Device Token is also cached and reused if still valid
- All Xbox Live API requests include the header:
Authorization: XBL3.0 x=<uhs>;<xsts_token> - Examples:
- Profile:
GET https://profile.xboxlive.com/users/xuid(<xuid>)/profile/settings?settings=Gamerscore - Achievements:
GET https://achievements.xboxlive.com/users/xuid(<xuid>)/achievements
- Profile:
- CMake 3.28 or later
- OBS Studio 30.0+ (headers + libraries)
- OpenSSL 3.x (for cryptographic operations)
- libcurl (for HTTP requests)
- FreeType 2.x (for text rendering)
- zlib (required by FreeType, usually available by default)
- libuuid (Linux/BSD only, for UUID generation)
- C compiler with C11 support
Note on zlib: zlib is required by FreeType for font compression support and is typically pre-installed on all platforms (macOS SDK, Windows via vcpkg/obs-deps, Linux system packages).
- Install dependencies via Homebrew:
brew install cmake openssl@3 curl freetype- Clone and configure:
git clone https://github.com/your-org/achievements-tracker-plugin.git
cd achievements-tracker-plugin
cmake --preset macos-dev- Build:
xcodebuild -configuration RelWithDebInfo -scheme achievements-tracker -parallelizeTargets -destination "generic/platform=macOS,name=Any Mac"Or maybe:
cmake --build build_macos_dev --config Debug- The plugin bundle will be at:
build_macos_dev/Debug/achievements-tracker.plugin- Copy to OBS plugins folder:
cp -r build_macos_dev/Debug/achievements-tracker.plugin \
~/Library/Application\ Support/obs-studio/plugins/For universal (arm64+x86_64) builds, you'll need a universal FreeType binary:
# Build universal FreeType (this will be done automatically in CI)
./scripts/build-universal-freetype.sh
# Then configure for universal build
cmake --preset macos-ciThe CI workflow automatically builds universal FreeType before building the plugin.
- Install dependencies via vcpkg:
vcpkg install openssl:x64-windows curl:x64-windows freetype:x64-windows- Configure and build:
cmake --preset windows-x64
cmake --build build_windows --config Release- Install dependencies:
sudo apt-get install cmake libssl-dev libcurl4-openssl-dev uuid-dev libfreetype6-dev- Configure and build:
cmake --preset linux-x64
cmake --build build_linux --config ReleaseThe project uses Unity as the unit testing framework.
For local development (single-arch, uses Homebrew OpenSSL):
cmake --preset macos-dev -DBUILD_TESTING=ON
cmake --build build_macos_dev --config Debug
ctest --test-dir build_macos_dev -C Debug --output-on-failureFor CI builds (universal binary, custom OpenSSL):
cmake --preset macos-ci -DBUILD_TESTING=ON
cmake --build build_macos --config RelWithDebInfo
ctest --test-dir build_macos -C RelWithDebInfo --output-on-failurecmake -S . -B build -DBUILD_TESTING=ON
cmake --build build --config Debug
ctest --test-dir build -C Debug --output-on-failure# Test Base64 encoding
cmake --build build_macos_dev --target test_encoder --config Debug
./build_macos_dev/Debug/test_encoder
# Test cryptographic signing
cmake --build build_macos_dev --target test_crypto --config Debug
./build_macos_dev/Debug/test_crypto
# Test ISO-8601 timestamp parsing
cmake --build build_macos_dev --target test_time --config Debug
./build_macos_dev/Debug/test_timeEnsure the plugin is build in Debug:
xcodebuild -configuration Debug -scheme achievements-tracker -parallelizeTargets -destination "generic/platform=macOS,name=Any Mac"Ensure the xcodeproj of the plugin has the option DWARF with dSYM file enabled:
Copy both the plugin and the dSYM in the Debug/OBS/Contents/PlugIns folder of OBS Studio:
Open obs-studio in Xcode and ensure Debug configuration is chosen for Profile:
https://learn.microsoft.com/en-us/gaming/gdk/docs/reference/live/rest/uri/gamerpic/atoc-reference-gamerpic https://deepwiki.com/microsoft/xbox-live-api/5-real-time-activity-system#resource-uri-format
Contributions are welcome! Please open an issue or submit a pull request.
For issues, questions, or feature requests, please visit the GitHub Issues page.