NarraLeaf

Data

Literals, type conversion, type tests, and every string, array, object, and JSON operation a graph is built out of.

Data holds the values a blueprint computes with. Reach for it when you need a constant, when a value arrives as the wrong type, or when you have to take apart a string, an array, or a JSON document. Almost nothing here has an exec pin — a Data node is read by whoever is wired to its output. Memo is the one exception, and it explains itself below.

Value types

These valueTypes appear on the pins below.

valueTypeHoldsProduced by
stringText.String, every string node.
integerA whole number.Integer, lengths, indices, counts.
floatA number.Float, To Float, Parse Float.
booleanTrue or false.Boolean, every type test and string test.
jsonAny JSON value: object, array, string, number, boolean, or null.JSON, Parse JSON, Get JSON Field, Make Object.
arrayA JSON array, as a type of its own.Make Array, the Array … nodes that return an array, Object Values.
array<T>An array whose items are all of type T. The card shows it as a list of that type, such as Ending list or string list.Get Endings, Get History, Split, Object Keys, Array Range.
struct:<id>An object whose fields are declared, such as an ending or a save entry. The card shows the struct's name, such as Ending. See Structs.Array First on endings, Item Click on a List, For Each over endings.
anyAnything.Memo, and the pins whose type follows what is picked on the card, such as Get Field and Get Var, until something is picked.
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.

An edge between two data pins is allowed when the types are identical, or when one of these holds:

FromToWhy
integerfloatEvery integer is a float.
integer, floatstringThe number is converted to text as the input is read. This is the only coercion that rewrites the value — every other permitted edge passes it through untouched.
arrayjsonAn array is a JSON value.
array<T>array, jsonAn array of known items is still an array.
array<T>array<U>When a T connects to a U.
struct:<id>jsonA struct is a JSON object.
struct:<id>another structWhen both have the same fields, in the same order, with the same types.
RectjsonA migration allowance rather than a rule about structured values — see below.
anyanythingany matches in both directions.
anythingany

Types from other categories widen the same way and nowhere else: element connects to any element:nl.… pin and back, element pins do not connect to any in either direction, and ImageAsset and string both reach an ImageAsset|null input.

Everything else is refused, including the reverses authors expect to work:

  • json → array, json → Rect. Every widening rule runs one way only. An arbitrary object is not a rectangle.
  • json → a struct. An object whose fields are not declared, such as the result of Parse JSON, does not connect to Get Field. Read it with Get JSON Field.
  • float → integer. Insert To Integer, which truncates toward zero.
  • string → integer or float. Insert Parse Int, Parse Float, To Integer, or To Float.
  • boolean → string, json → string. Only numbers coerce to text. Insert To String or Stringify JSON.
  • string, integer, float, boolean → json. array and Rect are the only types that reach a json input implicitly. Insert To JSON.
  • RGBAColor → json, Vector2D → json. They are structured types of their own, not JSON documents. Take them apart with Break Vector2D, or build a document with Make Object.

Rect → json is there for graphs written before Rect was a type. The Rect literal and Get Bounds both published json until it became one, so rectangles authored back then still feed Get JSON Field and keep working. Vector2D never was a json pin and stays narrow.

array feeds a json input, never the reverse. A json value that happens to hold an array (Parse JSON, Get JSON Field) will not connect to an array input such as Array Length or List's Set List Content. For Each in Flow takes json, so iterating over it still works; the Array … nodes do not.

The array<T> and struct types decide what connects and what the card offers. They do not change the values: an ending is the same object when the game runs. A wire that connected in a graph from an earlier version still connects.

Conventions

  • Every node here is pure but one. There are no exec pins to connect, so a Data node cannot sit on the execution path. Its output is computed when a consumer reads it, and recomputed on the next read. Memo is the exception: it is an exec node, because holding a value still is exactly what a pure node cannot do.
  • A Blueprint Value graph accepts all of them, Memo included.
  • Nothing is modified in place. A node that writes returns a new value on its output pin and leaves its input alone.
  • On-card literals exist for string, integer, float, and boolean pins only. A json or array input has no on-card editor; feed it a JSON literal or a Make Object / Make Array node.
  • An unwired input is not an error. It reads the pin's on-card literal, or nothing when there is none, and each node normalizes: a missing array reads as empty, a missing string as "", a missing number as 0.
  • A chain of pure nodes resolves at most 32 links deep. Past that the read returns nothing, silently.
  • Some nodes are grouped into families. While the palette is browsed, each of these is one row: the literals from String to Rect (Literal), the conversions from To String to To JSON (Convert Type), the type tests from Is String to Is Null (Check Type), Trim, Trim Start and Trim End (Trim Whitespace), To Upper Case, To Lower Case and Capitalize (Change Case), Replace and Replace All (Replace Text), and Pad Start and Pad End (Pad Text). A search finds each node by its own name, and the ▾ beside a placed card's title switches it to another node of its family. See Node families.

