Files
nana-story/docs/nana-story-v1-development-plan.md
T
2026-07-28 12:51:00 +08:00

24 KiB
Raw Blame History

nana-story V1 开发计划

中文名:《听娜娜讲故事》 计划版本:0.1 制定日期:2026-07-28 目标平台:Windows 桌面端 执行模型:1 个集成人 + 最多 3 个并行子智能体

1. 交付目标

V1 不是“通用 AI Galgame 平台”的完整形态,而是一段能够证明整个产品闭环的可玩纵切:

  1. 用户通过 LAPP 选择并调用聊天模型;
  2. 导入或使用内置的娜娜试玩资源包;
  3. 创建故事并进行 20~30 分钟的自由输入式角色扮演;
  4. 经历至少一次隐藏的简化 CoC7 判定;
  5. 建立一项重要许诺,并让行为影响信赖、希望等关系维度;
  6. 获得、使用或转移一件带隐藏背景的持有物;
  7. 随时查看自己的持有物、已知线索和已接受许诺;
  8. 查看模糊化的六维关系雷达图;
  9. 每轮自动保存,退出后能够恢复;
  10. 回溯到旧节点继续时创建新分支,并保留原线路。

V1 的成功标准不是资源数量,而是:

从创建故事到完成纵切,全程不需要开发者干预;状态可重放、隐藏信息不泄漏、回溯不破坏旧分支、异常不会留下半轮存档。

2. 已冻结的产品范围

2.1 技术与平台

  • 仓库名:nana-story
  • 首发 Windows 桌面端;安卓以后再考虑。
  • 技术栈:
    • Tauri 2
    • Vue 3
    • TypeScript
    • Vite
    • Naive UI
    • Pinia
    • Vue Router
  • 管理界面可以使用 Naive UI,游玩界面采用自定义视觉实现。
  • 管理端、游玩端和运行时位于同一个 Tauri 桌面进程,不引入 daemon、sidecar 或本地网关。

2.2 模型与 LAPP 边界

  • 供应商协议、模型选择、凭据解析和网络调用由 lapp-rs 负责。
  • nana-story 不直接依赖任何供应商 SDK。
  • nana-story 只提供必要的 LAPP 查看、选择、连接测试和简单管理能力。
  • 本地模型只作为 HTTP 服务接入。
  • 不负责安装、下载、启动、停止、更新或管理 Ollama、LM Studio 等本地模型运行器。
  • 开发时可使用相邻仓库的 path dependency;发布构建必须固定到明确的 lapp-rs 提交,不能复制其协议语义。

2.3 游戏交互

  • 自由输入为主。
  • 每轮可提供 2~3 个可编辑行动建议;点击后只填入输入框,不直接提交。
  • 提供“继续”按钮,表示沉默、观察、等待或允许 NPC 继续行动。
  • AI 不得替玩家决定说话、主动行动或内心想法。
  • 时间按照实际行动推进,不按消息轮数推进。
  • 高风险行动需要先给出叙事风险提示,再执行隐藏的简化 CoC7 判定。
  • 玩家默认看不到骰点、技能数值和精确关系变化。
  • 回复由若干短演出节拍构成,而不是一整块聊天气泡。

2.4 角色、关系与剧情

  • V1 只有一个完整角色:娜娜。
  • 剧情模块可以包含会说话的轻量配角,但不为其建立完整关系系统、长期记忆或自主调度。
  • 六维关系:
    • 好感 affinity
    • 信赖 trust
    • 希望 hope
    • 尊重 respect
    • 亲密 intimacy
    • 依恋 attachment
  • 信赖主要来自已经发生的行为。
  • 希望主要来自被接受的许诺和共同未来计划。
  • 重要许诺必须保存为独立对象,不能简化成一次关系数值变化。
  • 怨恨、恐惧、愧疚、嫉妒等保存为带来源的关系状态,不占六维。
  • 创建故事时绑定剧情模块;V1 不支持中途增删模块。

2.5 持有物、知识与分支

  • 物品定义、物品实例和角色认知必须分离。
  • 所有权 owner 与当前持有者 holder 必须分离。
  • 玩家可以随时读取自己当前可访问的持有物。
  • NPC 的真实持有物不能直接暴露;只能显示公开可见或玩家已经知道的内容。
  • V1 不处理负重、体积、格子或背包容量。
  • 每轮自动保存。
  • 从旧节点继续时创建新分支。
  • V1 不做分支合并,也不建立跨分支记忆。

