Yarn脚本
什么是 Yarn 脚本
以 .yarn 结尾的文件是 Yarn Spinner 对话脚本。本项目用它驱动:
- 对话和选项;
- 天数、时间和直播流程;
- 角色进出场;
- 技能检定与战斗;
- 新闻、邮件、商城、弹幕和 UI 状态;
- 角色表情、皮肤和部分 Spine 动作。
- 反正就是几乎所有东西
再次,Yarn Spinner 的通用语法请阅读Yarn Spinner 官方文档。本文档仅描述其在本项目中的特殊使用方法。
项目主流程
入口流程在 Assets/YarnScripts/Logic/ 下:
Initial
-> Welcome
-> Aistalt_Day
-> Live
-> Live_Node
-> Live_Hub
-> Chat_node
-> Aistalt_Night
-> ClockOut
-> Dream
-> EndDay
-> Initial实际游戏中可能因为天数、选项和条件跳转到不同节点,但理解这些节点足以定位大多数 Mod 接入点。
Initial - 初始化
在游戏开始时自动播放。负责每日初始化。
它会重置或准备当天的 UI、邮件、新闻、交互物品和其他运行时状态。
Welcome - 欢迎
玩家点击“开始直播”后,即进入 Welcome。
这里通常完成直播界面准备,并把流程交给白天对话。Aistalt会在这里欢迎玩家。
Aistalt_Day - 白天与Aistalt的对话
白天与 Aistalt 的单独对话。包括了小蓝冷笑话,小绿讲历史,看新闻和杂谈等。
Live_Hub - 直播根节点,超级重要!!!!!!!!!!!
Live_Hub 是直播循环的中心节点。
title:Live_Hub
subtitle: Auto_9bd309fc1c
when:always
tags:#hub #reach
---
<<Solo Aistalt>> // 清理上一轮中可能残留的其他角色
<<if $CurrentHour<18>> // 如果还没下班
<<set $LineCount += 1>> // 增加连线次数;有些对话要监听这个参数来判断
<<detour Live_Hub_RandomGroup_Start>> // 牢爱的随机台词
<<if CountNPCOption("Live_Entry") >0 >> // 确认现在是否还有可用的Live_Entry,如果没有的话,那执行GenerateNPCOption Live_Entry会报错。如果有那就继续。
<<GenerateNPCOption Live_Entry 3>> // 寻找以Live_Entry开头的所有节点,生成3个可用的。
<<else>>
Aistalt: 等等……互联网上已经没有人类了吗? #state:Idle #line:063a1c7 // 目前还没出现过这个情况。互联网上真没人了再说吧……
<<EndLiveStatus>> // 这种情况下只能结束直播状态
<<ChangeController Window_LiveStream CanEndLive yes>> // 切换为可以结束直播。
<<endif>>
<<else>>
<<detour Live_Hub_RandomGroup_End>> // 准备下班的随机台词;如果已经超过18点了,当然就应该依劳动法下班
<<EndLiveStatus>> // 结束直播状态
<<ChangeController Window_LiveStream CanEndLive yes>> // 可结束直播
<<endif>>
===它通常通过:
<<GenerateNPCOption Live_Entry 3>>寻找以 Live_Entry 开头、且条件满足的节点,生成指定数量的连麦选项。比如:
title: Live_Entry_MaoGirl // 以Live_Entry开头,因此它可以在Live_Hub阶段访问
when:always // 总是可用
Character:MaoGirl // 这是一个属于MaoGirl(罗莎)的节点,决定了在角色卡片上会出现谁
---
MaoGirl: 哟,你好呀。
===
基本上,所有的Live_Entry都要求在结束的时候,通过下面这条命令来返回 Live_Hub
<<jump Live_Hub>>从而让Live_Hub自循环,直到对话今天时间大于18点。
Chat_node 与 Aistalt_Night
直播结束后进入夜间聊天。
夜间的“其他联系人”也通过 GenerateNPCOption 生成角色选项,此时是Night_Entry。
ClockOut、Dream、EndDay
玩家下班后会经过 ClockOut 和 Dream。Dream 是预留的夜间自由行动节点。EndDay 会推进日期、清理大部分运行时状态,并重新进入 Initial。
变量约定
下面是项目中最常见的公共 Yarn 变量。Mod 应优先复用它们,不要为同一概念重复创建变量。
| 变量 | 用途 |
|---|---|
$ThePlayer | 玩家名称。 |
$player_compu | 玩家当前算力。 |
$Check_Result | 最近一次检定结果的临时寄存器。 |
$Attr | 复合检定中命中的属性临时寄存器。 |
$Today | 当前天数。 |
$CurrentMinute | 当前分钟。 |
$CurrentHour | 当前小时。 |
$LastSpokenCharacter | 最近通过连麦说话角色的 TechName。 |
$<角色>_Love | 角色好感值。 |
$<角色>_Hate | 角色敌意值。 |
$<角色>_Opinion | 通常等于好感减敌意。 |
$<角色>_Experience | 角色经历次数。 |
$<角色>_CState | 角色生命状态,常见约定是 1 存活、0 死亡、2 失踪。具体剧情可以有自己的约定。 |
$Topic_<TechName> | Topic 或技能相关变量,具体取决于系统和脚本。 |
标签
游戏中有大量的逻辑是通过标签来传达的。
行末状态标签
Aistalt: 这是一首悲伤的歌…… #state:Sad

这会请求角色动画系统应用 Sad 状态。详情请见d.美术一章。
打字过程中的状态标签
Aistalt: 这是一首悲伤的歌……[state value="Happy" /]但是好在,我们终归是得救了。#state:Sad这句话会在播放时,将状态切换为Sad,随后在打字机碰到内部标签时,切换为Happy。
人格标签
Aistalt: 这是同理的一句。#Empathy
Aistalt: 这是技术的一句。#Tech
Aistalt: 这是捣乱的一句。#Troll
Aistalt: 这是媚俗的一句。#Kitsch这是用来切人格的,就是你在游戏内看到的共情、技术等标签。
外语标签
Aistalt: [F="asf1r12f1231f"]不会被翻译的文本[/F]这些文本会首先在打字机内显示为:asf1r12f1231f,随后被自动翻译:不会被翻译的文本。
这通常是当你希望让某个外国角色,譬如哈妮Victim,或者阿尔娃Greta爆粗口时使用的。
文字样式
Aistalt: 另外,如发现任何[angry]故障协议[/angry],用[excite]右键[/excite]将其卸除。
这会导致这句话被渲染为特殊的样式。关于可用的文本样式,请参考可用的文本样式。
带检定的选项
-> 揍他一顿 #Check:Troll:20:Topic_Conflict这是一次难度为20的键政检定,且检定难度会被 冲突 技能减少。
格式大致是:
#Check:<属性>:<难度>:<可选Topic>可继续追加 Modify:
-> 揍他一顿 #Check:Troll:20:Topic_Literature #Modify:Variable:true:DiceNum:Modify_Text这个的意思就是,如果此处配置的Variable为真,那么就会为这次检定增补DiceNum个骰子,并且在检定的确认界面上,会显示Modify_Text的文本。
选项结果标识
-> 好厉害哦 #Heat这类特殊表示会提示在点击这个选项后,可能产生的结果。具体请见 可用的结果标识。

左上角这个就是检定,右上角这个就是结果标识。
脚本精读
我们选择了一个对话,来进行精读。这应该会有助于您建立对脚本的初步认识。另外,游戏内目前大部分的脚本都是正常工作的,也可以作为参考。
c. 脚本精读