# CoolAPI — Unity SDK for Cool GameX

CoolAPI is the official Unity SDK for the [Cool GameX](../README.md) platform.
Drop it into your game to add **authentication**, **achievements**, **playtime
tracking**, **player stats**, and **DLC** in a few lines of code.

**Free for everyone.** CoolAPI is **MIT-licensed** — use it in any Unity game,
commercial or not, no strings attached. All it needs is a Cool GameX backend URL
(your own, or a shared one) and your game's slug.

✅ No external dependencies · ✅ async/await · ✅ Unity 2021.3+ · ✅ Windows/macOS/Linux

> 🎓 **New here? Start with the [step-by-step TUTORIAL.md](TUTORIAL.md)** — it
> takes you from creating a game in the Admin panel to unlocking your first
> achievement from Unity in about 10 minutes.
>
> 📜 Version history: see the [CHANGELOG](CHANGELOG.md). Current: **v1.4.0**.

## Status flags (know if you're connected)

```csharp
CoolAPI.IsInitialized    // Initialize() has run
CoolAPI.IsConnected      // the server was reachable on the last call
CoolAPI.IsAuthenticated  // a player is logged in

await CoolAPI.CheckConnection();   // ping the server now -> updates IsConnected
Debug.Log(CoolAPI.StatusLine());   // "initialized=true connected=true authenticated=false"
```

---

## Install