3. V1 明确不做

  • 多个完整角色及多角色发言调度。
  • 导演 Agent、自动总结 Agent 或运行时多 Agent 编排。
  • 完整 CoC7 职业、成长、战斗、理智、追逐和幸运消费。
  • Live2D、语音、口型、动态镜头和复杂动画。
  • 分支合并和跨分支记忆。
  • 中途增删剧情模块。
  • 负重、体积、容量、制作和物品经济。
  • 内置资源编辑器或可视化剧情编辑器。
  • Steam Workshop 正式接入、DLC 支付、社区付费内容抽成。
  • 云同步、账户、多人或跨设备存档。
  • Android、Web 和多语言发布。
  • 模型下载器、模型启动器和本地模型进程管理。
  • 任意脚本、任意插件或任意外部工具执行。

V1 只保证资源包格式未来可以承接 Workshop/DLC,不实现市场本身。

4. 总体架构

4.1 三类事实

层级 内容 权威来源
创作资源 CharacterCard、WorldBook、Persona、PlotModule、ItemSpec 和素材引用 不可变的版本化资源
分支状态 世界状态、关系、许诺、知识、持有物、时钟、判定记录 根状态/检查点 + 节点 delta
上下文投影 当前意图、命中的世界书、最近演出、提示词 每轮临时编译,可重建

任何模型推测、检索结果和临时提示词都不是持久事实。需要持续存在的变化必须经过类型化操作,由状态 reducer 验证后写入当前分支。

4.2 单一权威写入路径

flowchart TD
    A["玩家输入"] --> B["上下文编译"]
    B --> C["单模型工具循环"]
    C --> D["暂存工具结果与状态操作"]
    D --> E["规则校验与 reducer"]
    E --> F["原子提交 StoryNode"]
    F --> G["生成 PlayerView"]
    G --> H["Vue 演出"]

约束:

  • 模型和前端都不能直接修改 RuntimeState
  • reducer 是状态变化的唯一权威入口。
  • 一轮生成要么完整提交,要么完全不提交。
  • 模型失败、取消、超时或畸形输出不得留下半轮状态。
  • 同一玩家行动的重新生成复用原判定记录;推骰属于新行动和新节点。

4.3 前后端安全边界

前端不得得到完整 RuntimeState,只能得到经过投影的 PlayerView

PlayerView
├─ 当前演出节拍
├─ 可编辑行动建议
├─ 玩家可访问的持有物
├─ 已知线索
├─ 已接受许诺
├─ 模糊化六维关系
└─ 可回溯节点摘要

这条边界用于结构性防止:

  • NPC 隐藏物品泄漏;
  • 未揭示世界事实泄漏;
  • 精确关系数值泄漏;
  • 内部骰点和难度泄漏;
  • 未触发的剧情节点泄漏。

4.4 推荐持久化

V1 默认采用嵌入式 SQLite,由 Rust 侧独占访问。

  • 内容包以经过校验的不可变文件形式安装到应用数据目录。
  • SQLite 保存故事、资源绑定、节点、分支、检查点和迁移版本。
  • 节点中的状态操作使用版本化、类型化 JSON。
  • 每隔固定节点数创建检查点,恢复时使用“最近检查点 + 后续 delta”。
  • SQLite 事务同时提交用户输入、模型演出、工具结果、判定记录和状态 delta。

建议最小表:

stories
story_bindings
story_nodes
story_branches
state_checkpoints
installed_packs
schema_migrations

不要在 V1 过早拆出几十张关系、物品、许诺明细表。分支事件流才是事实来源,当前状态是可重建投影。

4.5 模型运行时

V1 游戏运行时仍然只有一个模型,不引入导演 Agent。

每轮流程:

  1. 读取当前节点、资源绑定和重建后的运行时状态;
  2. 按优先级编译上下文;
  3. 调用 lapp-rs 选中的聊天模型;
  4. 模型按需调用判定、关系、许诺、知识、持有物、时钟等领域工具;
  5. Rust 验证工具参数并写入暂存事务;
  6. 模型根据工具返回继续生成短演出节拍和行动建议;
  7. 校验演出协议与全部状态操作;
  8. 原子提交新节点;
  9. 生成脱敏后的 PlayerView 给前端。