Array Push, Set JSON Field, Remove JSON Field, and every other writer on this page hand you a new value and leave the input untouched. Wiring Get Var → Array Push changes nothing on its own — you have to wire the result back into Set Var. See Variables.

Literals

A literal has one output pin and an on-card field. Its type is fixed by the node you pick, which is what makes the rest of the graph type-check.

String

blueprint.data.stringLiteral · Pure

PinDirectionTypeNotes
valueout · datastring

On-card fields

FieldWhat
valueThe text.

Integer

blueprint.data.integerLiteral · Pure

PinDirectionTypeNotes
valueout · datainteger

On-card fields

FieldWhat
valueA number. Truncated to a whole number when read.

Float

blueprint.data.floatLiteral · Pure

PinDirectionTypeNotes
valueout · datafloat

On-card fields

FieldWhat
valueA number. A value that is not finite reads as 0.

Boolean

blueprint.data.booleanLiteral · Pure

PinDirectionTypeNotes
valueout · databoolean

On-card fields

FieldWhat
valueA True / False dropdown.

Null

blueprint.data.nullLiteral · Pure

The only literal with no on-card field — there is nothing to configure about null. Its output is typed json, so it reaches any json or any input.

PinDirectionTypeNotes
valueout · datajsonAlways null.

JSON

blueprint.data.jsonLiteral · Pure

The card shows the root type and a summary; editing opens a tree form with named fields for an object and ordered entries for an array. A new node starts as an empty object.

PinDirectionTypeNotes
valueout · datajson

On-card fields

FieldWhat
valueThe document, edited as a tree. Everything it writes is JSON-safe.

Color

blueprint.data.colorLiteral · Pure

Edited with a color picker and shown as 8-digit RGBA hex. The output is always the normalized { r, g, b, a } record — r, g, b as bytes, a from 0 to 1.

PinDirectionTypeNotes
valueout · dataRGBAColor

On-card fields

FieldWhat
valueA color picker.

Vector2D

blueprint.data.vector2dLiteral · Pure

PinDirectionTypeNotes
valueout · dataVector2D

On-card fields

FieldWhat
valueA fixed x / y number schema. Extra fields are rejected, and a field that is missing or not a number reads as 0.

Rect

blueprint.data.rectLiteral · Pure

Like Color and Vector2D, Rect is a type of its own. Unlike them, it also widens into json, so it still connects to any json input — see the note under Value types.

PinDirectionTypeNotes
valueout · dataRect

On-card fields

FieldWhat
valueA fixed x / y / width / height number schema, validated the same way as Vector2D.

Number

blueprint.data.numberLiteral · Pure

The legacy number constant, hidden from the palette so it cannot be added to a new graph. It stays registered so old graphs keep resolving. Use Float.

PinDirectionTypeNotes
valueout · datafloat

On-card fields

FieldWhat
valueA number.

Literal

blueprint.data.literal · Pure

The legacy untyped constant, also hidden from the palette. Its any output type-checks against everything, which is exactly why the typed literals replaced it.

PinDirectionTypeNotes
valueout · dataany

On-card fields

FieldWhat
valueAn untyped value.

Conversion

These are the nodes the connection rules send you to. None of them fail: an input that cannot be read produces the type's zero value rather than an error.

To String

blueprint.string.toString · Pure

null and an unwired input both read as "". An object or an array is serialized to JSON text.

PinDirectionTypeNotes
valuein · dataany
resultout · datastring

To Integer

blueprint.data.toInteger · Pure

Truncates toward zero — -2.7 becomes -2, not -3. true reads as 1, false as 0, a numeric string is accepted, and anything else gives 0.

PinDirectionTypeNotes
valuein · dataany
resultout · datainteger

To Float

blueprint.data.toFloat · Pure

Same acceptance as To Integer, without the truncation. A value that is not a finite number gives 0.

PinDirectionTypeNotes
valuein · dataany
resultout · datafloat

To Boolean

blueprint.data.toBoolean · Pure

Strings are matched after trimming and lowercasing: "", "false", "0", and "no" are false; "true", "1", and "yes" are true; any other non-empty string is true. 0 and a non-finite number are false.

PinDirectionTypeNotes
valuein · dataany
resultout · databoolean

To JSON

blueprint.data.toJson · Pure

A string is parsed as JSON, and kept as the original string when it does not parse — so this node never destroys text. Other values are made JSON-safe: a non-finite number and a cycle become null, a function or symbol becomes its text form.

