# 07 · 图谱宇宙链 XYLink SDK —— 游戏接入接口

> **版本**：v1.0.0｜**定位**：把本地资料库沉淀为**零依赖单文件 SDK**——任何游戏（RTS/RPG/卡牌/文字/网页小游戏）引一个 `<script>`，即可接入西游宇宙的**剧情状态机 / 三币经济 / 世界观注册表 / 事件桥 / 跨游戏存档**。

> **首个非自家接入案例**：《西游·功德修行录》→ 见 [`integrations/gongdelu/`](./integrations/gongdelu/)。

```
 其他游戏（RTS·RPG·卡牌·文字…）
   │  <script src="xyLink.js">            ← 本目录，file:// 直开可用
   ▼
 ┌─────────────── XYLink（图谱宇宙链）───────────────┐
 │  story     剧情状态机（story_ch1_ch2.json 语义） │
 │  economy   三币经济（功德/金丹/灵韵，V8 同名）     │
 │  world     世界观注册表（势力/英雄/法宝/隐国）    │
 │  bridge    游戏事件桥（RedAlertBridge 同签名）   │
 │  save      存档（ns 隔离 + 导出/导入迁移）       │
 │  protocol  iframe postMessage（门户/小游戏）    │
 └──────────────────────────────────────────────┘
```

---

## 一、30 秒接入

```html
<script src="xyLink.js"></script>
<script src="data/story_ch1_ch2.js"></script>  <!-- 可选：不引则自行 XYLink.story.load(json) -->
<script>
  // ① 初始化（同源多游戏：共享进度用同名 ns，隔离用不同 ns）
  XYLink.init({ game: "我的游戏", ns: "global" });

  // ② 游戏事件 → 图谱宇宙链（与叙事引擎 RedAlertBridge 完全同签名，RTS 调用点可原样复用）
  XYLink.bridge.onFactionJoin("local", "huaguoshan");
  XYLink.bridge.onHiddenKingdomEnter("local", "hk_chechi");
  XYLink.bridge.onTreasureInherit("local", "jingubang");
  XYLink.bridge.onVictory(levelDef, 1, 5);          // index 1-based（胜第1关→解锁第2关）

  // ③ 三币经济
  XYLink.economy.grant("gongde", 50, "守脉奖励");
  XYLink.economy.spend("gongde", 24, "招安散妖");    // 余额不足返回 {ok:false}，不抛异常

  // ④ 剧情推进（story_ch1_ch2.json 语义：requires/state_write/flags_add/next/on_enter）
  XYLink.story.start();
  const view = XYLink.story.view();                  // {id,title,text,speakers,choices,atEnd}
  XYLink.story.choose(0);                            // 自动过防吃书校验

  // ⑤ 存档（自动保存；亦可导出 JSON 跨游戏/跨设备迁移）
  const json = XYLink.save.export();  XYLink.save.import(json);
</script>
```

**最小可运行示例**：本目录 `demo.html`（模拟第三方游戏「灵脉守卫」，加载后自动演示一轮完整调用链）。

---

## 二、模块 API 总表

### story — 剧情状态机（对齐 `story_ch1_ch2.json` meta.parse_guide）

| 方法 | 返回 | 说明 |
|------|------|------|
| `load(data)` | this | 注入剧情 JSON（init 时自动挂载 `window.XYLINK_STORY_DATA`） |
| `start()` / `goto(id)` | `{ok, node\|violation}` | 进入节点（先过防吃书校验，再执行 on_enter） |
| `view()` | 视图对象 | 当前节点：`text_variants` 已按 state 匹配、`choices` 已按 requires 求值（`enabled`） |
| `choose(index)` | `{ok, node\|error}` | 执行选项：requires → state_write（map 浅合并）→ flags_add → next |
| `checkValidations(node)` | `{ok}\|violation` | 防吃书校验：check=不变量；`faction_once_fixed` 仅 Ch2+（与 engine/validations.js 一致） |
| `setFlag/hasFlag/raiseFavor/addReputation` | — | 状态直调 API |
| `renderText(node)` | string | 文本变体求值（第一个 when 全满足者，无则节点 text 兜底） |

条件键支持：`faction` / `faction_not` / `flags_has` / `flags_absent` / `reputation_gt` / `reputation_lt` / `favor_gt` / `chapter_gte`（未知键忽略，向前兼容）。

### economy — 三币经济（币名与 V8Bridge 一致）

| 方法 | 返回 | 说明 |
|------|------|------|
| `balances()` | `{gongde,jindan,lingyun}` | 余额（初始 功德20/金丹0/灵韵0） |
| `grant(cur, n, reason)` | `{ok, balances}` | 发放（n 必须 > 0） |
| `spend(cur, n, reason)` | `{ok}\|{ok:false,error:'insufficient'}` | 消费，不足不抛异常 |
| `creditTransfer(from, to, n)` | `{ok, out, balances}` | 跨币折算（基准表 gongde10/jindan6/lingyun4，`setRates` 可调） |
| `ledger(limit)` | 数组 | 流水台账（上限 100 条） |

### bridge — 游戏事件桥（**RedAlertBridge / RTS storyBridge 同签名**）