上下文优先级:

  1. 玩家自主权和输出协议;
  2. 当前角色卡、Persona 与场景;
  3. 当前关系、许诺、知识、持有物和剧情压力;
  4. 命中的世界书条目;
  5. 当前分支最近演出;
  6. 非关键风格参考。

V1 不做向量记忆库。世界书先采用确定性的标签、关键词和条件触发;长上下文压缩只能作为可丢弃缓存,不能成为新的事实来源。

5. 仓库结构与代码所有权

建议从第一天就使用 Rust workspace,把并行边界变成目录边界:

nana-story/
├─ src/                         # Vue 应用
│  ├─ app/                     # 路由、全局状态、真实/Mock adapter
│  ├─ features/play/           # 主演出屏
│  ├─ features/inventory/      # 持有物、线索、许诺
│  ├─ features/relationship/   # 关系档案
│  └─ features/history/        # 回溯与分支
├─ src-tauri/                  # Tauri 外壳与窄命令
├─ crates/
│  ├─ nana-domain/             # 资源、状态、delta、PlayerView
│  ├─ nana-engine/             # reducer、规则、简化 CoC7
│  ├─ nana-store/              # SQLite、节点、检查点、恢复
│  └─ nana-runtime/            # LAPP、上下文、工具循环、Turn Engine
├─ contracts/                  # 生成的 JSON Schema 与 TS 类型
├─ content/nana-demo/          # 试玩纵切资源包
├─ fixtures/                   # 稳定的契约和模型响应样例
├─ tests/e2e/                  # 跨模块验收
└─ docs/adr/                   # 已接受架构决策

单一契约源:

Rust serde 类型
→ 生成 JSON Schema
→ 生成 TypeScript DTO
→ CI 检查生成物是否漂移

禁止同时手写 Rust、Schema 和 TypeScript 三套同名模型。

6. 多子智能体并行方案

6.1 推荐拓扑

并行度维持在 1 个集成人 + 3 个子智能体。

角色 独占范围 主要职责
集成人 公共契约、根配置、入口、生成物、跨模块接线、最终验收 拆任务、冻结契约、日常合并、拒绝范围扩张
子智能体 ACore nana-domainnana-enginenana-store 类型、reducer、规则、SQLite、分支重放
子智能体 BRuntime nana-runtime LAPP、上下文编译、工具循环、Turn Engine
子智能体 CExperience src/content/nana-demo/ Vue 界面、演出、官方 Fixture、娜娜纵切内容

测试靠近各自模块编写;跨模块 E2E 和契约生成由集成人负责。

不建议同时开启 5~8 个编码子智能体。这个项目的瓶颈是共享语义而不是代码量,过高并行度会把收益变成 Schema、状态提交和 UI DTO 的返工。

6.2 必须先冻结的契约

进入正式并行前必须合并:

  • ResourceHeader
  • CharacterCard
  • WorldBook
  • Persona
  • PlotModule
  • ItemSpecItemInstance
  • StoryStoryBindingStoryNode
  • RuntimeState
  • 所有状态操作的判别联合
  • PresentationBeat
  • PlayerView
  • TurnRequestTurnResultTurnFailure
  • 五组 canonical fixtures
    • 普通对话;
    • 隐藏判定;
    • 许诺建立与履行;
    • 物品转移且 NPC 尚未知情;
    • 回溯后分叉。

6.3 Worktree 与分支

每个子智能体必须使用独立 Git worktree

integration/v1
agent/core
agent/runtime
agent/experience

规则:

  • 所有分支从同一份已冻结契约提交开始。
  • 每个子智能体只修改分配的目录。
  • Cargo.tomlpackage.json、锁文件、CI、Tauri 入口、Vue 入口和生成代码只由集成人修改。
  • 子智能体需要新增依赖或修改公共契约时,提交短小的变更请求,不直接跨目录修改。
  • 禁止无关重构、全仓格式化和顺手升级依赖。
  • 每天至少合并一次小的可验证增量,不在阶段末进行巨型合并。
  • 只有集成人解决跨模块冲突。

6.4 子智能体任务包模板

每个任务必须包含:

目标:
基线提交:
允许修改的目录:
输入契约版本:
必须新增的测试:
验收命令:
明确不做:
交付时需要说明的风险:

没有这些信息的任务不应分派给子智能体。

7. 里程碑与并行波次

基准工期为 25 个有效开发日,约 5 周。AI 子智能体可以压缩编码时间,但不能取消契约、纵切联调和 Windows 发布验证。

M0:工程骨架与契约冻结(第 1~2 日)

交付:

  • 初始化 Tauri 2 + Vue 3 工程和 Rust workspace
  • 接入相邻 lapp-rs,固定开发基线;
  • 建立 pnpm verify 或等价的一键校验;
  • 定义 Rust 领域类型、生成 JSON Schema 和 TS DTO
  • 建立 canonical fixtures
  • 内置最小娜娜资源包;
  • 写入首批 ADR。

演示:

  • Windows 桌面窗口可以启动;
  • 前端通过窄命令读取应用版本和一份静态 PlayerView
  • 最小娜娜资源包能够加载。

硬门槛:

  • CI 可重复运行;
  • 非法资源返回稳定错误;
  • ID、版本、哈希、依赖和引用可校验;
  • Rust、Schema、TS 不存在多个事实来源。

并行:

  • 集成人:契约与仓库骨架;
  • ACI 和 Rust workspace
  • BFake LAPP Provider/录制模型响应夹具;
  • C:按四张原型搭静态 UI 外壳。

M1:确定性状态内核(第 36 日)

交付:

  • RuntimeState
  • 纯 reducer
  • 六维关系与单轮限幅;
  • 许诺生命周期;
  • 知识与可见性;
  • 物品 owner/holder、位置、取得方式;
  • 时钟;
  • 简化 CoC7 判定记录;
  • PlayerView 投影;
  • SQLite 节点、delta 和检查点。

演示:

  • 不调用模型,仅通过固定命令完成:
    • 获得物品;
    • 作出许诺;
    • 改变关系;
    • 推进时钟;
    • 执行一次判定;
    • 保存、关闭、恢复。

硬门槛:

  • 同一根状态 + 同一组 delta 必须产生完全相同的 RuntimeStatePlayerView
  • delta 重放不能重复结算;
  • 关系变化会被规则限幅;
  • owner/holder 语义正确;
  • 玩家无法读取 NPC 未知持有物;
  • 同一行动重新生成时可以复用判定记录。

并行:

  • Adomain、engine、store
  • B:基于 fixture 实现 runtime 接口和 Fake Provider
  • C:前端使用同一份 PlayerView fixture 完成完整假数据交互。

M2:单轮模型运行循环(第 5~10 日,与 M1 后半段重叠)

交付:

  • LAPP profile 读取、模型选择和连接测试;
  • 非流式与流式聊天适配;
  • 上下文编译器;
  • 领域工具目录;
  • 工具循环和最大轮次保护;
  • PresentationBeat
  • 暂存事务、校验、提交和回滚;
  • 取消、超时、畸形输出和一次安全重试。

演示:

  • 用户输入一句自由文本;
  • 娜娜以短节拍回应;
  • 表情发生一次可选变化;
  • 生成 23 个可编辑建议;
  • 一次需要判定的行动经过工具返回后继续叙述;
  • 整轮状态一次性提交。

硬门槛:

  • 模型和 UI 都不能直接写 RuntimeState
  • 工具失败、取消和断流不产生半轮节点;
  • 模型不能替玩家决定主动言行和内心;
  • 高风险行动先有风险提示;
  • 凭据、完整上游错误体和隐藏状态不进入日志或前端 DTO;
  • CI 使用 Fake Provider,不依赖真实付费模型。

并行:

  • A:补齐 reducer 和 store 的运行时接口;
  • B:实现 LAPP adapter、上下文和工具循环;
  • C:把主演出屏从 fixture adapter 切到真实 Turn API。

M3:自动存档、回溯和分支(第 8~14 日)

交付:

  • 每轮原子自动保存;
  • 分支头和节点父子关系;
  • 从任意旧节点创建新分支;
  • 旧线路保留;
  • 故事恢复;
  • 同输入重新生成与推骰的不同语义;
  • 简洁故事时间线和完整回溯页。

演示:

  • 连续玩 5 轮后退出;
  • 重启恢复;
  • 回到第 2 轮并继续;
  • 原分支和新分支同时存在;
  • 两条分支的持有物、许诺和关系状态互不污染。