PinDirectionTypeNotes
valuein · dataany
resultout · datajson

Parse Int

blueprint.data.parseInt · Pure

Base 10, and the leading number wins — "12px" gives 12. No digits at all gives 0.

PinDirectionTypeNotes
valuein · datastringAccepts an on-card literal.
resultout · datainteger

Parse Float

blueprint.data.parseFloat · Pure

PinDirectionTypeNotes
valuein · datastringAccepts an on-card literal.
resultout · datafloat

Parse JSON

blueprint.data.parseJson · Pure

Strict: text that does not parse, and an empty string, both give null. Use To JSON instead when you would rather keep the original text.

PinDirectionTypeNotes
valuein · datastringAccepts an on-card literal.
resultout · datajson

Stringify JSON

blueprint.data.stringifyJson · Pure

An unwired input gives the text "null". A value that cannot be serialized gives "".

PinDirectionTypeNotes
valuein · datajson
resultout · datastring

Type tests

Each takes any and answers a question about the value that actually arrived, which is how you find out what a json or any pin is really carrying.

Is String

blueprint.data.isString · Pure

PinDirectionTypeNotes
valuein · dataany
resultout · databoolean

Is Number

blueprint.data.isNumber · Pure

Finite numbers only — NaN and the infinities are false, and so is a numeric string. This asks about the type, not about parseability.

PinDirectionTypeNotes
valuein · dataany
resultout · databoolean

Is Boolean

blueprint.data.isBoolean · Pure

PinDirectionTypeNotes
valuein · dataany
resultout · databoolean

Is Array

blueprint.data.isArray · Pure

PinDirectionTypeNotes
valuein · dataany
resultout · databoolean

Is Object

blueprint.data.isObject · Pure

True for a non-null object that is not an array. An array answers Is Array, not this.

PinDirectionTypeNotes
valuein · dataany
resultout · databoolean

Is Null

blueprint.data.isNull · Pure

True for null, and also for an input that resolved to nothing — an unwired pin reads as null here.

PinDirectionTypeNotes
valuein · dataany
resultout · databoolean

Not Null

blueprint.data.notNull · Pure

The negation of Is Null, so you do not have to hang a Not off it.

PinDirectionTypeNotes
valuein · dataany
resultout · databoolean

Is Empty Value

blueprint.data.isEmptyValue · Pure

True for null, "", an empty array, and an empty object. 0 and false are values, not emptiness, and both answer false.

PinDirectionTypeNotes
valuein · dataany
resultout · databoolean

Strings

Every value input here takes an on-card literal, so a one-off string does not need its own literal node. Indices are zero-based, and out-of-range indices are clamped rather than rejected.

Concat

blueprint.string.concat · Pure

Joins its inputs in pin order with nothing between them. The card has an add-input control: beyond a and b you can append further string inputs, and the signature below shows only the two it starts with.

PinDirectionTypeNotes
ain · datastringAccepts an on-card literal.
bin · datastringAccepts an on-card literal.
resultout · datastring

Format

blueprint.string.format · Pure

Replaces {name} in the template with the matching field of values, or {0}, {1} … when values is an array. A placeholder with no match becomes empty, and every placeholder becomes empty when values is neither an object nor an array.

Format is the one formatter the palette offers, and it works in a Blueprint Value and in a function. For a template in the player's language, wire Translation Key Text into template.

PinDirectionTypeNotes
templatein · datastringAccepts an on-card literal.
valuesin · datajsonWire a JSON literal, a Make Object, or a Make Array for {0}, {1} ….
resultout · datastring

Length

blueprint.string.length · Pure

PinDirectionTypeNotes
valuein · datastringAccepts an on-card literal.
lengthout · datainteger

Is Empty

blueprint.string.isEmpty · Pure

Length zero. A string of spaces is not empty — that is Is Blank.

PinDirectionTypeNotes
valuein · datastringAccepts an on-card literal.
resultout · databoolean

Is Blank

blueprint.string.isBlank · Pure

Empty, or nothing but whitespace.

PinDirectionTypeNotes
valuein · datastringAccepts an on-card literal.
resultout · databoolean

Trim

blueprint.string.trim · Pure

PinDirectionTypeNotes
valuein · datastringAccepts an on-card literal.
resultout · datastring

Trim Start

blueprint.string.trimStart · Pure

PinDirectionTypeNotes
valuein · datastringAccepts an on-card literal.
resultout · datastring

Trim End

blueprint.string.trimEnd · Pure

PinDirectionTypeNotes
valuein · datastringAccepts an on-card literal.
resultout · datastring

To Upper Case

blueprint.string.toUpperCase · Pure

PinDirectionTypeNotes
valuein · datastringAccepts an on-card literal.
resultout · datastring