| 方法 | 对齐签名 | 行为 |
|------|----------|------|
| `onHiddenKingdomEnter(pid, kingdomId)` | ✅ | hidden_progress 累计 + flag `<id>_entered` |
| `onTreasureInherit(pid, treasureId)` | ✅ | treasures 幂等登记 + flag `treasure_<id>` |
| `onFactionJoin(pid, factionId)` | ✅ | 设定 faction + 该势力声望 +1 |
| `onLingmaiCapture(pid, n)` | ✅ | lingmai_control 累加 |
| `onVictory(levelDef, index, total)` | ✅ | 合并 `levelDef.story`（flags + state 键级覆盖）+ 解锁 index+1 关 |
| `isUnlocked(n)` / `progress()` / `markWin(id)` | — | 关卡进度（`{unlocked, wins}`） |

另：`XYLink.on(evt, cb)` 订阅事件——`change`（任何变更）、`<module>:<action>`（如 `economy:grant`）、`"*"`（全量）。

### world — 世界观注册表（WB 精华·机器可读，正式设定以 `01_世界观圣经/` 为准）

| 表 | 内容 |
|----|------|
| `currencies` | gongde 功德 / jindan 金丹 / lingyun 灵韵 |
| `factions` | 花果山新生代 / 牛魔王家族 / 兜率宫坐骑派 / 狮驼岭大鹏 / 天庭 / 独立 |
| `heroes` | 猕三郎→jingubang / 哪吒→qiankunquan / 红绫→bashanfan（含 AOE 技能名） |
| `treasures` | 如意金箍棒 / 乾坤圈 / 芭山扇 |
| `kingdoms` | 隐匿四国：hk_chechi 车迟国 / hk_jisai 祭赛国 / hk_nver 女儿国 / hk_fengxian 凤仙郡 |
| `sanyao` | 散妖招安参数 `{gongde:3, need:8}`（WB §1.6） |
| `get(id)` | 全表统一检索 |

### save — 存档 / protocol — 跨帧协议

| 方法 | 说明 |
|------|------|
| `save.export() / import(json)` | 导出/导入完整快照 `{app:"XYLink", v:1, ns, state, cur, progress, ledger}`（坏包拒绝） |
| `save.persist() / restore() / reset()` | 手动持久化 / 接管旧档 / 清档（autoSave 默认开启，变更即存） |
| `protocol.serve(handlers?, env?)` | 门户宿主端：默认映射 state/story/economy/save 八个动作 |
| `protocol.connect(origin?, env?, target?)` | iframe 游戏端：`request(action, payload) → Promise`；信封 `{ns:"xiyou-xylink", v:1, id, action, payload}` |

---

## 三、数据契约

**state 形状**（与 `story_ch1_ch2.json` state_schema 对齐 + XYLink 扩展层）：

```jsonc
{
  "chapter": 1, "faction": "huaguoshan",
  "npc_favor":  {"mihou":0,"hongling":0,"laojun":0,"guanyin":0,"dapeng":0},
  "reputation": {"huaguoshan":10,"niu":0,"laojun":0,"dameng":0},
  "treasures": ["jingubang"], "lingmai_control": 1, "hidden_progress": {"hk_chechi":1},
  "flags": ["entered_ch1","ch1_join_huaguoshan"],
  "wallet": {"gongde":46,"jindan":0,"lingyun":0},
  "meta": {"link":"1.0.0","game":"灵脉守卫","updatedAt":"…"}
}
```

**存储键**：`xysl_xylink_<ns>_v1`（localStorage 优先，不可用自动内存兜底）。**默认 ns="global"**——同源所有接入游戏共享西游进度；`ns:"我的游戏"` 即私有空间。

---

## 四、契约对齐一览

| XYLink | 对齐对象 | 一致性 |
|--------|----------|--------|
| `bridge` 五方法 | engine `RedAlertBridge` / RTS `storyBridge` | 方法签名、幂等语义、state 合并规则逐一同构 |
| `story` 推进语义 | story_ch1_ch2.json `meta.parse_guide` | requires/when/state_write/flags_add/next/on_enter 全实现 |
| 防吃书校验 | engine `js/src/validations.js` | check=不变量 + `faction_once_fixed` 仅 Ch2+ 的 SCOPE_OVERRIDES 补丁 |
| 三币命名 | V8Bridge（gongde/jindan/lingyun） | 未来接 V8 图谱上报零改名 |

---

## 五、验证

```bash
node 西游资料库/07_图谱宇宙链SDK/test_xylink.js   # → 49/49 通过（9 大组：契约/剧情/校验/经济/桥/注册表/存档/事件/协议）
```

浏览器实测：`demo.html`（见 `preview_sdk.png`）——模拟第三方游戏自动执行 init→剧情推进→入伙→发钱→占隐国→获法宝→招安扣费 全链路，监视器与 API 日志全绿。

## 六、目录与版本

```
07_图谱宇宙链SDK/
├── xyLink.js              SDK 本体（单文件 ~600 行，零依赖，浏览器+Node 双端）
├── data/story_ch1_ch2.js  剧情数据包（由 /workspace/story_ch1_ch2.json 生成，勿手改）
├── demo.html              最小接入演示（模拟第三方游戏）
├── test_xylink.js         无头测试 49 项
├── preview_sdk.png        演示页实测截图
└── README.md              本文档
```

**演进预留**：`protocol` 信封风格与 v8Bridge 一致，后续接 v8 图谱/三币上报（`graphAddChar / creditTransfer / balances`）时，仅替换 serve 端 handlers，游戏侧调用零改动。
