# LiveOps Unity Cozy Collector Demo

This Unity project is a playable port of the Cozy Collector web demo (`liveops-phaser-demo`). It uses the same arcade loop — move around the camp, collect spawning snacks before the round timer runs out — to show how a game can use LiveOps services without shipping a client update.

The demo is assembled like a regular Unity game: the scene, world, and UI live in baked assets (scene, prefabs, ScriptableObjects, imported sprites), and runtime scripts only contain logic wired through the inspector. All assets are generated by Editor bake scripts under `Tools > LiveOps`.

## Demonstrated Services

| Service | Demo use |
| --- | --- |
| Authorization | Device login with the configured project key. |
| Player | Loads player profile and wallets after login; session card shows nickname, region, wallets. |
| Remote Config | Controls round duration, player speed, spawn interval, collectible score; live updates highlight changed keys. |
| Storage | Saves best score and last round state (`cozy_fantasy_save` / `main`). |
| Stores | Shop modal lists the `cozy-camp-shop` catalog; purchases debit wallets. |
| Inventory | Backpack modal lists collected items via `Rudder.Client.Inventory`. |
| Leaderboards | Submits round score to `cozy-collector-score` and shows the top entries in the round-result modal. |
| Scenarios | Sends `player_login` after login and `demo_round_finished` after a round; scenario offers show a Buy/Decline modal, `remote_config_override` applies live. |

## Requirements

- Unity `6000.5.6f1`.
- A Rudder project key.
- Network access to `https://api.rudder.build`.

## Quick Start

1. Open this folder in Unity `6000.5.6f1`.
2. Copy `Assets/LiveOpsLocal.asset.example` to `Assets/LiveOpsLocal.asset`
   (the real asset is git-ignored because it holds your project key).
3. Set `ProjectKey` to your project key.
4. Confirm the endpoints:
   - `BaseUrl`: `https://api.rudder.build`
   - `RealtimeUrl`: `wss://realtime.rudder.build/api/realtime/ws`
5. Bake the demo assets (see below), then open `Assets/LiveOpsExamples/LiveOpsCozyCollector.unity`.
6. Press Play.

## Baking The Demo Assets

All demo assets are generated from the Unity menu:

```text
Tools > LiveOps > Bake Cozy Collector (All)
```

The bake scripts (`Assets/LiveOpsExamples/Editor/CozyCollectorBake.*.cs`) create or overwrite:

- `Assets/LiveOpsExamples/CozyCollectorSpriteLibrary.asset` — sprite references imported from `Sprites/`.
- `Assets/LiveOpsExamples/Prefabs/` — snack, score popup, collect burst, and UI row prefabs.
- `Assets/LiveOpsExamples/LiveOpsCozyCollector.unity` — camera, world, canvas, panels; assigns `Assets/LiveOpsLocal.asset` to `Rudder`; adds the scene to Build Settings.

The bake is idempotent: re-running it rewrites the same asset paths, so run it again after changing runtime scripts or sprites.

## Stage Data Checklist

The demo handles missing backend data with visible setup messages, but the strongest run needs these staging entities:

| Feature | Expected setup |
| --- | --- |
| Remote Config | Optional keys: `demo_round_seconds`, `demo_player_speed`, `demo_spawn_interval_ms`, `demo_collectible_score`. Defaults are used when keys are missing. |
| Stores | A store with slug `cozy-camp-shop` with at least one offer. |
| Leaderboards | A leaderboard with slug `cozy-collector-score`. |
| Scenarios | Events `player_login` and/or `demo_round_finished`; offer `moonberry-boost` for the scenario offer flow. |
| Storage | No setup required; the demo writes type `cozy_fantasy_save`, id `main`. |

## Project Structure

```text
Assets/LiveOpsExamples/
  LiveOpsCozyCollector.unity   (baked)
  CozyCollectorSpriteLibrary.asset (baked)
  Sprites/                     (imported from liveops-phaser-demo)
  Prefabs/                     (baked)
  Scripts/                     (runtime logic only)
    CozyCollectorController.cs
    GameWorld.cs, SnackSpawner.cs, Snack.cs, ScorePopupView.cs
    CozyCollectorConsts.cs, CozyCollectorSpriteLibrary.cs
    UI/                        (panels and row views)
  Sandbox/                     (legacy sandbox controllers)
  Editor/
    CozyCollectorBake.*.cs     (asset/prefab/scene/UI bake)
Assets/LiveOpsLocal.asset        (git-ignored; copy from LiveOpsLocal.asset.example)
Packages/rudder.sdk/             (Rudder SDK UPM package: Runtime/Sources + Runtime/Plugins/Rudder.Core.dll)
```

Runtime scripts never construct UI or scene objects; everything visual comes from the baked scene and prefabs, with references wired via `[SerializeField]`.

## Updating Core DLLs

Build the C# SDK from the sibling repository and copy the assembly into the
UPM package:

```sh
dotnet build ../liveops-csharp-sdk -c Release
cp ../liveops-csharp-sdk/bin/Release/netstandard2.1/Rudder.Core.dll \
  Packages/rudder.sdk/Runtime/Plugins/Rudder.Core.dll
```

`Rudder.Core` depends only on Newtonsoft.Json, which Unity provides through
the `com.unity.nuget.newtonsoft-json` package — no other DLLs are bundled.