To Lower Case

blueprint.string.toLowerCase · Pure

PinDirectionTypeNotes
valuein · datastringAccepts an on-card literal.
resultout · datastring

Capitalize

blueprint.string.capitalize · Pure

Upper-cases the first character and leaves the rest exactly as it is — this is not title case.

PinDirectionTypeNotes
valuein · datastringAccepts an on-card literal.
resultout · datastring

Equals

blueprint.string.equals · Pure

PinDirectionTypeNotes
ain · datastringAccepts an on-card literal.
bin · datastringAccepts an on-card literal.
resultout · databoolean

Equals Ignore Case

blueprint.string.equalsIgnoreCase · Pure

PinDirectionTypeNotes
ain · datastringAccepts an on-card literal.
bin · datastringAccepts an on-card literal.
resultout · databoolean

Contains

blueprint.string.contains · Pure

PinDirectionTypeNotes
valuein · datastringAccepts an on-card literal.
searchin · datastringAccepts an on-card literal.
resultout · databoolean

Starts With

blueprint.string.startsWith · Pure

PinDirectionTypeNotes
valuein · datastringAccepts an on-card literal.
searchin · datastringAccepts an on-card literal.
resultout · databoolean

Ends With

blueprint.string.endsWith · Pure

PinDirectionTypeNotes
valuein · datastringAccepts an on-card literal.
searchin · datastringAccepts an on-card literal.
resultout · databoolean

Index Of

blueprint.string.indexOf · Pure

Searches forward from start and gives -1 when there is no match. start is clamped into the string, so an out-of-range value searches from the beginning or the end rather than failing.

PinDirectionTypeNotes
valuein · datastringAccepts an on-card literal.
searchin · datastringAccepts an on-card literal.
startin · dataintegerAccepts an on-card literal. Defaults to 0.
indexout · datainteger

Last Index Of

blueprint.string.lastIndexOf · Pure

Searches backward from the end. There is no start pin — that is the one asymmetry with Index Of.

PinDirectionTypeNotes
valuein · datastringAccepts an on-card literal.
searchin · datastringAccepts an on-card literal.
indexout · datainteger

Count

blueprint.string.count · Pure

Counts non-overlapping occurrences. An empty search gives 0, not the string length.

PinDirectionTypeNotes
valuein · datastringAccepts an on-card literal.
searchin · datastringAccepts an on-card literal.
countout · datainteger

Char At

blueprint.string.charAt · Pure

An index outside the string gives "", not an error.

PinDirectionTypeNotes
valuein · datastringAccepts an on-card literal.
indexin · dataintegerAccepts an on-card literal.
charout · datastring

Substring

blueprint.string.substring · Pure

The second pin is a length, not an end index. Both are clamped into the string, and an unwired length takes everything from start onwards.

PinDirectionTypeNotes
valuein · datastringAccepts an on-card literal.
startin · dataintegerAccepts an on-card literal.
lengthin · dataintegerAccepts an on-card literal.
resultout · datastring

Insert

blueprint.string.insert · Pure

index is clamped into the string, and an index that cannot be read appends at the end.

PinDirectionTypeNotes
valuein · datastringAccepts an on-card literal.
indexin · dataintegerAccepts an on-card literal.
insertin · datastringAccepts an on-card literal.
resultout · datastring

Replace

blueprint.string.replace · Pure

Replaces the first occurrence only. An empty search returns the value unchanged rather than splicing at every position.

PinDirectionTypeNotes
valuein · datastringAccepts an on-card literal.
searchin · datastringAccepts an on-card literal.
replacementin · datastringAccepts an on-card literal.
resultout · datastring

Replace All

blueprint.string.replaceAll · Pure

Every occurrence. search is plain text, not a pattern — an empty search again returns the value unchanged.

PinDirectionTypeNotes
valuein · datastringAccepts an on-card literal.
searchin · datastringAccepts an on-card literal.
replacementin · datastringAccepts an on-card literal.
resultout · datastring

Repeat

blueprint.string.repeat · Pure

count is clamped to 0–10000, so a runaway number cannot build an unbounded string.

PinDirectionTypeNotes
valuein · datastringAccepts an on-card literal.
countin · dataintegerAccepts an on-card literal.
resultout · datastring

Pad Start

blueprint.string.padStart · Pure

length is the target total length, not the number of characters to add. A string that is already long enough comes back unchanged.

PinDirectionTypeNotes
valuein · datastringAccepts an on-card literal.
lengthin · dataintegerAccepts an on-card literal.
padin · datastringAccepts an on-card literal.
resultout · datastring

Pad End

blueprint.string.padEnd · Pure

