Files
aibis-dream/Docs/Yarn维修节点类型规范.md

19 KiB
Raw Permalink Blame History

Yarn 维修节点类型规范

本规范适用于 Assets/Yarn/FP/ 下的维修流程脚本,包括:

  • FP_Huoshan1
  • FP_Peipei1 / FP_Peipei2 / FP_Peipei3
  • FP_Shitou1 / FP_Shitou2
  • FP_Prologue

注意FP_Day*_sleep 属于梦境脚本,沿用《Yarn 节点类型规范.md》;FP_Day*_begin/mid/night 属于外出/日常脚本,不在本规范范围内。


1. 节点类型与跳转权限

类型 标签 职责 跳转权限 内容限制
start start 引擎入口 单出口 <<jump>> 无叙事文本;负责最小环境初始化,并 <<detour>> 调用 init 后跳转到 Center
init init 变量声明与初始状态 无出口 <<declare>> / <<set>> / 全局参数初始化;本身不跳转
center center 阶段调度中枢 可多出口 <<jump>> 仅按 $gameStage 分发,无文本、无选项
content content 阶段内容节点 通常单出口 可含叙事文本、局部选项、小游戏指令
performance performance 原子化线性演出节点 单出口 timeline、cutscene 等,禁止选项
event event C# 调用的事件响应入口 单/多出口 <<jump>> 仅轻量路由,禁止大段叙事
function function 纯指令封装 禁止 <<jump>> 仅 Command,无文本;命名加 _Func 后缀
end end 维修结束/收尾 单出口 可含少量结束演出,最终必须 <<NextYarn>>

附加标记(可附加到任何类型):

  • deprecated:已废弃节点,运行时不可达。
  • wip:待编辑/占位节点,运行时不可达。
  • no_save:该节点不可作为保存边界。即使节点类型通常允许保存(如 content),附加此标签也表示此处不应触发保存。
  • 瞬跳节点:见 §8 瞬跳节点与存档边界。所有瞬跳节点均不可作为保存边界。

2. 命名规则

类型 命名示例 规则
start Start 固定命名,首字母大写
init VarsInit数据初始化 建议统一为 VarsInit;如项目已有 数据初始化,可保留但同一 project 内保持一致
center Center 固定命名,每个维修 Yarn project 一个
content Stage1开头对话检查情绪旋钮调节 阶段入口建议用 StageN;阶段内子节点用中文动宾/名词短语
performance 地铁到站演出手术动画滤波器启动动画 中文描述性名称,明确表达演出内容
event EmoPlugInIntoEyeViewOnSalesTurnComplete OnXxx 或模块名 + 事件名,表达触发来源
function Wave_Show_FuncWave_Hide_FuncModule_HighlightOff_Func 领域_动作_Func模块_动作_FuncPascalCase;必须带 _Func 后缀
end EndStage8_End 统一用 End 或带阶段前缀的结束名

3. 各类型详细规范

3.1 start 节点

Yarn Spinner 默认从名为 Start 的节点开始运行。它不属于任何功能类型,职责仅是启动流程。

title: Start
tags: start
---
<<init_environment Day>>
<<init_actor 地铁医生 左边>>
<<show_actor 地铁医生>>

<<detour VarsInit>>
<<jump Center>>
===

约束清单:

  • 整个项目的开始阶段固定命名为 Start,标签 start
  • 单个yarn脚本的开始阶段不能命名为Start,但标签为start
  • 不写叙事文本、不声明变量、不含选项。
  • 仅做最小必要的环境初始化。

3.2 init 节点

集中声明维修流程所需变量,并设置初始全局参数。与梦境规范中的 InitParams 属于同一类型,只是节点名可按项目习惯选择 VarsInit数据初始化

init 节点本身不包含任何跳转出口,由 Start 节点通过 <<detour>> 调用;执行完毕后控制流自动返回 Start,再由 Start 统一跳转到 Center

title: VarsInit
tags: init
---
// 流程阶段
<<declare $gameStage=1>>

// 模块检查标记
<<declare $emoChecked=false>>
<<declare $memoryChecked=false>>
<<declare $logicChecked=false>>

// 小游戏相关状态
<<declare $salesTurnIndex=0>>
<<declare $knobFailCount=0>>
===