### Option A — One-click `.unitypackage` (recommended)
1. Download **[CoolGameX-SDK.unitypackage](https://coolgamex.com/sdk)** from
   the Get SDK page (or the **Admin → SDK** tab in the launcher).
2. In Unity: **Assets → Import Package → Custom Package…**, pick the file, click
   **Import**. That's it — `Assets/CoolGameX/` appears in your project.

### Option B — Zip
Download `CoolGameX-SDK.zip`, unzip, and drop the `CoolGameX/` folder anywhere
under your project's `Assets/`.

### Option C — Package Manager (from disk)
Copy the `sdk/` folder into your project and, in **Window → Package Manager**,
choose **+ → Add package from disk…** and select `sdk/package.json`.

Requires **Unity 2021.3+** (uses async/await + UnityWebRequest). No external
dependencies.

---

## Quick start — the easy way (no code)

1. Create an empty GameObject, add the **Cool GameX Manager** component
   (Add Component → *Cool GameX → Cool GameX Manager*).
2. Set **Game Slug** and **Server URL**. Done — it initializes, logs in with the
   launcher token, and tracks playtime automatically.
3. Unlock from anywhere:

```csharp
using CoolGameX;

CoolGameXManager.Unlock("speed_runner");

// React to unlocks (e.g. your own in-game banner / SFX):
CoolGameXManager.AchievementUnlocked += slug => Debug.Log($"Unlocked {slug}!");
```

## Quick start — manual (full control)

```csharp
using CoolGameX;
using UnityEngine;

public class GameBootstrap : MonoBehaviour
{
    async void Start()
    {
        await CoolAPI.Initialize("your-game-slug", "https://your-server.com");

        if (CoolAPI.IsAuthenticated)
            await CoolAPI.Auth.LoginWithToken(CoolAPI.Token);

        CoolAPI.Achievements.OnAchievementUnlocked += slug => Debug.Log($"🏆 {slug}");
        CoolAPI.Playtime.StartSession();
    }

    public async void OnSpeedrunFinished()
    {
        // Detailed result tells you if it was newly unlocked.
        UnlockResult r = await CoolAPI.Achievements.UnlockDetailed("speed_runner");
        if (r.NewlyUnlocked) Debug.Log("First time!");
    }

    async void OnApplicationQuit() => await CoolAPI.Playtime.EndSession();
}
```

## Player Stats

Persist per-player numbers (kills, levels cleared, coins, a high score). Stats
live on the backend and follow the player across machines.

```csharp
// fire-and-forget via the component:
CoolGameXManager.AddStat("enemies_killed");      // +1
CoolGameXManager.SetStat("high_score", 9001);

// or await the API directly:
int total = await CoolAPI.Stats.Add("enemies_killed", 5); // returns new total
await CoolAPI.Stats.Set("high_score", 9001);
int kills = await CoolAPI.Stats.Get("enemies_killed");
```

## DLC

Players acquire DLC by redeeming a code or buying it in the launcher. Your game
just checks ownership:

```csharp
if (await CoolAPI.DLC.Owns("haunted-expansion"))
    UnlockExpansionContent();

// Or fetch all owned DLC slugs for this game:
string[] owned = await CoolAPI.DLC.ListOwned();
```

## What's new in 1.4
- **Player Stats** are real: `Stats.Set/Add/Get/GetAllJson` (+ `CoolGameXManager.SetStat/AddStat`).
- **Typed achievements:** `Achievements.GetDefinitions()` → `AchievementInfo[]`.
- **One-click `.unitypackage`** install from `coolgamex.com/sdk`.

## What's new in 1.3
- **Connection status:** `CoolAPI.IsConnected` + `CoolAPI.CheckConnection()` +
  `CoolAPI.StatusLine()`.
- Free-to-use description + this changelog.

## What's new in 1.2
- **`CoolAPI.DLC`** — `Owns(slug)` / `ListOwned()` for add-on ownership.
- **Request timeouts** (`Net.TimeoutSeconds`, default 20s) so calls don't hang.

## What's new in 1.1
- **`CoolGameXManager`** drop-in component — zero-code setup + playtime heartbeat.
- **`Achievements.OnAchievementUnlocked`** event (fires only on first unlock).
- **`UnlockDetailed()`** returns `{ Success, NewlyUnlocked, Error }`.
- **`CoolAPI.LastError` / `LastStatus`** for easier debugging.

### Roadmap (later phases)
- **Leaderboards** built on top of the Stats API.
- **Cloud saves**.

> **Tip:** `OnApplicationQuit` may not give async calls time to finish on every
> platform. For long sessions, also call `CoolAPI.Playtime.ReportMinutes(n)`
> periodically (e.g. every 5 minutes) so progress isn't lost.

---

## How auth works

The Cool GameX launcher starts your game's executable with the player's Supabase
JWT on the command line:

```
YourGame.exe --cgx-token=<JWT>
```

`CoolAPI.Initialize()` reads that argument automatically and stores it in
`CoolAPI.Token`. If your game is launched **outside** the launcher, `Token` will
be null and `CoolAPI.IsAuthenticated` will be false — guard your platform calls
accordingly.

---

## API reference

### `CoolAPI`
| Member | Description |
| --- | --- |
| `Task Initialize(string gameSlug, string serverUrl)` | Initialize the SDK. Reads the launcher token. |
| `string GameSlug` | The slug you initialized with. |
| `string ServerUrl` | Backend base URL. |
| `string Token` | Current player JWT (or null). |
| `bool IsInitialized` | Whether `Initialize` has run. |
| `bool IsAuthenticated` | Whether a token is present. |
| `string ReadLaunchToken()` | Reads `--cgx-token=` from the command line. |

### `CoolAPI.Auth`
| Member | Description |
| --- | --- |
| `Task<bool> LoginWithToken(string token)` | Validate & store a JWT. |
| `void Logout()` | Clear the stored token. |

### `CoolAPI.Achievements`
| Member | Description |
| --- | --- |
| `Task<bool> Unlock(string achievementSlug)` | Unlock an achievement (idempotent). |
| `Task<UnlockResult> UnlockDetailed(string slug)` | Unlock + know if it was newly unlocked. |
| `event Action<string> OnAchievementUnlocked` | Fires on first unlock (slug). |
| `Task<AchievementInfo[]> GetDefinitions()` | Typed list of this game's achievements. |
| `Task<string> List()` | Raw JSON of the game detail payload. |

### `CoolAPI.Playtime`
| Member | Description |
| --- | --- |
| `void StartSession()` | Begin timing. |
| `Task<int> EndSession()` | Stop timing and report elapsed minutes. |
| `Task<bool> ReportMinutes(int minutes)` | Manually report minutes (heartbeat). |

### `CoolAPI.Stats`
| Member | Description |
| --- | --- |
| `Task<bool> Set(string key, int value)` | Set an integer stat to a value. |
| `Task<int> Add(string key, int amount = 1)` | Increment; returns the new total. |
| `Task<int> Get(string key)` | Read a stat (0 if unset). |
| `Task<string> GetAllJson()` | Raw JSON of all stats for this game. |

---

## Backend endpoints used

| Method | Path | Auth |
| --- | --- | --- |
| `POST` | `/api/achievements/unlock` | Bearer JWT |
| `POST` | `/api/playtime/update` | Bearer JWT |
| `POST` | `/api/stats/set` · `/api/stats/add` | Bearer JWT |
| `GET`  | `/api/stats` | Bearer JWT |
| `GET`  | `/api/games/:slug` | none |
| `GET`  | `/api/library` | Bearer JWT (used to validate login) |

All achievement/playtime calls send `Authorization: Bearer <JWT>`.

---

## License

MIT