硬门槛:

  • 每轮只出现一次有效提交;
  • 重启后的状态与提交前一致;
  • 回溯不会修改旧节点;
  • 重新生成复用原判定;
  • 推骰创建新行动和新判定记录;
  • 500 节点以内的分支恢复不需要扫描无关分支。

并行:

  • A:分支、检查点、恢复和迁移;
  • B:重新生成、推骰与运行时事务;
  • C:故事回溯 UI 和错误恢复交互。

M4:完整玩法系统与四个界面(第 11~18 日)

交付:

  • 主游戏界面;
  • 持有物/线索/许诺侧栏;
  • 六维关系档案;
  • 故事回溯页;
  • 角色卡、世界书、Persona、剧情模块和 ItemSpec 的导入校验;
  • 轻量配角;
  • 场景、立绘、表情和姿态保持;
  • “自由输入 / 建议 / 继续”三种操作。

演示:

  • 四张界面原型对应的真实交互全部接入运行状态;
  • 玩家查看自己的持有物;
  • NPC 未知物品不会出现;
  • 重要许诺能从 accepted 发展到 fulfilled 或 broken
  • 关系雷达变化但不显示精确数字;
  • 轻量配角可以参与一段事件但不会获得完整关系系统。

硬门槛:

  • 所有 UI 数据只来自 PlayerView 或其他脱敏 DTO
  • 不显示骰点、检定难度和精确关系增量;
  • UI 不把消息和演出节拍混为一套结构;
  • 静态资源加载失败有占位和明确错误;
  • 导入包不能通过路径穿越写出目标目录。

并行:

  • A:资源导入、规则系统和 PlayerView;
  • B:世界书触发、剧情工具和轻量配角上下文;
  • C:四个界面和演出状态机。

M5:娜娜 20~30 分钟纵切(第 17~21 日)

纵切至少包含:

  • 一个明确开场目标;
  • 一次普通自由对话;
  • 一次隐藏判定;
  • 一次玩家可感知的风险提示;
  • 一个被接受的重要许诺;
  • 一次用行动证明或破坏许诺;
  • 一件具有隐藏背景的物品;
  • 一次 owner/holder 不同的物品状态;
  • 一次关系路线分化;
  • 一个剧情时钟;
  • 一次轻量配角发言;
  • 一次回溯;
  • 至少两个结果方向。

硬门槛:

  • 无开发者操作可以从开场玩到结果;
  • 条件触发没有死路;
  • 角色不泄露玩家尚未获得的知识;
  • 不同选择产生可回放的不同状态;
  • 引擎规则中不得硬编码 nana 或纵切事件 ID
  • 使用另一个最小反例资源夹具证明引擎仍然通用。

本阶段停止增加系统功能。所有子智能体只处理纵切暴露的问题。

M6Windows 发布前加固(第 2225 日)

交付:

  • Windows 安装包;
  • 崩溃和断电恢复;
  • 存档迁移夹具;
  • 模型超时、断网、限流、拒绝、畸形工具调用处理;
  • 长对话上下文预算测试;
  • 日志脱敏;
  • 内容包边界和尺寸限制;
  • 用户可理解的错误页;
  • 最小发布说明和已知限制。

硬门槛:

  • 全新 Windows 环境能够安装、启动和卸载;
  • 配置一个 LAPP 模型后能够完成纵切;
  • 进程被强制关闭后不会产生半轮节点;
  • 旧 Schema 存档夹具能够迁移或给出明确的不兼容提示;
  • 凭据不进入前端状态、日志、崩溃报告或存档;
  • 所有 canonical fixtures、单元测试和跨模块验收通过。

8. 合并顺序与质量门

每个并行波次按以下顺序合并:

  1. 契约与 fixtures
  2. domain/engine/store
  3. runtime
  4. client adapter
  5. 跨模块 E2E
  6. 纵切内容更新。

任何合并都必须跑同一条最小跨模块场景:

创建故事
→ 三轮交互
→ 一次隐藏判定
→ 获得物品
→ 建立许诺
→ 关闭并重启
→ 回溯
→ 从旧节点继续
→ 校验两个分支互不污染

阶段门禁:

  • M1 未通过确定性重放,不接正式存档 UI。
  • M2 未实现“校验后一次性提交”,不允许模型修改运行时状态。
  • M3 未通过分支隔离,不开放回溯入口。
  • M5 未跑通完整纵切,不扩展第二完整角色、编辑器、Workshop 或 Live2D。