约束清单:

  • 标签 init,固定命名为 VarsInit(或统一使用 数据初始化)。
  • 仅包含 <<declare>><<set>><<set_global_param>> 等初始化指令。
  • 禁止叙事文本、选项和任何 <<jump>>
  • 同一 project 内,init 节点的命名必须一致。

3.3 center 节点

唯一拥有多出口跳转权的节点,负责按 $gameStage 进行阶段调度。

title: Center
tags: center
---
// Stage1: 诊室开场
// Stage2: 后脑检查
// Stage3: 滤波器深入
// ...

<<if $gameStage == 1>>
    <<jump Stage1>>
<<elseif $gameStage == 2>>
    <<jump Stage2>>
<<elseif $gameStage == 3>>
    <<jump Stage3>>
<<elseif $gameStage == 999>>
    <<jump End>>
<<endif>>
===

约束清单:

  • 标签 center,固定命名为 Center
  • 仅按 $gameStageif 分发,不写叙事文本、不含选项。
  • 维修终止条件统一在此处理(如 $gameStage == 999 时跳转到 end)。
  • 是同一 project 内唯一应该读取 $gameStage 的节点。
  • 瞬跳节点Center 只做阶段分发,进入后立刻 <<jump>>StageN 等目标,不向玩家停留;不得作为存档边界(tag 上已属禁止保存类型,编写时勿把可存逻辑写在此节点)。

3.4 content 节点

维修流程的核心单元,承载阶段中的实际内容:叙事、选项、小游戏指令等。

title: Stage1
tags: content
---
<<hide_dialog>>
<<switch_fix_system_to "Clinic">>
<<fade_out 1>>
<<jump 开头对话>>
===
title: 开头对话
tags: content
---
hs: 医——生——! #line:0bade9e

<<change_actor_state 捂头表情idle 火山>>
<<fade_in_actor 火山>>

// ... 叙事与演出 ...

<<set $gameStage = 2>>
<<jump Center>>
===

约束清单:

  • 标签 content
  • 阶段入口节点建议命名为 StageN;阶段内子节点用中文描述性名称。
  • 阶段末尾通常做两件事:设置 $gameStage、跳回 Center
  • 允许内部嵌套局部选项,但选项应服务于当前阶段内容,不做跨阶段跳转。
  • 不应读取 $gameStage 做复杂分发(这是 center 的职责)。
  • 瞬跳 content:若节点内无台词、无选项、进入后仅做 <<set>> / 条件判断并立刻 <<jump>>(如 UF检查状态),属于瞬跳节点,须附加 no_save,不得依赖默认的 content 可存语义。详见 §8

3.5 performance 节点

原子化线性演出节点,用于 timeline、cutscene 等必须完整播放的演出。

title: 地铁到站演出
tags: performance
---
<<hide_dialog>>
<<play_timeline 地铁到站>>
<<wait 2>>
<<jump 诊室外2>>
===

约束清单:

  • 标签 performance
  • 禁止分支选项,必须单出口。
  • 禁止叙事文本、角色台词与旁白
  • 保存点只能出现在 performance 节点的开始之前结束之后,节点内部不允许保存。
  • 仅包含 timeline 播放、镜头运动、动画演出等线性指令。

3.6 event 节点

由 C# 代码调用的事件响应入口,负责把外部游戏事件映射到对应阶段节点。

title: EmoPlugIn
tags: event
---
<<jump 检查情绪>>
===
title: OnSalesTurnComplete
tags: event
---
<<if $salesTurnIndex == 1>>
    <<jump 销售转动_语义合成>>
<<elseif $salesTurnIndex == 2>>
    <<jump 销售转动_语言审查>>
<<elseif $salesTurnIndex == 3>>
    <<jump 销售转动_异常检测>>
<<endif>>
===

约束清单:

  • 标签 event
  • 节点标题应表达触发来源,建议使用 OnXxx 或「模块 + 事件」形式。
  • 允许根据 $gameStage 或少量状态变量做轻量 if 分发。
  • 禁止大段对话、旁白、演出文本
  • 不应成为玩家直接阅读的内容节点。

3.7 function 节点

纯指令封装,零文本、零跳转,用于复用一组命令。与梦境规范的 function 保持一致,命名加 _Func 后缀。

title: Wave_Show_Func
tags: function
---
<<switch_emotion_wave_config "normal">>
<<show_emotion_wave 1>>
===
title: Wave_Hide_Func
tags: function
---
<<hide_emotion_wave 0.3>>
===