PinDirectionTypeNotes
valuein · datastringAccepts an on-card literal.
lengthin · dataintegerAccepts an on-card literal.
padin · datastringAccepts an on-card literal.
resultout · datastring

Split

blueprint.string.split · Pure

The result is an array of strings. It reaches the Array … nodes as well as Join, For Each and any other json input.

PinDirectionTypeNotes
valuein · datastringAccepts an on-card literal.
separatorin · datastringAccepts an on-card literal.
resultout · dataarray<string>

Join

blueprint.string.join · Pure

Takes json, unlike Array Join, which takes array. A values that is not an array gives "".

PinDirectionTypeNotes
valuesin · datajson
separatorin · datastringAccepts an on-card literal.
resultout · datastring

Matches Regex

blueprint.string.matchesRegex · Pure

pattern is the expression source with no delimiters and no flags. A pattern that does not compile gives false rather than raising.

PinDirectionTypeNotes
valuein · datastringAccepts an on-card literal.
patternin · datastringAccepts an on-card literal.
resultout · databoolean

Extract Regex

blueprint.string.extractRegex · Pure

Returns the first capture group when the pattern has one, otherwise the whole match. No match, or a pattern that does not compile, gives "".

PinDirectionTypeNotes
valuein · datastringAccepts an on-card literal.
patternin · datastringAccepts an on-card literal.
resultout · datastring

Normalize Line Breaks

blueprint.string.normalizeLineBreaks · Pure

Rewrites \r\n and lone \r to \n, so text pasted from any platform compares and splits consistently.

PinDirectionTypeNotes
valuein · datastringAccepts an on-card literal.
resultout · datastring

Arrays

Every one of these reads its array input as an array and substitutes an empty one when it is not, so nothing throws. Every one that writes returns a new array on result.

When the type of the items is known, as with the endings from Get Endings, the nodes that return an array return the same type, and Array Get, Array First, Array Last and Array Find By Key return one item of that type: Array Filter By Key on endings gives endings, and Array First gives one ending. Array Concat takes the type of a.

Array Length

blueprint.collection.arrayLength · Pure

PinDirectionTypeNotes
arrayin · dataarray
lengthout · datainteger

Array Get

blueprint.collection.arrayGet · Pure

An index that is negative or past the end gives null. The output is json because an array element can be any JSON value, and takes the item type when the items are known.

PinDirectionTypeNotes
arrayin · dataarray
indexin · dataintegerAccepts an on-card literal.
itemout · datajson

Array Set

blueprint.collection.arraySet · Pure

Writes at index and returns the new array. A negative index, or one above 10000, returns the input unchanged; an index past the end extends the array, leaving the skipped slots empty.

PinDirectionTypeNotes
arrayin · dataarray
indexin · dataintegerAccepts an on-card literal.
itemin · dataany
resultout · dataarray

Array Push

blueprint.collection.arrayPush · Pure

Appends to the end.

PinDirectionTypeNotes
arrayin · dataarray
itemin · dataany
resultout · dataarray

Array Insert

blueprint.collection.arrayInsert · Pure

index is clamped to 0–length, so an out-of-range index appends rather than failing.

PinDirectionTypeNotes
arrayin · dataarray
indexin · dataintegerAccepts an on-card literal.
itemin · dataany
resultout · dataarray

Array Remove

blueprint.collection.arrayRemove · Pure

Removes the first item equal to item, compared as Equal compares: two objects with the same fields match, even though they are different objects. No match returns the input unchanged.

PinDirectionTypeNotes
arrayin · dataarray
itemin · dataany
resultout · dataarray

Array Remove At

blueprint.collection.arrayRemoveAt · Pure

Removes one item and closes the gap. An out-of-range index returns the input unchanged.

PinDirectionTypeNotes
arrayin · dataarray
indexin · dataintegerAccepts an on-card literal.
resultout · dataarray

Array Contains

blueprint.collection.arrayContains · Pure

True when an item equals item, compared as Equal compares, the same rule as Array Remove.

PinDirectionTypeNotes
arrayin · dataarray
itemin · dataany
resultout · databoolean

Array Slice

blueprint.collection.arraySlice · Pure

end is exclusive. Both bounds are clamped into the array, and an unwired end runs to the end.

PinDirectionTypeNotes
arrayin · dataarray
startin · dataintegerAccepts an on-card literal.
endin · dataintegerAccepts an on-card literal.
resultout · dataarray

Array Join

blueprint.collection.arrayJoin · Pure

Converts each item to text — objects and arrays become JSON — and joins them. Takes array, where the string Join takes json.

PinDirectionTypeNotes
arrayin · dataarray
separatorin · datastringAccepts an on-card literal.
resultout · datastring

Array First

blueprint.collection.arrayFirst · Pure

