# 架构决策记录

## 1. 引擎与 UI 分离

`engine/` 下纯 TS 类，不 import Vue。UI 层通过 composables 桥接。

## 2. A/B 双缓冲

两个 `<video>` 元素轮换，一个播放时另一个预加载候选视频。300ms CSS opacity 交叉淡化。

## 3. JSON 驱动

所有剧情数据放在 JSON 中，编辑器本质是 JSON 的可视化读写工具。

## 4. IndexedDB 存档

比 localStorage 容量大，可存储截屏缩略图。多槽位支持，跨会话持久化。

## 5. 故事图与玩家树

创作端的 JSON 是有向图（Graph），玩家端展示的是严格树（Tree）。

- 数据层：故事图 + 玩家存档
- 渲染层：`buildPlayerTree()` 将图投影为树
- 汇聚节点在树上复制展示，每条路径独立
- 回环用 `pathSet` 精确剪枝 + `depth > 10` 兜底

详见 [ROADMAP.md P23](../ROADMAP.md#p23-玩家树可视化--缩进树取代平铺列表)

## 6. 成就 — 纯变量单一检查点

所有成就通过变量检测，在 `StateManager.apply` 末尾单一检查点触发。事件型成就改写为变量型（QTE 成功 = 在 effects 中 `set` 标记变量）。

## 7. i18n — 双文件分层

- `src/locales/` — UI 文本（静态 import，构建时打包）
- `public/locales/` — 故事文本（fetch 动态加载）

`useI18n.t()` 优先查故事消息，fallback 到 UI 消息。

## 8. 章节 — 单文件共享场景

所有场景在一个 JSON 中，章节用 `startScene` 标记边界。场景可跨章引用以保持叙事灵活性，但建议制作者保持各章 BFS 独立。
