# CoolAPI Tutorial — Achievements & Playtime in 10 minutes

This walks you through wiring a Unity game into Cool GameX end-to-end: creating
the game and its achievements in the **Admin panel**, dropping the SDK into
Unity, and unlocking an achievement from gameplay.

> **The golden rule:** an achievement is identified by its **slug**. The slug you
> type in the Admin panel must match **exactly** the string you pass to
> `CoolAPI.Achievements.Unlock("…")` in code. Slugs are lowercase with
> underscores, e.g. `speed_runner`.

---

## The big picture

```
   Admin panel                Unity game (CoolAPI)            Backend
 ┌──────────────┐            ┌────────────────────┐        ┌──────────┐
 │ create game  │  slug      │ Unlock("first_win")│  JWT   │ /unlock  │
 │ add achiev.  │ ─────────▶ │ + game slug        │ ─────▶ │  saves   │
 └──────────────┘            └────────────────────┘        └──────────┘
        ▲                              ▲
        │ download_url + exe           │ launcher passes --cgx-token=<JWT>
        └──────────────── Cool GameX launcher ───────────────┘
```

The launcher (the desktop app) installs your zip, then launches your `.exe`
with the player's login token. CoolAPI reads that token and calls the backend.

---

## Step 1 — Create your game in the Admin panel

1. Open the desktop app and sign in with your **dev** account.
2. Click **Admin** in the sidebar → **+ New game**.
3. Fill in at least:
   - **Title** — e.g. `My Awesome Game` (the slug auto-fills to `my-awesome-game`)
   - **Cover image URL** — a 16:9 image (1920×1080 looks best)
   - **Download URL** — *(you'll set this in Step 5; leave blank for now)*
   - **Executable path** — the `.exe` name inside your zip, e.g. `MyAwesomeGame.exe`
4. Click **Save game**.

**Write down the slug** (e.g. `my-awesome-game`) — you'll need it in code.

---

## Step 2 — Add achievements

Still in the game editor (scroll down to **Achievements**), add each one:

| Field | Example | Notes |
| --- | --- | --- |
| **slug** | `first_win` | the id you'll use in code — lowercase_underscores |
| **Name** | `First Win` | shown to the player |
| **Description** | `Win your first match.` | |
| **Points** | `10` | |
| **Hidden** | off | hidden ones show as `???` until unlocked |

Click **+ Add achievement**. Repeat for each. Add a few now, e.g.
`first_win`, `speed_runner`, `the_end`.

---

## Step 3 — Install CoolAPI in Unity

In Unity: **Window → Package Manager → + → Add package from git URL…**

```
https://github.com/your-username/coolgamex.git?path=/sdk
```

(or **Add package from disk…** and pick `sdk/package.json` if working locally).

Requires Unity **2021.3+**.

---

## Step 4 — Add the manager script

Create an empty GameObject named `CoolGameX` in your first scene and attach this
script. It initializes the SDK, logs in with the launcher token, and tracks
playtime automatically.

```csharp
using CoolGameX;
using UnityEngine;

public class CoolGameXManager : MonoBehaviour
{
    [Tooltip("Must match the game's slug in the Admin panel.")]
    public string gameSlug = "my-awesome-game";

    [Tooltip("Your backend URL. http://localhost:4000 while developing.")]
    public string serverUrl = "http://localhost:4000";

    public static CoolGameXManager I { get; private set; }

    async void Awake()
    {
        I = this;
        DontDestroyOnLoad(gameObject);

        await CoolAPI.Initialize(gameSlug, serverUrl);

        if (CoolAPI.IsAuthenticated)
        {
            await CoolAPI.Auth.LoginWithToken(CoolAPI.Token);
            Debug.Log("[CGX] Logged in via launcher.");
        }
        else
        {
            Debug.Log("[CGX] No launcher token — running outside Cool GameX.");
        }

        CoolAPI.Playtime.StartSession();
    }

    /// <summary>Call this from anywhere: CoolGameXManager.I.Unlock("first_win");</summary>
    public async void Unlock(string slug)
    {
        if (!CoolAPI.IsAuthenticated) return;        // skip when not launched by CGX
        bool ok = await CoolAPI.Achievements.Unlock(slug);
        Debug.Log($"[CGX] Unlock '{slug}' → {ok}");
    }

    // Periodic heartbeat so playtime survives a crash (every 5 min).
    float _t;
    void Update()
    {
        _t += Time.unscaledDeltaTime;
        if (_t >= 300f) { _t = 0f; _ = CoolAPI.Playtime.ReportMinutes(5); }
    }

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

---

## Step 5 — Unlock achievements from gameplay

Wherever the achievement is earned, call:

```csharp
// Player won their first match:
CoolGameXManager.I.Unlock("first_win");

// Finished a level fast:
if (levelTime < 90f) CoolGameXManager.I.Unlock("speed_runner");

// Beat the game:
CoolGameXManager.I.Unlock("the_end");
```

That's it — `Unlock` is safe to call repeatedly; the backend ignores
duplicates, and the launcher shows the slide-in popup.

---

## Step 6 — Ship it

1. **Build** your game in Unity (e.g. to a `Build/` folder).
2. **Zip** the build folder so the `.exe` is inside, e.g. `MyAwesomeGame.zip`.
3. **Host the zip** somewhere with a direct download link (GitHub Releases, an
   S3 bucket, etc.).
4. Back in the **Admin panel** → edit your game → set:
   - **Download URL** → the direct link to the zip
   - **Executable path** → `MyAwesomeGame.exe` (must match the file in the zip)
5. Tick **Published** → **Save**.

Now in **Library**, **Install** downloads + extracts your zip to
`~/CoolGameX/Games/My Awesome Game/`, and **Play** launches it with the token.
Earn an achievement → popup. 🎉

---

## Testing without building every time

You can test the SDK against your local server without going through the
launcher by faking a token:

1. Get a JWT for your account (sign in on the app, or use Supabase).
2. In Unity, temporarily call:
   ```csharp
   await CoolAPI.Initialize("my-awesome-game", "http://localhost:4000");
   await CoolAPI.Auth.LoginWithToken("PASTE_A_JWT_HERE");
   await CoolAPI.Achievements.Unlock("first_win");
   ```
3. Check the **Achievements** tab in the app — it should show as unlocked.

> When the real launcher runs your game it passes the token automatically as
> `--cgx-token=<JWT>`, so remove any hard-coded token before shipping.

---

## Troubleshooting

| Symptom | Fix |
| --- | --- |
| `Unlock` returns false | Slug mismatch — the code slug must equal the Admin slug exactly. |
| "Not authenticated" in logs | Game wasn't launched by the launcher (no token). Use the test flow above. |
| Achievement not in the list | It belongs to a different `gameSlug`, or the game isn't the one you claimed. |
| Nothing happens on localhost | Is the backend running? `cd server && npm run dev`. |

See [README.md](README.md) for the full API reference.