约束清单:

  • 标签 function
  • 命名必须带 _Func 后缀。
  • 禁止任何叙事文本、对话、选项
  • 禁止任何 <<jump>>
  • 仅包含演出或小游戏相关的 Command。

3.8 end 节点

维修流程的收尾节点,负责结束当前脚本。

title: End
tags: end
---
<<fade_out 1>>
<<wait 1>>

me: 今天就到这里吧。 #line:xxxxxxxx

<<hide_dialog>>
<<wait 2>>
<<NextYarn>>
===

约束清单:

  • 标签 end,建议同时附加 no_save:维修流程已结束,控制权即将交还 C#,通常不应作为保存边界。
  • 可含少量结束演出与收尾对话。
  • 可能跳回center,也可能进入<>
  • 不要在一个维修脚本里设置多个 end 节点,除非剧情明确需要分支结局。

4. 控制流图

Start ──<<detour>>──> VarsInit / 数据初始化
  │                          │
  │                          │(自动返回 Start)
  │                          ▼
  │                       Start
  │                          │
  ▼                          │
Center ◀─────────────────────┘
  │
  ├──<<jump>>──> Stage1content/performance 入口)
  │                      │
  │                      ├── content 子节点 ── ...
  │                      │
  │                      ├── performance 子节点 ──<<jump>>──> content 或 end
  │                      │
  │                      └── <<set $gameStage>> ──> <<jump Center>>
  │
  ├──<<jump>>──> End ──<<NextYarn>>
  │
  └── C# 调用 ──> event 节点 ──<<jump>>──> content 子流程

5. $gameStage 使用规范

  • $gameStagecenter 节点的调度主键。
  • 类型可以为 intstring,但同一 Yarn project 内必须保持一致
  • 只有 center 节点读取 $gameStage
  • content 节点在末尾写入 $gameStage,然后跳回 center
  • 终止值(如 999"流程结束")统一在 center 中处理。

6. 快速检查表