PinDirectionTypeNotes
arrayin · dataarray
itemout · datajsonnull for an empty array.

Array Last

blueprint.collection.arrayLast · Pure

PinDirectionTypeNotes
arrayin · dataarray
itemout · datajsonnull for an empty array.

Array Is Empty

blueprint.collection.arrayIsEmpty · Pure

PinDirectionTypeNotes
arrayin · dataarray
resultout · databoolean

Array Index Of

blueprint.collection.arrayIndexOf · Pure

The position of the first item equal to item, compared by value the way Array Contains compares. -1 when nothing matches.

PinDirectionTypeNotes
arrayin · dataarray
itemin · dataany
indexout · datainteger

Array Concat

blueprint.collection.arrayConcat · Pure

a followed by b, as a new array.

PinDirectionTypeNotes
ain · dataarray
bin · dataarray
resultout · dataarray

Array Reverse

blueprint.collection.arrayReverse · Pure

PinDirectionTypeNotes
arrayin · dataarray
resultout · dataarray

Array Unique

blueprint.collection.arrayUnique · Pure

Drops later duplicates, keeping the first of each. Items are compared as Equal compares them, so two objects with the same fields count as one.

PinDirectionTypeNotes
arrayin · dataarray
resultout · dataarray

Array Range

blueprint.collection.arrayRange · Pure

count numbers starting at start, each one step further on. The array a page needs when it has to draw N of something and the numbers are the content.

PinDirectionTypeNotes
startin · dataintegerAccepts an on-card literal. Defaults to 0.
countin · dataintegerAccepts an on-card literal. Clamped to 0–10000.
stepin · dataintegerAccepts an on-card literal. Defaults to 1, and a step of 0 is read as 1 — it would otherwise be count copies of start wearing the shape of a range.
resultout · dataarray<integer>

Array Find By Key

blueprint.collection.arrayFind · Pure

The first item whose key field equals value, compared as Equal compares, and where it was.

PinDirectionTypeNotes
arrayin · dataarray
keyin · datastringThe field name. Accepts an on-card literal. A dropdown of the items' fields when their type is known.
valuein · dataanyTakes the type of the field key names, and then accepts an on-card literal for a string, number or boolean field.
itemout · datajsonnull when nothing matches. One item of the array's type when it is known.
indexout · datainteger-1 when nothing matches.

Array Filter By Key

blueprint.collection.arrayFilter · Pure

Every item whose key field equals value, compared as Equal compares, in their original order.

PinDirectionTypeNotes
arrayin · dataarray
keyin · datastringAccepts an on-card literal. A dropdown of the items' fields when their type is known.
valuein · dataanyTakes the type of the field key names, and then accepts an on-card literal for a string, number or boolean field.
resultout · dataarrayThe same type as array.

Array Sort By Key

blueprint.collection.arraySort · Pure

Orders records by one of their fields. The three key-based nodes take a field name rather than a comparator, because a comparator is a function value and sorting records by one of their fields is what a list actually needs.

Numbers compare as numbers, booleans as false before true, and everything else as text, ordered the way the runtime collates strings. Items whose field is missing, null, or "" sort to the end in both directions, and ties keep the order they arrived in. An empty key returns the array unchanged.

PinDirectionTypeNotes
arrayin · dataarray
keyin · datastringAccepts an on-card literal. A dropdown of the items' fields when their type is known.
descendingin · databooleanAccepts an on-card literal.
resultout · dataarrayThe same type as array.

JSON Array Length

blueprint.data.jsonArrayLength · Pure

The older name for Array Length, hidden from the palette and kept so existing graphs keep resolving. A value that is not an array gives 0. Use Array Length in new graphs.

PinDirectionTypeNotes
valuein · dataarray
lengthout · datainteger

Structs

A struct is an object whose fields are declared: an ending, a history entry, a save entry, a gallery entry, or a row of a List. A pin that carries one shows the struct's name on the card, such as Ending, and a pin that carries an array of them shows Ending list. Get Field reads one field, picked from a dropdown.

StructFieldsHanded out by
EndingendingId, name, sceneId, sceneName, isReachedGet Endings
History entryid, type, text, character, avatar, voice, voiceId, selected, isPendingGet History, Get Future History
Save entryid, slot, timestamp, createdAt, preview, line, speaker, metadataList Auto Saves
Notificationid, messageGet Notifications
Languagecode, displayName, isSourceGet Available Languages
Voice languagecode, displayNameGet Available Voice Languages
Choicetext, index, disabled, voiceIdThe rows of the choice list in the Game UI
NVL lineindex, nametag, isActiveThe rows of the NVL list in the Game UI
Confirm buttonid, text, index, disabledThe buttons Show Confirm opens its page with

