数据
常量、类型转换、类型判断,以及构成一张图所需的全部字符串、数组、对象和 JSON 操作
Data 承载蓝图参与运算的值。需要一个常量、值的类型不对,或者要拆解字符串、数组、JSON 文档时,都用它。这里几乎没有节点带执行引脚——Data 节点由连到它输出端的一方读取。Memo 是唯一的例外,它在本页末尾自己解释
值类型
下面的引脚上出现以下类型。卡片、类型选择器、变量与消息中显示的是界面名称,括号中是类型 id,即文档的引脚表、命令行工具与项目文件中的写法
| 类型 | 内容 | 产出方 |
|---|---|---|
字符串(string) | 文本 | String,以及所有字符串节点 |
整数(integer) | 不带小数的数 | Integer,以及各类长度、下标、计数 |
数字(float) | 可带小数的数 | Float、To Float、Parse Float |
布尔值(boolean) | 真或假 | Boolean,以及所有类型判断和字符串判断 |
JSON(json) | 任意 JSON 值:object、array、string、number、boolean 或null | JSON、Parse JSON、Get JSON Field、Make Object |
列表(array) | JSON 数组,但作为独立类型存在 | Make Array、返回数组的那些Array …节点、Object Values |
某类型的列表(array<T>) | 各项类型都为T的数组。卡片上显示为该类型的列表,例如结局列表、字符串列表 | Get Endings、Get History、Split、Object Keys、Array Range |
结构的名称(struct:<id>) | 字段已声明的对象,例如结局、存档条目。卡片上显示结构的名称,例如结局。见结构 | 作用于结局的Array First、List 的Item Click、遍历结局的For Each |
任意值(any) | 任意值 | Memo,以及类型随卡片上所选内容而定的引脚,例如Get Field、Get Var,在选定之前 |
颜色(RGBAColor) | { r, g, b, a } | Color |
二维向量(Vector2D) | { x, y } | Vector2D、Make Vector2D、Rect Center、Get Center |
矩形(Rect) | { x, y, width, height } | Rect、Make Rect、Get Bounds、Get Measured Rect |
其他分类的引脚上还有以下类型:
| 类型 | 内容 | 见 |
|---|---|---|
元素(element)、按钮元素(element:nl.button)等 | 界面上的一个元素。限定了控件类型时,名称为控件名加「元素」 | Element |
图片(ImageAsset、ImageAsset|null) | 一个图片资产;可空形式也可以为空 | Image |
计时器(Timer) | Delay给出的令牌 | Flow |
动画(AnimationToken) | Animate Property给出的令牌 | Displayable |
声音(SoundHandle) | Play Sound播放的片段 | Sound |
响应(ResponseBody) | Fetch取回的响应 | Network |
存档槽(SaveSlot) | 一份存档 | Game |
两个数据引脚之间的连线,在类型完全相同时成立;此外还有以下几种:
| 来源 | 目标 | 原因 |
|---|---|---|
integer | float | 整数一定是浮点数 |
integer、float | string | 读取该输入时数字会被转成文本。这是唯一会改写值的隐式转换——其余允许的连线都原样传递 |
array | json | 数组本身就是一个 JSON 值 |
array<T> | array、json | 各项类型已知的数组仍是数组 |
array<T> | array<U> | T能接到U时 |
struct:<id> | json | 结构就是一个 JSON 对象 |
struct:<id> | 另一个结构 | 两者字段相同、顺序相同、类型相同时 |
Rect | json | 一条为旧图留的兼容口子,而不是关于结构化类型的规则——见下 |
any | 任意类型 | any在两个方向上都匹配 |
| 任意类型 | any |
其它分类的类型也只在同样的地方放宽:element能接到任意element:nl.…引脚上、也能反过来,element类引脚与any则在两个方向上都接不上;ImageAsset与string都能接进ImageAsset|null输入
其余一律拒绝,包括那些作者以为能反过来用的:
json→array、json→Rect。 每一条放宽规则都只单向成立。一个任意对象并不是一个矩形json→ 结构。 字段未声明的对象(例如Parse JSON的结果)不能接到Get Field上,请用Get JSON Field读取float→integer。 插一个To Integer,它向零截断string→integer或float。 插Parse Int、Parse Float、To Integer或To Floatboolean→string、json→string。 只有数字会隐式转成文本。插To String或Stringify JSONstring、integer、float、boolean→json。 只有array和Rect能隐式接进json输入。插To JSONRGBAColor→json、Vector2D→json。 它们是各自独立的结构化类型,不是 JSON 文档。要拆开就用Break Vector2D,要造文档就用Make Object
Rect → json 是给 Rect 成为独立类型之前写下的图留的。那时 Rect 常量和 Get Bounds 发布的都是 json,所以当年写下的矩形至今仍能接进 Get JSON Field 并继续工作。Vector2D 从来就不是 json 引脚,因此保持窄口
array能接进json输入,反过来永远不行。一个恰好装着数组的json值(Parse JSON、Get JSON Field)不能接到Array Length或 List 的Set List Content这类array输入上。Flow里的For Each收json,所以遍历仍然可行;Array …节点则不行
array<T>和结构类型决定哪些引脚能相连、卡片上提供哪些选项,不改变值本身:游戏运行时,结局仍是同一个对象。早期版本的图中原本成立的连线仍然成立
约定
- 这里除一个之外都是纯节点。 没有执行引脚可连,所以 Data 节点不可能落在执行线路上。它的输出在下游读取时才计算,下一次读取时重新计算。
Memo是例外:它是执行节点,因为把一个值按住不动恰恰是纯节点做不到的事 - Blueprint Value 图接受它们全部,
Memo也在内 - 不存在原地修改。 写入类节点在输出引脚上给出一个新值,输入原封不动
- 只有
string、integer、float、boolean引脚支持卡片内联输入。json和array输入没有卡片编辑器,请接一个JSON常量或Make Object/Make Array节点 - 输入未连线不算错误。 它读取该引脚的卡片内联值,没有内联值时读到空;各节点自行归一:缺失的数组读作空数组,缺失的字符串读作
"",缺失的数字读作0 - 一条纯节点链最多解析 32 层。 超过之后读取静默地什么都取不到
- 部分节点在创建浮窗中按组列出。 浏览创建浮窗时,以下每组合为一行:常量中从
String到Rect的节点(字面量),转换中从To String到To JSON的节点(转换类型),类型判断中从Is String到Is Null的节点(判断类型),Trim、Trim Start和Trim End(去除空白),To Upper Case、To Lower Case和Capitalize(转换大小写),Replace和Replace All(替换文本),以及Pad Start和Pad End(填充文本)。搜索时每个节点按自己的名称列出;已放置的卡片可用标题旁的 ▾ 切换为同组的其他节点。见同类节点
Array Push、Set JSON Field、Remove JSON Field,以及本页所有写入类节点,交给你的都是一个新值,输入保持不动。只把Get Var → Array Push连起来什么也不会发生——你必须把结果再连回Set Var。参见 变量
常量
常量节点有一个输出引脚和一个卡片字段。类型由你选的节点固定下来,图的其余部分才因此能做类型检查
String
blueprint.data.stringLiteral · Pure
String(字符串)常量
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
value | out · data | string |
卡片字段
| 字段 | 含义 |
|---|---|
value | 文本内容 |
Integer
blueprint.data.integerLiteral · Pure
Integer(整数)常量
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
value | out · data | integer |
卡片字段
| 字段 | 含义 |
|---|---|
value | 一个数字。读取时截断为整数 |
Float
blueprint.data.floatLiteral · Pure
Float(浮点数)常量
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
value | out · data | float |
卡片字段
| 字段 | 含义 |
|---|---|
value | 一个数字。非有限值读作0 |
Boolean
blueprint.data.booleanLiteral · Pure
Boolean(布尔值)常量
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
value | out · data | boolean |
卡片字段
| 字段 | 含义 |
|---|---|
value | True / False 下拉框 |
Null
blueprint.data.nullLiteral · Pure
Null(空值)是唯一没有卡片字段的常量——null没有什么可配置的。它的输出类型是json,因此能接到任何json或any输入
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
value | out · data | json | 恒为null |
JSON
blueprint.data.jsonLiteral · Pure
卡片显示根类型和摘要;编辑时打开树形表单,object 用命名字段,array 用顺序条目。新建节点是一个空 object
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
value | out · data | json |
卡片字段
| 字段 | 含义 |
|---|---|
value | 以树形方式编辑的文档。写入的一切都是 JSON-safe 值 |
Color
blueprint.data.colorLiteral · Pure
Color(颜色)用颜色选择器编辑,并以 8 位 RGBA hex 显示。输出永远是归一化后的{ r, g, b, a }记录——r、g、b为字节,a取值0到1
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
value | out · data | RGBAColor |
卡片字段
| 字段 | 含义 |
|---|---|
value | 颜色选择器 |
Vector2D
blueprint.data.vector2dLiteral · Pure
Vector2D(二维向量)常量
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
value | out · data | Vector2D |
卡片字段
| 字段 | 含义 |
|---|---|
value | 固定的x / y数值 schema。额外字段会被拒绝;缺失或非数字的字段读作0 |
Rect
blueprint.data.rectLiteral · Pure
和Color、Vector2D一样,Rect(矩形)是一个独立类型。与它们不同的是,它还能放宽成json,因此仍能接到任何json输入——理由见本页开头“值类型”一节
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
value | out · data | Rect |
卡片字段
| 字段 | 含义 |
|---|---|
value | 固定的x / y / width / height数值 schema,校验规则与Vector2D相同 |
Number
blueprint.data.numberLiteral · Pure
Number(数字)是旧版数字常量,已从创建浮窗隐藏,无法加进新图。它仍然注册着,好让旧图继续解析。请用Float
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
value | out · data | float |
卡片字段
| 字段 | 含义 |
|---|---|
value | 一个数字 |
Literal
blueprint.data.literal · Pure
Literal(字面量)是旧版无类型常量,同样从创建浮窗隐藏。它的any输出能通过任何类型检查——这恰恰是它被那些带类型的常量取代的原因
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
value | out · data | any |
卡片字段
| 字段 | 含义 |
|---|---|
value | 一个无类型的值 |
转换
连接规则会把你引向这几个节点。它们都不会失败:读不出来的输入产出该类型的零值,而不是报错
To String
blueprint.string.toString · Pure
To String(转为字符串):null和未连线的输入都读作""。object 和 array 会被序列化为 JSON 文本
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
value | in · data | any | |
result | out · data | string |
To Integer
blueprint.data.toInteger · Pure
To Integer(转为整数)向零截断——-2.7得到-2而不是-3。true读作1,false读作0,数字字符串可以接受,其余一律得到0
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
value | in · data | any | |
result | out · data | integer |
To Float
blueprint.data.toFloat · Pure
接受范围与To Integer相同,只是不截断。非有限数字得到0
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
value | in · data | any | |
result | out · data | float |
To Boolean
blueprint.data.toBoolean · Pure
字符串在去除首尾空白并转小写后匹配:""、"false"、"0"、"no"为假;"true"、"1"、"yes"为真;其他非空字符串一律为真。0和非有限数字为假
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
value | in · data | any | |
result | out · data | boolean |
To JSON
blueprint.data.toJson · Pure
字符串会尝试按 JSON 解析,解析不了就保留原字符串——所以这个节点绝不会毁掉文本。其他值会被转成 JSON-safe 值:非有限数字和循环引用变成null,函数和 symbol 变成它们的文本形式
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
value | in · data | any | |
result | out · data | json |
Parse Int
blueprint.data.parseInt · Pure
固定十进制,取开头的数字——"12px"得到12。一个数字都没有则得到0
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
value | in · data | string | 可在卡片上内联输入 |
result | out · data | integer |
Parse Float
blueprint.data.parseFloat · Pure
Parse Float(解析浮点数)
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
value | in · data | string | 可在卡片上内联输入 |
result | out · data | float |
Parse JSON
blueprint.data.parseJson · Pure
严格解析:解析不了的文本和空字符串都得到null。想保留原文本时改用To JSON
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
value | in · data | string | 可在卡片上内联输入 |
result | out · data | json |
Stringify JSON
blueprint.data.stringifyJson · Pure
未连线的输入得到文本"null"。无法序列化的值得到""
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
value | in · data | json | |
result | out · data | string |
类型判断
每个都接收any,回答关于实际到达的那个值的一个问题——这就是你弄清json或any引脚里究竟装着什么的办法
Is String
blueprint.data.isString · Pure
Is String(是否为字符串)
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
value | in · data | any | |
result | out · data | boolean |
Is Number
blueprint.data.isNumber · Pure
只认有限数字——NaN和无穷都为假,数字字符串也为假。它问的是类型,不是能不能解析
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
value | in · data | any | |
result | out · data | boolean |
Is Boolean
blueprint.data.isBoolean · Pure
Is Boolean(是否为布尔值)
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
value | in · data | any | |
result | out · data | boolean |
Is Array
blueprint.data.isArray · Pure
Is Array(是否为数组)
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
value | in · data | any | |
result | out · data | boolean |
Is Object
blueprint.data.isObject · Pure
非 null 且不是数组的 object 才为真。数组归Is Array回答,不归它
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
value | in · data | any | |
result | out · data | boolean |
Is Null
blueprint.data.isNull · Pure
对null为真,对解析不出结果的输入也为真——未连线的引脚在这里读作 null
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
value | in · data | any | |
result | out · data | boolean |
Not Null
blueprint.data.notNull · Pure
Is Null的取反,省得你再挂一个Not
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
value | in · data | any | |
result | out · data | boolean |
Is Empty Value
blueprint.data.isEmptyValue · Pure
对null、""、空数组和空 object 为真。0和false是值而不是空,两者都为假
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
value | in · data | any | |
result | out · data | boolean |
字符串
这里每个value输入都能在卡片上内联输入,所以一次性的字符串不必单独放一个常量节点。下标从 0 开始,越界的下标会被夹取而不是拒绝
Concat
blueprint.string.concat · Pure
Concat(拼接)按引脚顺序把输入首尾相接,中间不加任何内容。卡片上有添加输入的控件:在a和b之外可以继续追加string输入,下面的签名只列出它初始自带的两个
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
a | in · data | string | 可在卡片上内联输入 |
b | in · data | string | 可在卡片上内联输入 |
result | out · data | string |
Format
blueprint.string.format · Pure
把模板中的{name}替换为values里的同名字段;values是数组时用{0}、{1}……。匹配不到的占位符变成空;values既不是 object 也不是 array 时,所有占位符都变成空
Format 是创建浮窗中唯一的格式化节点,可用于 Blueprint Value 与函数。要使用玩家语言中的模板,把 Translation Key Text 接到 template
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
template | in · data | string | 可在卡片上内联输入 |
values | in · data | json | 接一个JSON常量、Make Object,或为 {0}、{1}……接Make Array |
result | out · data | string |
Length
blueprint.string.length · Pure
Length(长度)
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
value | in · data | string | 可在卡片上内联输入 |
length | out · data | integer |
Is Empty
blueprint.string.isEmpty · Pure
长度为 0。全是空格的字符串不算空——那是Is Blank
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
value | in · data | string | 可在卡片上内联输入 |
result | out · data | boolean |
Is Blank
blueprint.string.isBlank · Pure
为空,或只包含空白字符
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
value | in · data | string | 可在卡片上内联输入 |
result | out · data | boolean |
Trim
blueprint.string.trim · Pure
Trim(去除首尾空白)
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
value | in · data | string | 可在卡片上内联输入 |
result | out · data | string |
Trim Start
blueprint.string.trimStart · Pure
Trim Start(去除首部空白)
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
value | in · data | string | 可在卡片上内联输入 |
result | out · data | string |
Trim End
blueprint.string.trimEnd · Pure
Trim End(去除尾部空白)
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
value | in · data | string | 可在卡片上内联输入 |
result | out · data | string |
To Upper Case
blueprint.string.toUpperCase · Pure
To Upper Case(转为大写)
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
value | in · data | string | 可在卡片上内联输入 |
result | out · data | string |
To Lower Case
blueprint.string.toLowerCase · Pure
To Lower Case(转为小写)
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
value | in · data | string | 可在卡片上内联输入 |
result | out · data | string |
Capitalize
blueprint.string.capitalize · Pure
只把第一个字符转成大写,其余原样保留——这不是标题式大小写
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
value | in · data | string | 可在卡片上内联输入 |
result | out · data | string |
Equals
blueprint.string.equals · Pure
Equals(相等)
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
a | in · data | string | 可在卡片上内联输入 |
b | in · data | string | 可在卡片上内联输入 |
result | out · data | boolean |
Equals Ignore Case
blueprint.string.equalsIgnoreCase · Pure
Equals Ignore Case(相等,忽略大小写)
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
a | in · data | string | 可在卡片上内联输入 |
b | in · data | string | 可在卡片上内联输入 |
result | out · data | boolean |
Contains
blueprint.string.contains · Pure
Contains(包含)
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
value | in · data | string | 可在卡片上内联输入 |
search | in · data | string | 可在卡片上内联输入 |
result | out · data | boolean |
Starts With
blueprint.string.startsWith · Pure
Starts With(以……开头)
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
value | in · data | string | 可在卡片上内联输入 |
search | in · data | string | 可在卡片上内联输入 |
result | out · data | boolean |
Ends With
blueprint.string.endsWith · Pure
Ends With(以……结尾)
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
value | in · data | string | 可在卡片上内联输入 |
search | in · data | string | 可在卡片上内联输入 |
result | out · data | boolean |
Index Of
blueprint.string.indexOf · Pure
从start向后查找,找不到给出-1。start会被夹进字符串范围,所以越界的值只是从头或从尾开始找,而不会失败
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
value | in · data | string | 可在卡片上内联输入 |
search | in · data | string | 可在卡片上内联输入 |
start | in · data | integer | 可在卡片上内联输入。默认为0 |
index | out · data | integer |
Last Index Of
blueprint.string.lastIndexOf · Pure
从末尾向前查找。没有start引脚——这是它与Index Of唯一不对称的地方
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
value | in · data | string | 可在卡片上内联输入 |
search | in · data | string | 可在卡片上内联输入 |
index | out · data | integer |
Count
blueprint.string.count · Pure
统计不重叠的出现次数。search为空时给出0,而不是字符串长度
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
value | in · data | string | 可在卡片上内联输入 |
search | in · data | string | 可在卡片上内联输入 |
count | out · data | integer |
Char At
blueprint.string.charAt · Pure
下标落在字符串之外时给出"",而不是报错
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
value | in · data | string | 可在卡片上内联输入 |
index | in · data | integer | 可在卡片上内联输入 |
char | out · data | string |
Substring
blueprint.string.substring · Pure
第二个引脚是长度,不是结束下标。两者都会被夹进字符串范围;length未连线时取从start起的全部剩余内容
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
value | in · data | string | 可在卡片上内联输入 |
start | in · data | integer | 可在卡片上内联输入 |
length | in · data | integer | 可在卡片上内联输入 |
result | out · data | string |
Insert
blueprint.string.insert · Pure
index会被夹进字符串范围;读不出下标时追加到末尾
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
value | in · data | string | 可在卡片上内联输入 |
index | in · data | integer | 可在卡片上内联输入 |
insert | in · data | string | 可在卡片上内联输入 |
result | out · data | string |
Replace
blueprint.string.replace · Pure
只替换第一处。search为空时原样返回,而不是在每个位置插入
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
value | in · data | string | 可在卡片上内联输入 |
search | in · data | string | 可在卡片上内联输入 |
replacement | in · data | string | 可在卡片上内联输入 |
result | out · data | string |
Replace All
blueprint.string.replaceAll · Pure
替换全部。search是纯文本而不是正则;同样,search为空时原样返回
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
value | in · data | string | 可在卡片上内联输入 |
search | in · data | string | 可在卡片上内联输入 |
replacement | in · data | string | 可在卡片上内联输入 |
result | out · data | string |
Repeat
blueprint.string.repeat · Pure
count被夹到0–10000,所以失控的数字不会撑出一个无界的字符串
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
value | in · data | string | 可在卡片上内联输入 |
count | in · data | integer | 可在卡片上内联输入 |
result | out · data | string |
Pad Start
blueprint.string.padStart · Pure
length是补齐后的目标总长度,不是要补的字符数。已经够长的字符串原样返回
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
value | in · data | string | 可在卡片上内联输入 |
length | in · data | integer | 可在卡片上内联输入 |
pad | in · data | string | 可在卡片上内联输入 |
result | out · data | string |
Pad End
blueprint.string.padEnd · Pure
Pad End(尾部填充)
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
value | in · data | string | 可在卡片上内联输入 |
length | in · data | integer | 可在卡片上内联输入 |
pad | in · data | string | 可在卡片上内联输入 |
result | out · data | string |
Split
blueprint.string.split · Pure
结果是字符串数组,能接到Array …节点,也能接到Join、For Each和其他任何json输入
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
value | in · data | string | 可在卡片上内联输入 |
separator | in · data | string | 可在卡片上内联输入 |
result | out · data | array<string> |
Join
blueprint.string.join · Pure
它收json,而Array Join收array。values不是数组时给出""
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
values | in · data | json | |
separator | in · data | string | 可在卡片上内联输入 |
result | out · data | string |
Matches Regex
blueprint.string.matchesRegex · Pure
pattern是正则表达式本体,不带分隔符也不带 flag。编译不了的表达式给出false,而不是抛错
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
value | in · data | string | 可在卡片上内联输入 |
pattern | in · data | string | 可在卡片上内联输入 |
result | out · data | boolean |
Extract Regex
blueprint.string.extractRegex · Pure
表达式带捕获组时返回第一个捕获组,否则返回整段匹配。没有匹配,或表达式编译不了,都给出""
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
value | in · data | string | 可在卡片上内联输入 |
pattern | in · data | string | 可在卡片上内联输入 |
result | out · data | string |
Normalize Line Breaks
blueprint.string.normalizeLineBreaks · Pure
把\r\n和单独的\r改写为\n,这样来自任何平台的文本在比较和分割时表现一致
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
value | in · data | string | 可在卡片上内联输入 |
result | out · data | string |
数组
这里每个节点都把array输入当数组读,不是数组时替换为空数组,所以不会抛错。每个写入类节点都在result上返回一个新数组
各项类型已知时(例如Get Endings给出的结局),返回数组的节点返回同一类型,Array Get、Array First、Array Last和Array Find By Key返回该类型的一项:对结局使用Array Filter By Key得到结局,Array First得到一个结局。Array Concat取a的类型
Array Length
blueprint.collection.arrayLength · Pure
Array Length(数组长度)
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
array | in · data | array | |
length | out · data | integer |
Array Get
blueprint.collection.arrayGet · Pure
下标为负或越过末尾时给出null。输出类型是json,因为数组的一项可以是任何 JSON 值;各项类型已知时,输出取该类型
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
array | in · data | array | |
index | in · data | integer | 可在卡片上内联输入 |
item | out · data | json |
Array Set
blueprint.collection.arraySet · Pure
在index处写入并返回新数组。下标为负或大于10000时原样返回输入;下标越过末尾会把数组撑长,中间跳过的位置留空
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
array | in · data | array | |
index | in · data | integer | 可在卡片上内联输入 |
item | in · data | any | |
result | out · data | array |
Array Push
blueprint.collection.arrayPush · Pure
追加到末尾
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
array | in · data | array | |
item | in · data | any | |
result | out · data | array |
Array Insert
blueprint.collection.arrayInsert · Pure
index被夹到0–长度之间,所以越界的下标只会变成追加,而不会失败
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
array | in · data | array | |
index | in · data | integer | 可在卡片上内联输入 |
item | in · data | any | |
result | out · data | array |
Array Remove
blueprint.collection.arrayRemove · Pure
移除第一个与item相等的项,比较方式与 Equal 相同:两个字段相同的 object 会判定为相等,尽管它们并非同一个对象。没有匹配时原样返回输入
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
array | in · data | array | |
item | in · data | any | |
result | out · data | array |
Array Remove At
blueprint.collection.arrayRemoveAt · Pure
移除一项并把后面的补上。下标越界时原样返回输入
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
array | in · data | array | |
index | in · data | integer | 可在卡片上内联输入 |
result | out · data | array |
Array Contains
blueprint.collection.arrayContains · Pure
有一项与item相等时为真。比较方式与 Equal 相同,与Array Remove同一套规则
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
array | in · data | array | |
item | in · data | any | |
result | out · data | boolean |
Array Slice
blueprint.collection.arraySlice · Pure
end不含在内。两端都被夹进数组范围;end未连线时一直取到末尾
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
array | in · data | array | |
start | in · data | integer | 可在卡片上内联输入 |
end | in · data | integer | 可在卡片上内联输入 |
result | out · data | array |
Array Join
blueprint.collection.arrayJoin · Pure
把每一项转成文本——object 和 array 转成 JSON——再连接起来。它收array,而字符串的Join收json
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
array | in · data | array | |
separator | in · data | string | 可在卡片上内联输入 |
result | out · data | string |
Array First
blueprint.collection.arrayFirst · Pure
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
array | in · data | array | |
item | out · data | json | 空数组时为 null |
Array Last
blueprint.collection.arrayLast · Pure
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
array | in · data | array | |
item | out · data | json | 空数组时为 null |
Array Is Empty
blueprint.collection.arrayIsEmpty · Pure
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
array | in · data | array | |
result | out · data | boolean |
Array Index Of
blueprint.collection.arrayIndexOf · Pure
第一个与 item 相等的项的位置,按值比较,与 Array Contains 用的是同一套。没有命中时为 -1
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
array | in · data | array | |
item | in · data | any | |
index | out · data | integer |
Array Concat
blueprint.collection.arrayConcat · Pure
a 接上 b,返回一个新数组
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
a | in · data | array | |
b | in · data | array | |
result | out · data | array |
Array Reverse
blueprint.collection.arrayReverse · Pure
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
array | in · data | array | |
result | out · data | array |
Array Unique
blueprint.collection.arrayUnique · Pure
丢掉后出现的重复项,保留每一种的第一个。比较方式与Equal相同,所以字段相同的两个对象算作同一项
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
array | in · data | array | |
result | out · data | array |
Array Range
blueprint.collection.arrayRange · Pure
从 start 开始的 count 个数字,每个比前一个多 step。当一页要画 N 个东西、而那些数字本身就是内容时,需要的就是这个数组
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
start | in · data | integer | 可填字面量。默认 0 |
count | in · data | integer | 可填字面量。会被夹到 0–10000 |
step | in · data | integer | 可填字面量。默认 1;step 为 0 时按 1 读——否则那会是 count 份 start,一个披着 range 外形却永远不前进的循环 |
result | out · data | array<integer> |
Array Find By Key
blueprint.collection.arrayFind · Pure
第一个 key 字段等于 value 的项,以及它在哪里。比较方式与Equal相同
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
array | in · data | array | |
key | in · data | string | 字段名。可填字面量。各项类型已知时,为各项字段的下拉列表 |
value | in · data | any | 类型随key所指字段而定;字段为字符串、数字或布尔值时可在卡片上填写 |
item | out · data | json | 没有命中时为 null。数组各项类型已知时,为该类型的一项 |
index | out · data | integer | 没有命中时为 -1 |
Array Filter By Key
blueprint.collection.arrayFilter · Pure
所有 key 字段等于 value 的项,保持原有顺序。比较方式与Equal相同
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
array | in · data | array | |
key | in · data | string | 可填字面量。各项类型已知时,为各项字段的下拉列表 |
value | in · data | any | 类型随key所指字段而定;字段为字符串、数字或布尔值时可在卡片上填写 |
result | out · data | array | 与array类型相同 |
Array Sort By Key
blueprint.collection.arraySort · Pure
按记录的某个字段排序。这三个按键节点收的是字段名而不是比较函数,因为比较函数是一个函数值,而按记录的某个字段排序才是列表真正需要的东西。
数字按数字比,布尔按 false 在前、true 在后比,其余按文本比,用运行时排列字符串的那套次序。字段缺失、为 null 或为 "" 的项在两个方向上都排到最后,相持时保持原有先后。key 为空时原样返回
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
array | in · data | array | |
key | in · data | string | 可填字面量。各项类型已知时,为各项字段的下拉列表 |
descending | in · data | boolean | 可填字面量 |
result | out · data | array | 与array类型相同 |
JSON Array Length
blueprint.data.jsonArrayLength · Pure
Array Length的旧名字,在创建浮窗中隐藏,保留下来让已有的图继续解析。输入不是数组时给出0。新图请用Array Length
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
value | in · data | array | |
length | out · data | integer |
结构
结构是字段已声明的对象:结局、历史记录条目、存档条目、画廊条目,或 List 的一行。携带结构的引脚在卡片上显示结构的名称,例如结局;携带结构数组的引脚显示结局列表。Get Field(获取字段)读取其中一个字段,字段从下拉列表中选择
| 结构 | 字段 | 给出该结构的节点 |
|---|---|---|
| 结局 | endingId、name、sceneId、sceneName、isReached | Get Endings |
| 历史记录条目 | id、type、text、character、avatar、voice、voiceId、selected、isPending | Get History、Get Future History |
| 存档条目 | id、slot、timestamp、createdAt、preview、line、speaker、metadata | List Auto Saves |
| 通知 | id、message | Get Notifications |
| 语言 | code、displayName、isSource | Get Available Languages |
| 语音语言 | code、displayName | Get Available Voice Languages |
| 选项 | text、index、disabled、voiceId | 游戏 UI 中选项列表的行 |
| NVL 行 | index、nametag、isActive | 游戏 UI 中 NVL 列表的行 |
| 确认按钮 | id、text、index、disabled | Show Confirm 打开页面时传入的按钮 |
各字段的含义写在给出该结构的节点下。插件可以声明自己的节点给出的结构,例如画廊插件的画廊条目,见清单。List 的行采用编辑内容中设置的结构,可以是上表中的结构,也可以是为该 List 填写的字段,见列表
- 类型沿连线传递。 数组节点把项的类型传下去,见数组。Flow 中的
For Each给出所遍历数组的一项。List 节点和条目事件头给出、接收该 List 结构的行,见 List - 字段的类型就是引脚的类型。 字符串字段为
string,数字为float,布尔值为boolean,图片为ImageAsset|null,颜色为RGBAColor,JSON 为json - 从结构上拖出连线。 从携带结构的引脚拖出连线并在画布空白处松开,添加节点菜单会打开在字段分组,列出获取每个字段的条目,例如获取 isReached、获取 name。从携带结构数组的引脚拖出时,列出按每个字段筛选、排序、查找的条目,例如按 isReached 筛选。每个条目添加的节点已选好该字段,并与该引脚相连。对布尔字段筛选或查找时,比较的值为真
- 结构中没有的字段会被报告。
Get Field选择了结构中没有的字段,或Array Filter By Key、Array Sort By Key、Array Find By Key的key不是各项的字段时,画布上显示警告,项目检查报告字段不存在(blueprint/field-missing)。这样的节点读不到值:Get Field得到空值,筛选不保留任何项,排序不改变顺序。删除 List 的字段或手动填写键之后会出现这种情况。只检查结构已知的节点
Get Field
blueprint.list.getItemField · Pure
读取结构中的一个字段。把结构连到对象,在字段中选择字段。输出取该字段的类型,因此结局的isReached可以直接连到Branch
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
object | in · data | struct:* | 任意结构,显示为结构。在 List 的行中可以不连接 |
value | out · data | any | 取所选字段的类型。值中没有该字段时为null |
卡片字段
| 字段 | 说明 |
|---|---|
Field | 要读取的字段,从连到对象的结构的字段中选择。结构中已不存在的字段仍留在列表中,显示为字段“…”已缺失 |
- 保留第一次连入的结构。 此后对象只接受该结构,连线断开后也一样。要读取其他结构,请另加一个
Get Field - 在 List 的行中,对象可以不连接。 此时节点读取正在绘制的那一行,卡片显示对象 · 当前行。可以读到行的位置与 List 中所列相同:List 项模板中元素的蓝图、List 自己的条目事件头,以及组件定义
- 在其他位置不连接时,读不到值。 卡片报告对象未连接。保留了结构、连线已断开的
Get Field也读不到值,不会改为读取当前行 - 字段未声明的对象接不上,请用
Get JSON Field读取
该节点原名获取条目字段(Get Item Field),只能读取 List 的行。类型 id 没有变化,已有的图仍保留该节点,在行中未连接的节点照旧读取当前行
几何
Vector2D 与 Rect 是结构化类型而不是 JSON 文档,因此要用它们自己的节点来构造和拆解,而不是 Get JSON Field。每个输入收到非数字都读作 0
Make Vector2D
blueprint.data.makeVector2d · Pure
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
x | in · data | float | 可填字面量 |
y | in · data | float | 可填字面量 |
value | out · data | Vector2D |
与 Vector2D 常量不同,两个分量都可以连线——当那个点是算出来的时候,Move Mouse To 要的就是这个
Break Vector2D
blueprint.data.breakVector2d · Pure
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
value | in · data | Vector2D | |
x | out · data | float | |
y | out · data | float |
Make Rect
blueprint.data.makeRect · Pure
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
x | in · data | float | 可填字面量 |
y | in · data | float | 可填字面量 |
width | in · data | float | 可填字面量 |
height | in · data | float | 可填字面量 |
value | out · data | Rect |
负的 width 或 height 会被归一而不是保留:原点移过去、边长取正,于是你拿到的就是你画出来的那个矩形
Break Rect
blueprint.data.breakRect · Pure
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
value | in · data | Rect | |
x | out · data | float | |
y | out · data | float | |
width | out · data | float | |
height | out · data | float |
Rect Center
blueprint.data.rectCenter · Pure
到矩形四条边等距的那个点
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
value | in · data | Rect | |
center | out · data | Vector2D |
对象
Object Keys 与 Object Values 读取对象的顶层,Object Merge 合并两个对象。写入或删除字段请用下方 JSON 一节的 Set JSON Field 或 Remove JSON Field,它们接受路径。不是 object 的输入按{}读取
Object Keys
blueprint.collection.objectKeys · Pure
按插入顺序给出字段名。数组或其他任何非 object 都给出空数组
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
object | in · data | json | |
result | out · data | array<string> |
Object Values
blueprint.collection.objectValues · Pure
Object Values(对象值)
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
object | in · data | json | |
result | out · data | array |
Object Set Field
blueprint.collection.objectSetField · Pure
已由Set JSON Field取代,它接受路径,因此也能写到嵌套字段;在创建浮窗中隐藏,但已有该节点的图仍能运行。field是一个纯粹的名字,其中的点是名字的一部分而不是路径分隔。名字为空时原样返回那份副本
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
object | in · data | json | |
field | in · data | string | 可在卡片上内联输入 |
value | in · data | any | |
result | out · data | json |
Object Remove Field
blueprint.collection.objectRemoveField · Pure
Object Remove Field(对象移除字段)已由Remove JSON Field取代;在创建浮窗中隐藏,但已有该节点的图仍能运行
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
object | in · data | json | |
field | in · data | string | 可在卡片上内联输入 |
result | out · data | json |
Object Merge
blueprint.collection.objectMerge · Pure
浅合并;同名字段以b为准。嵌套 object 是整体替换而不是继续合并。Merge JSON Object是同一个操作的另一个类型 id
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
a | in · data | json | |
b | in · data | json | |
result | out · data | json |
JSON
路径类节点用点标记定位文档:user.profile.name,数组下标用数字段,items.0。键名里的字面点用\.转义。空路径表示整个文档,所以不填路径的Set JSON Field会把文档整体替换掉
Get JSON Field
blueprint.data.jsonGet · Pure
路径不存在时给出null,所以「字段缺失」和「字段的值就是null」读出来一模一样。这两者需要区分时用Has JSON Field
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
json | in · data | json | |
path | in · data | string | 可在卡片上内联输入 |
result | out · data | json |
Has JSON Field
blueprint.data.jsonHas · Pure
判断的是存在性而不是真值:值为null的字段依然存在
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
json | in · data | json | |
path | in · data | string | 可在卡片上内联输入 |
result | out · data | boolean |
Set JSON Field
blueprint.data.jsonSet · Pure
复制输入,然后写进这份副本。路径上缺失的容器会被创建——下一段是数字就建数组,否则建 object——所以往一个空文档里写stats.hp会得到{ "stats": { "hp": … } }
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
json | in · data | json | |
path | in · data | string | 可在卡片上内联输入 |
value | in · data | any | 以 JSON-safe 形式写入 |
result | out · data | json |
Remove JSON Field
blueprint.data.jsonRemove · Pure
删除 object 字段,或把数组条目整个抽掉、后面的项依次前移。路径不存在时原样给回那份副本
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
json | in · data | json | |
path | in · data | string | 可在卡片上内联输入 |
result | out · data | json |
Make Object
blueprint.data.jsonMakeObject · Pure
由动态引脚对构造 object,所以下面的签名只有输出。卡片上每加一个字段就生成一个Name输入(string,可在卡片上内联输入)和一个Value输入(any);新建节点自带一对。字段名在运行时读取,因此接线的Name可以算出键名。名字为空、或与前面重复的字段会被跳过
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
result | out · data | json |
Make Array
blueprint.data.jsonMakeArray · Pure
按引脚顺序由动态Item输入构造数组,所以下面的签名只有输出。新建节点一个都没有——在卡片上添加。它是产出array类型的那个节点,因此也是把构造好的数组交给Array Length或 List 的Set List Content的办法
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
result | out · data | array |
Merge JSON Object
blueprint.data.jsonMergeObject · Pure
浅合并、b为准,与Object Merge完全一致。非 object 的输入按{}处理。已由Object Merge取代;在创建浮窗中隐藏,但已有该节点的图仍能运行
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
a | in · data | json | |
b | in · data | json | |
result | out · data | json |
Clone JSON
blueprint.data.jsonClone · Pure
一份 JSON-safe 深拷贝。写入类节点本来就会复制输入,所以只有当你要把同一份文档交给两条互不应看见对方修改的分支时才需要它
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
value | in · data | json | |
result | out · data | json |
把一个值按住
Memo
blueprint.data.memo
执行经过它时读一次输入,把那个值留在输出上,直到执行下一次经过。第一次经过之前,输出读作 null。这个值和蓝图的变量存在同一个 store 里:在 Init 里按住的值,之后的 Mouse Click 仍然读得到;宿主实例重新开始时,它也跟着重新开始。
它的输出可以喂给多个下游。算出来的数据输出只能接一个下游,从它再拉第二条连线会替换掉第一条,而且是两个不同的理由:纯节点每次被读都会重新求值,同一个 Random Float 读两次就是两个数字;执行节点的输出则属于产生它的那一次脉冲。Memo 只有一个写入方——它自己——所以每次读到的都是那次写入留下的东西,扇出去也不会让任何人意外。本页的常量节点、Element 绑定和 Fn 的参数引脚同样可以扇出,因为每次读到的都是同一个值。
| 引脚 | 方向 | 类型 | 说明 |
|---|---|---|---|
in | in · exec | — | |
value | in · data | any | 执行经过时读一次 |
next | out · exec | — | |
result | out · data | any | 卡片上标作 Value |
它是同步的而不是 latent,这是刻意的:这里没有什么可等的,而 latent 节点会被内联故事值挡在门外。