检查项 start init center content performance event function end
是否包含叙事文本? 禁止 禁止 禁止 允许 禁止 禁止 禁止 允许(少量)
是否包含选项? 禁止 禁止 禁止 允许 禁止 禁止 禁止 禁止
是否有 <<jump>> 仅一个出口 禁止 可多出口 通常一个出口 单出口 可有 禁止 最终 <<NextYarn>>
是否修改 $gameStage 禁止 可初始化 禁止 允许 禁止 尽量避免 禁止 禁止
是否被 C# 调用?
是否可作为保存边界? 否(瞬跳) 是(瞬跳 content 除外,须 no_save 仅开头/结尾(节点本身建议 no_save 否(可附加 no_save 强调) 否(建议 no_save

7. 附加标记

  • deprecated:已废弃节点,运行时不可达。
  • wip:待编辑/占位节点,运行时不可达。
  • no_save:该节点不可作为保存边界,运行时经过此处不应触发保存。

7.1 no_save 使用场景

no_save 用于显式声明某节点处不允许保存,常用于以下情况:

  • end 节点:维修流程已结束,控制权即将交还 C#,通常附加 no_save
  • performance 节点:演出期间不能保存,建议在 tags: 中附加 no_save
  • 关键 event 节点:事件路由节点通常不保存,可附加 no_save 强调。
  • 瞬跳 content 节点:无玩家可感知停留、进入后立即跳转的路由/状态检查节点(如 UF检查状态),必须附加 no_save。完整定义与排查清单见 §8
  • 特殊 content 节点:极少数剧情上明确不希望保存的 content 节点,可附加 no_save 覆盖默认可保存语义。

任何活跃节点不得 <<jump>>deprecated / wip 节点,也不得在标记为 no_save 的节点处触发 OnNodeStart 自动保存

7.2 Yarn 显式存档 <<save>>

用于节点末尾、状态已就位、即将进入无对话 / 纯 C# 交互阶段时的显式存盘点OnNodeStart 无法覆盖的场景)。

<<play_timeline 地铁>>
<<hide_dialog>>
<<change_actor_state "turn" "地铁医生">>
<<save>>
<<detour 切换到诊所外>>

约定:

  • 插入位置:所有需要进快照的状态命令之后;<<jump>> / <<detour>> / load_scene 之前(顺序即快照内容)。
  • anchor:默认 omit(读档不重进 Yarn);依赖 sections 还原画面与玩法状态。
  • 判定:绕过 tag / no_save;读档中、暂停、SuppressAutoSave 仍拒绝。
  • async 命令change_actor_state_async 等未等待的命令之后立刻 <<save>> 可能 capture 未完成态,save 前应 <<wait>> 或使用同步命令。

no_saveno_save 禁止的是 OnNodeStart 自动存;节点末尾仍可写 <<save>> 表达作者意图。


8. 瞬跳节点与存档边界

8.1 定义

瞬跳节点:进入后不向玩家展示可感知内容(无台词、无选项、无需要玩家推进的对话行),在同一轮 Yarn 执行中很快通过 <<jump>> 离开,或仅承担路由 / 变量写入 / 阶段切换的节点。

典型特征(满足多数即可视为瞬跳):

  • 节点体无角色台词、无 -> 选项;
  • 仅有 <<if>> + <<set>> + <<jump>>,或少量 <<wait>> 后立即跳转;
  • 玩家不会在屏幕上「停」在这个节点完成一次交互。

8.2 与存档的关系

所有瞬跳节点均不得作为存档边界。 原因:

  1. 语义:存档点应对应玩家能感知的进度位置;瞬跳节点只是控制流中转,不是叙事/玩法上的「停点」。
  2. 实现:瞬跳节点常在同一帧内连跳(如 contentendCenterstart);若在瞬跳节点触发保存,锚点容易漂移或落到 start / center 等错误节点(参见 UF检查状态Stage3 一类问题)。

8.3 按 tag 的默认策略

类型 是否瞬跳 是否可存 说明
start tag 已禁止
init tag 已禁止
center 阶段调度,仅分发 <<jump>>;编写与排查时明确视为瞬跳
function tag 已禁止
event 多为瞬跳 tag 已禁止;路由型 event 一律不可存
end 多为瞬跳 建议 end no_save
performance 否(演出中) 节点本身不可存;边界在演出前后
content 视内容而定 仅非瞬跳 content 可存 有台词/选项/玩家停留 → 可存;纯路由 → no_save

8.4 维修脚本中的常见瞬跳 content(待排查)

以下模式在现有脚本中已出现或容易出现,应加 no_save 或改写为不可触发的保存路径(全项目逐步排查,非一次性改完):

  • *检查状态*状态:条件满足后立刻 <<jump>> 到结束/下一阶段(如 UF检查状态视觉检查状态$isFinished*==true 分支);
  • 阶段 StageN 入口若 tag 为 start:已禁止,勿改为 content 除非有真实停点;
  • 任何「只写 $gameStage 并跳 Center / 结束*」的短节点。

8.5 编写与审查 checklist

  • 该节点玩家是否会看到对话或做出选择?若否 → 瞬跳 → 不可存,加 no_save
  • 是否为 Center 或等价调度节点?→ 不可存
  • 进入后是否在同一轮控制流内连跳多个节点?→ 链上所有节点都不应单独成为存档边界;可存点应落在链之后第一个玩家会停住的 content 上。
  • 新加 content 节点时,默认「可存」;仅当确认有玩家停点时才省略 no_save

TODO(脚本排查):对 Assets/Yarn/FP/ 下各 project 扫描瞬跳 content 节点,补 no_save 或调整跳转结构。优先级可参考存档验证工具中误报节点(如 Peipei UF检查状态)。


9. 设计原则

  • **start 负责启动**:最小初始化 + <<detour>> 调用 init + 唯一 <<jump>>Center
  • **init 负责配置**:所有变量声明集中管理;无跳转出口,执行完毕后返回 Start
  • **center 负责调度**:打开 center 即可一览整个维修流程阶段;瞬跳、不可存
  • **content 负责内容**:阶段之间的叙事、选项、小游戏交互隔离,便于单独调整。
  • **performance 负责原子化演出**timeline、cutscene 等必须完整播放,保存边界清晰。
  • **event 负责桥接**:把 C# 事件翻译成 Yarn 内部跳转,不掺杂叙事。
  • **function 负责复用指令**:零文本零跳转,_Func 后缀与梦境规范保持一致。
  • **end 负责收尾**:统一出口,统一 <<NextYarn>>