The fields are described with the node that hands them out. A plugin can declare the structs its own nodes hand out, such as the Gallery's Gallery entry; see Manifest. The rows of a List have the struct set under Edit content, which is one of the structs above or the fields written for that List; see Lists.

  • The type follows the wires. The array nodes pass the item type on, as described under Arrays. For Each in Flow gives one item of the array it walks. The List nodes and the item heads give and take rows of the List's struct; see List.
  • A field's type becomes the pin's type. A String field gives string, Number float, Boolean boolean, Image ImageAsset|null, Color RGBAColor and JSON json.
  • Dragging a wire off a struct. Release a wire dragged from a struct pin on empty canvas, and the add-node menu opens on Fields, which lists Get for each field, such as Get isReached. A wire dragged from an array of structs lists Filter by, Sort by and Find by for each field, such as Filter by isReached. Each entry adds the node with the field already chosen and wires it to the pin. Filter by and Find by on a boolean field compare against True.
  • A field the struct does not have is reported. A Get Field set to a field the struct lacks, and a key on Array Filter By Key, Array Sort By Key or Array Find By Key that names no field of the items, are warnings on the canvas and the project check Field not in shape (blueprint/field-missing). Such a node reads nothing: Get Field gives an empty value, a filter keeps no items, and a sort keeps the order. This happens after a List's field is deleted or a key is typed by hand. Only nodes whose struct is known are checked.

Get Field

blueprint.list.getItemField · Pure

One field of a struct. Wire the struct into Object and pick the field under Field. The output takes the field's type, so isReached from an ending wires straight into Branch.

PinDirectionTypeNotes
objectin · datastruct:*Any struct, shown as Struct. Can stay unwired inside a List row.
valueout · dataanyTakes the type of the picked field. null when the value has no such field.

On-card fields

FieldWhat
FieldThe field to read, from the fields of the struct wired into Object. A field the struct no longer has stays in the list as Missing field “…”.
  • The first struct wired in is kept. From then on Object accepts only that struct, even after its wire is removed. To read another struct, add another Get Field.
  • Inside a List row, Object can stay unwired. The node then reads the row being drawn, and the card shows Object · Current row. A row is in reach in the places listed under List: the blueprints of the elements in the List's item template, the List's own item heads, and component definitions.
  • Unwired anywhere else, it reads nothing. The card reports Object as not connected. A Get Field that kept a struct and lost its wire also reads nothing; it does not read the row instead.
  • An object without declared fields does not connect. Read it with Get JSON Field.

The node was named Get Item Field and read only List rows. Its type id is unchanged, so graphs that hold it keep the node, and one left unwired in a row reads the row as before.

Geometry

Vector2D and Rect are structured types rather than JSON documents, so they are built and taken apart with nodes of their own rather than with Get JSON Field. Every input reads a non-number as 0.

Make Vector2D

blueprint.data.makeVector2d · Pure

PinDirectionTypeNotes
xin · datafloatAccepts an on-card literal.
yin · datafloatAccepts an on-card literal.
valueout · dataVector2D

Unlike the Vector2D literal, both components can be wired — which is what Move Mouse To wants when the point is computed.

Break Vector2D

blueprint.data.breakVector2d · Pure

PinDirectionTypeNotes
valuein · dataVector2D
xout · datafloat
yout · datafloat

Make Rect

blueprint.data.makeRect · Pure

PinDirectionTypeNotes
xin · datafloatAccepts an on-card literal.
yin · datafloatAccepts an on-card literal.
widthin · datafloatAccepts an on-card literal.
heightin · datafloatAccepts an on-card literal.
valueout · dataRect

A negative width or height is normalized rather than kept: the origin moves and the extent is made positive, so the rectangle you get is the one you drew.

Break Rect

blueprint.data.breakRect · Pure

PinDirectionTypeNotes
valuein · dataRect
xout · datafloat
yout · datafloat
widthout · datafloat
heightout · datafloat

Rect Center

blueprint.data.rectCenter · Pure

The point equidistant from the rectangle's four edges.

PinDirectionTypeNotes
valuein · dataRect
centerout · dataVector2D

Objects

Object Keys and Object Values read an object's top level, and Object Merge combines two objects. To write or remove a field, use Set JSON Field or Remove JSON Field under JSON, which take a path. An input that is not an object is read as {}.

Object Keys

blueprint.collection.objectKeys · Pure

Field names in insertion order. An array or any other non-object gives an empty array.

PinDirectionTypeNotes
objectin · datajson
resultout · dataarray<string>

Object Values

blueprint.collection.objectValues · Pure

PinDirectionTypeNotes
objectin · datajson
resultout · dataarray

Object Set Field

blueprint.collection.objectSetField · Pure

