# Integration Guide

GameMaker Studio 2 Windows：授权验证 + 成就的接入步骤。

---

## 路径 A：只是想先跑示例

示例工程已经完全预置，**无需手工拷贝任何文件**。

```
GameMaker Studio 2
  → File → Open Project
  → samples/gamemaker/windows-auth-achievements/project/IGP.WindowsAuthAchievements.yyp
  → F5
```

运行后查看状态面板：连接状态、授权状态、最近结果、最近错误应随桌面端连接进度刷新。更多验证步骤见 [`SMOKE-CHECKLIST.md`](./SMOKE-CHECKLIST.md)。

---

## 路径 B：接入到你自己的工程

### 1. 放入运行时 GML

把 `adapters/gamemaker/runtime/igp_gms2_windows_runtime.gml` 作为 **script 资源** 加入你的工程（推荐命名保持一致：`igp_gms2_windows_runtime`）。

### 2. 放入原生桥 DLL

把 `adapters/gamemaker/bridge/IGP.GamemakerDesktopBridge.Native.dll` 作为 **Included File** 加入你的工程（放在 `datafiles/`，GameMaker 会在启动时拷到工作目录）。

### 3. 初始化（Create 事件）

```gml
global.igp = igp_sample_create(YOUR_APP_ID);
igp_sample_bootstrap(global.igp, {
    desktop_auto_attach: true
});
```

- `desktop_pipe_endpoint` 默认使用内置连接策略，通常不用传
- `desktop_launch_command` 留空时会按 Unity 同口径自动发现并在 attach 失败时自动尝试拉起
- 只有在覆盖默认 pipe 或特殊发行的启动命令时才需要显式传这两个字段

### 4. 每帧推进（Step 事件）

```gml
igp_sample_step(global.igp);
```

这会内部调用 `igp_update()` 并排空事件队列，更新示例状态。如果你不想用封装，直接在自己的 step 里写：

```gml
igp_update();

var evt = igp_poll_event();
while (!is_undefined(evt)) {
    // 按 evt.type 分派到自己的处理
    evt = igp_poll_event();
}
```

### 5. 渲染状态（Draw 事件）

从 `igp_sample_ui_model(global.igp)` 读字段，或直接查 `igp_get_state_snapshot()`：

- `connection_state`：当前连接状态
- `desktop_channel_state`：当前 desktop 通道状态
- `desktop_attach_state`：当前 attach 校验状态
- `authorization_state` / `authorization_required`：授权
- `anti_addiction_state` / `anti_addiction_can_play_now`：防沉迷当前状态
- `pending_events`：队列中还未消费的事件数
- `last_result` / `last_error`：最近结果/错误

### 6. 触发成就

```gml
igp_unlock_achievement(ACHIEVEMENT_KEY, "", 0, YOUR_APP_ID);
igp_report_achievement_progress(ACHIEVEMENT_KEY, PROGRESS_VALUE, "", "", 0, YOUR_APP_ID);
```

### 7. 查询防沉迷状态

```gml
var status = igp_get_current_anti_addiction_status();
status = igp_refresh_anti_addiction_status(YOUR_APP_ID);
```

运行中如果状态变化，会从 `igp_poll_event()` 读到 `anti_addiction_state_changed`。游戏收到后自行处理提示、存档、回主菜单或退出。

### 8. 退出（Clean Up 事件）

```gml
igp_shutdown();
```

---

## 事件类型参考（首期）

| type | 典型字段 |
| --- | --- |
| `connection_state_changed` | `state` / `connected` / `desktop_channel_state` / `desktop_attach_state` |
| `authorization_state_changed` | `state`、`required` |
| `anti_addiction_state_changed` | `state`、`reason`、`anti_addiction_status` |
| `achievement_result` | `success`、`operation`、`achievementKey`、`duplicated`、`message` |
| `error_reported` | `code`、`category`、`message` |
| `detached` | `reason`、`source` |

GMS2 0.0.1 不会触发 `room_*` / `realtime_message_received`。这些事件语义保留在 [`core/contracts/runtime-events.md`](../../../core/contracts/runtime-events.md) 中供其他引擎适配使用。

完整 API 参考见 [`adapters/gamemaker/runtime/API-SHAPE.md`](../../../adapters/gamemaker/runtime/API-SHAPE.md)。
