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. 脚本精读