# Rudder SDK for Unity LiveOps SDK for Unity: device auth, player profile, remote config, stores, inventory, leaderboards, battle pass, quests, storage and scenarios. The package wraps `Rudder.Core.dll` (the .NET SDK) with Unity adapters: `UnityWebRequest` transport and `PlayerPrefs` token storage. Coding agents: read `AGENTS.md` before integrating this package into a game. ## Installation The package is published to the Rudder scoped registry. Add the registry to your project's `Packages/manifest.json`: ```json { "scopedRegistries": [ { "name": "Rudder", "url": "https://hub.rudder.build/api/packages/rudder/npm/", "scopes": ["rudder"] } ], "dependencies": { "rudder.sdk": "0.4.0", "com.unity.nuget.newtonsoft-json": "3.2.2" } } ``` `com.unity.nuget.newtonsoft-json` is required — `Rudder.Core` serializes with Newtonsoft.Json and the package does not bundle the DLL. ## Quickstart Create a configuration asset via `Assets > Create > Rudder > Configuration`, set `ProjectKey`, add the `Rudder` component to a startup scene, assign the asset, then: ```csharp using RudderSdk.Unity; var client = Rudder.Initialize(); await client.Auth.LoginWithDeviceAsync("global", "en", nickname: "Player"); var configs = await client.RemoteConfig.LoadAsync(); var stores = await client.Stores.ListAsync(); ``` All features hang off the client: `Auth`, `Player`, `BattlePass`, `Quests`, `Stores`, `Inventory`, `Leaderboards`, `RemoteConfig`, `Scenario`, `Effects`, `Storage`. ```csharp client.Effects.OnStoreOffer += effect => { /* show offer UI */ }; await client.Scenario.TriggerAsync("player_login"); var purchase = await client.Stores.PurchaseAsync("cozy-camp-shop", "moonberry-boost"); var leaderboard = client.Leaderboards.FindBySlug("cozy-collector-score"); await leaderboard.SubmitAsync(score); var top = await leaderboard.ListAsync(10); ``` ## Lifecycle - `Rudder.Initialize()` — synchronous. Reads the configuration on the scene component and returns `RudderClient`. Idempotent. Throws if the component or configuration is missing. - `client.Auth.LoginWithDeviceAsync` — device login. Use this as the first awaited call. Pending scenario effects are fetched after sign-in via the per-frame `Update` heartbeat. - `Rudder.State` — `NotInitialized` / `Initializing` / `Ready` / `Failed`. - `Rudder.LastError` — the initialization error when `State` is `Failed`. - `Rudder.Client` — the initialized `RudderClient`; throws until `Initialize`. - HTTP timeout defaults to 10 seconds, configurable per `RudderConfiguration.TimeoutSeconds`. Errors surface as `RudderApiException` subclasses from `RudderSdk.Core`: `RudderAuthException` (401, session over), `RudderNotFoundException` (404), `RudderRateLimitException` (429) and `RudderNetworkException` (no response). ## Samples Import **Feature Samples** from the Package Manager (select the Rudder SDK package, then Samples). Each scene is one API: | Scene | SDK calls | | --- | --- | | Authentication | `Initialize`, `Auth.LoginWithDeviceAsync`, `Player.GetProfileAsync`, `Auth.Logout` | | Remote Config | `RemoteConfig.LoadAsync`, `Get(key, fallback)` | | Storage | `Storage.GetAsync`, `SaveAsync`, `DeleteAsync` | | Store & Inventory | `Stores.ListAsync`, `PurchaseAsync`, `Inventory.GetAsync` | | Leaderboards | `Leaderboards.FindBySlug`, `SubmitAsync`, `ListAsync` | | Scenarios | `Scenario.TriggerAsync`, `Effects.OnNotification`, `Effects.OnStoreOffer`, … | Assign a `RudderConfiguration` on the Sample object if the field is empty, then press Play. In this repo the scenes are already visible at `Assets/Samples/Rudder SDK/`.