9. 测试矩阵

层级 主要测试
Domain Schema、ID/引用、版本/哈希、资源依赖、反序列化错误
Engine reducer、限幅、许诺生命周期、知识可见性、物品 owner/holder、CoC7
Store 原子提交、重放、检查点、分支隔离、迁移、损坏恢复
Runtime Fake Provider、工具循环、上下文预算、取消、超时、畸形输出
Security PlayerView 泄密、日志脱敏、内容包路径穿越、凭据边界
Frontend 演出状态机、建议编辑、继续、侧栏、雷达、回溯
Cross-module 完整最小场景、重启恢复、回溯继续、真实 LAPP 冒烟
Content 条件可达性、无死路、隐藏事实、不同结果、角色一致性

真实模型测试不作为普通 CI 的前提。CI 使用确定性 Fake Provider;真实模型只运行独立冒烟和录制回归。

10. 主要风险与控制

风险 控制
多个子智能体各自发明 Schema Rust 类型为唯一事实来源;契约目录独占;变更必须更新 fixtures
UI 或模型直接修改状态 所有修改必须经过类型化工具和唯一 reducer
模型输出不稳定 工具调用、结构校验、最大循环次数、一次安全重试、失败不提交
假数据与真实接口分裂 UI 和运行时共用 canonical PlayerView fixtures
分支恢复不确定 纯 reducer;固定 delta 顺序;每次重放做哈希校验
重生成刷骰 判定绑定玩家行动;重新生成复用,推骰创建新行动
隐藏信息泄漏 后端生成 PlayerView;前端永远不获得完整状态
lapp-rs 仍处于 0.1 阶段 固定提交;包一层窄 adapter;用三种协议夹具做回归
本地模型不支持工具调用 V1 启动前做能力检测并明确提示;不在 V1 增加第二套自由文本解析运行时
子智能体大范围重构 目录所有权、短任务包、禁止无关改动、每日小合并
Windows 问题最后才出现 M0 即建立 Windows 构建;每个阶段做一次安装/启动冒烟
纵切内容被写成娜娜专用代码 引擎只识别通用标签和资源引用;增加非娜娜反例夹具

11. V1 Definition of Done

满足以下全部条件才称为 V1

  • Windows 安装包可用;
  • 使用 LAPP 可以选择云端或本地 HTTP 模型并通过连接测试;
  • 内置娜娜试玩包可直接创建故事;
  • 20~30 分钟纵切可从头玩到至少两个结果方向;
  • 自由输入、可编辑建议和“继续”都能稳定完成一轮;
  • 六维关系、许诺、知识、持有物、时钟和隐藏判定都在纵切中真实生效;
  • 每轮原子自动保存;
  • 重启恢复一致;
  • 回溯后建立新分支并保留旧线;
  • 同一行动重新生成不重新掷骰;
  • NPC 隐藏状态、精确关系值、骰点和凭据不泄漏;
  • 模型取消、超时和畸形输出不产生半轮状态;
  • canonical fixtures、自动测试和 Windows 冒烟全部通过;
  • 没有引入 V1 明确不做的功能。

12. 开工顺序

第一批实际开发任务按下面顺序创建:

  1. 初始化 nana-story 仓库、Tauri/Vue 工程和 Rust workspace
  2. 写入架构 ADR 与目录所有权;
  3. 定义 ResourceHeader、资源绑定、StoryNodeRuntimeState、状态操作、PresentationBeatPlayerView
  4. 生成 JSON Schema、TypeScript DTO 和 canonical fixtures
  5. 同时启动三个独立 worktree
    • Corereducer + SQLite
    • RuntimeFake Provider + Turn API
    • Experience:静态主演出屏 + fixture adapter
  6. 在 M1 确定性重放通过后,接入真实 lapp-rs 和第一条完整游戏回合。

第一条集成目标应当非常小:

玩家输入“我答应天亮前回来”,娜娜回应并接受许诺;引擎创建 Promise、提高希望、保存节点;关闭应用后恢复;回溯到许诺之前继续,旧分支仍然存在。

它同时覆盖角色演出、工具调用、许诺、关系、存档、恢复和分支,是最适合作为 nana-story 第一条端到端主线的开发样例。