# Lying Bottle Quickstart

## 前置条件

1. 项目已安装 `cn.indiegp.sdk.unity`。
2. 项目已安装 `cn.indiegp.sdk.unity.lying-bottle`。
3. 场景中已有 `IGPRuntimeManager`。
4. `IGPConfig.appId` 已配置。
5. 游戏启动流程已经调用 `IGPRuntimeManager.InitializeAsync()`。

## 调用方式

```csharp
using IGP.UnitySDK;
using IGP.UnitySDK.LyingBottle;

public sealed class LyingBottleQuickstart
{
    private IGPRuntimeManager runtimeManager;

    public async System.Threading.Tasks.Task<string> LoadBottlesAsync()
    {
        return await IGPLyingBottle.GetBottlesAsync<string>(runtimeManager);
    }

    public async System.Threading.Tasks.Task<string> DrawAsync(string subBottleId, string stableRequestId)
    {
        return await IGPLyingBottle.DrawGachaAsync<object, string>(
            runtimeManager,
            subBottleId,
            new
            {
                requestId = stableRequestId,
                poolKey = "default",
                drawCount = 1,
            });
    }
}
```

## 错误处理

`IGPLyingBottleException` 会保留 desktop 返回的错误码、消息和上游 JSON。

```csharp
try
{
    await IGPLyingBottle.GetBottlesAsync<string>(runtimeManager);
}
catch (IGPLyingBottleException ex)
{
    var status = ex.HttpStatus();
    if (status.HasValue && status.Value >= 500)
    {
        // 可按业务策略重试。重试 POST 时复用 body.requestId。
    }
}
```

常见规则：

- `LYING_BOTTLE_HTTP_<status>`：API 返回非 2xx，`UpstreamJson` 里通常有 API error envelope。
- `LYING_BOTTLE_*`：bridge 或调用参数问题，通常不重试。
- `DESKTOP_*`：desktop session 问题，用户登录后重新 attach。
- 带 `requestId` 的 POST 请求重试时必须复用同一个 body-level `requestId`；`StartSession` / `EndSession` 当前没有 body-level `requestId`。

## 路由

本模块内置当前 player 侧 13 条路由。route 使用相对 `/lying-bottle/` 的路径模板，例如 `bottles/:subBottleId/gacha/draw`。

如需调用通用入口：

```csharp
var spec = IGPLyingBottleRoutes.Find(
    IGPLyingBottleHttpMethod.Post,
    IGPLyingBottleRoutes.GachaDraw);

var result = await IGPLyingBottle.CallAsync<object, string>(
    runtimeManager,
    spec,
    pathParams: IGPLyingBottle.PathParams("subBottleId", subBottleId),
    body: new
    {
        requestId = stableRequestId,
        poolKey = "default",
        drawCount = 1,
    });
```

完整请求/响应字段见 `DEVELOPER-GUIDE.zh-CN.md`。