Superseded by Set JSON Field, which takes a path and so also reaches nested fields; hidden from the palette but still runs in graphs that hold it. field is a plain name, and a dot in it is part of the name rather than a path step. A blank name returns the copy unchanged.

PinDirectionTypeNotes
objectin · datajson
fieldin · datastringAccepts an on-card literal.
valuein · dataany
resultout · datajson

Object Remove Field

blueprint.collection.objectRemoveField · Pure

Superseded by Remove JSON Field; hidden from the palette but still runs in graphs that hold it.

PinDirectionTypeNotes
objectin · datajson
fieldin · datastringAccepts an on-card literal.
resultout · datajson

Object Merge

blueprint.collection.objectMerge · Pure

Shallow merge; b wins on a collision. Nested objects are replaced, not merged. Merge JSON Object is the same operation under a second type id.

PinDirectionTypeNotes
ain · datajson
bin · datajson
resultout · datajson

JSON

The path nodes address a document with dot notation: user.profile.name, and a numeric segment for an array index, items.0. Escape a literal dot in a key as \.. An empty path means the whole document, so Set JSON Field with no path replaces it outright.

Get JSON Field

blueprint.data.jsonGet · Pure

A path that does not exist gives null, so a missing field and a field holding null read the same. Use Has JSON Field when the difference matters.

PinDirectionTypeNotes
jsonin · datajson
pathin · datastringAccepts an on-card literal.
resultout · datajson

Has JSON Field

blueprint.data.jsonHas · Pure

Presence, not truthiness: a field whose value is null still exists.

PinDirectionTypeNotes
jsonin · datajson
pathin · datastringAccepts an on-card literal.
resultout · databoolean

Set JSON Field

blueprint.data.jsonSet · Pure

Copies the input and writes into the copy. Missing containers along the path are created — an array when the next segment is a number, an object otherwise — so writing stats.hp into an empty document produces { "stats": { "hp": … } }.

PinDirectionTypeNotes
jsonin · datajson
pathin · datastringAccepts an on-card literal.
valuein · dataanyStored JSON-safe.
resultout · datajson

Remove JSON Field

blueprint.data.jsonRemove · Pure

Deletes an object field, or splices out an array entry so the later items shift down. A path that does not exist gives back the copy unchanged.

PinDirectionTypeNotes
jsonin · datajson
pathin · datastringAccepts an on-card literal.
resultout · datajson

Make Object

blueprint.data.jsonMakeObject · Pure

Builds an object from dynamic pin pairs, so the signature below is only the output. Each field on the card adds a Name input (string, takes an on-card literal) and a Value input (any); a new node starts with one pair. Names are read at run time, so a wired Name computes the key. A field whose name is blank, or repeats an earlier name, is skipped.

PinDirectionTypeNotes
resultout · datajson

Make Array

blueprint.data.jsonMakeArray · Pure

Builds an array from dynamic Item inputs in pin order, so the signature below is only the output. A new node starts with none — add them on the card. This is the node that produces the array type, and therefore the way to hand a built array to Array Length or List's Set List Content.

PinDirectionTypeNotes
resultout · dataarray

Merge JSON Object

blueprint.data.jsonMergeObject · Pure

Shallow merge with b winning, identical to Object Merge. A non-object input is treated as {}. Superseded by Object Merge; hidden from the palette but still runs in graphs that hold it.

PinDirectionTypeNotes
ain · datajson
bin · datajson
resultout · datajson

Clone JSON

blueprint.data.jsonClone · Pure

A deep, JSON-safe copy. The writer nodes already copy their input, so you only need this when you are about to hand the same document to two branches that must not see each other's edits.

PinDirectionTypeNotes
valuein · datajson
resultout · datajson

Holding a value

Memo

blueprint.data.memo

Reads its input once, when execution passes through, and keeps that value on its output until the next time execution passes through. Before the first pass the output reads null. The value is kept in the same store as the blueprint's variables: one held during Init is still there for a later Mouse Click, and it starts over when that owner instance does.

Its output may feed several consumers. A computed data output feeds only one, and a second wire from it replaces the first, for two different reasons: a pure node re-evaluates at every read, so the same Random Float read twice gives two numbers; and an exec node's output belongs to the pulse that produced it. A Memo has exactly one writer — itself — so every read returns what that write left, and fanning it out cannot surprise anybody. The literals on this page, Element bindings and the parameter pins of an Fn fan out as well, because every read of them gives the same value.

PinDirectionTypeNotes
inin · exec—
valuein · dataanyRead once, as execution passes.
nextout · exec—
resultout · dataanyLabelled Value on the card.

Synchronous rather than latent on purpose: there is nothing to await, and a latent node would be barred from an inline story value.

On this page