Flowlab Technical Reference

Flowlab Technical Reference

How Flowlab runs behavior logic, and what copied behavior JSON means. A reference for building tools and for debugging game logic.

Engine version 5600  ·  node data regenerated with each engine release  ·  see the Behavior Handbook for what each behavior does
Contents ▾ 1The graph model 2The frame loop 3Trigger evaluation order 4Signal flow 5Per-entity state 6Messages 7Timing 8Choosing between similar nodes 9Clipboard JSON 10Node appendix
1

The graph model

In short
A behavior graph belongs to an object type, not to a placed instance. All instances run the same graph, and each instance keeps its own runtime state.

A graph is a set of nodes connected by links. Each node has input and output ports, and every port carries one of these value types: number, text, a list (of numbers, text, or anything), or any. A link connects one output port to one input port; an output may fan out to many inputs and an input may be fed by many outputs.

Triggers start evaluation on their own (Once, Timer, Collision); Mailboxes start it when a message arrives (section 6); all other nodes run only when a value arrives at an input. A bundle is a sub-graph inside a single node with its own ports. Bundles can contain bundles.

For what each node does, see the Behavior Handbook. For every node type's exact ports and fields, see the node appendix.

Values and conventions

  • What a trigger sends. Trigger outputs carry the number 1 unless the Behavior Handbook says otherwise: Once, Always, Timer and Keyboard all send 1 (Keyboard set to any key sends the key as text instead; Mouse Move sends coordinates). To move an object by an amount, route the trigger through a Number: its get input emits the stored value; set stores the incoming number and emits nothing; + adds the incoming number to the stored value and emits the result. See 9.5 for a captured example.
  • Axes. x increases to the right. y increases downward for positions and for Velocity. Impulse and Push Motor are the other way around: a positive y pushes up, negative pushes down.
  • Units. Position works in pixels by default (its pixelUnits setting; grid cells of 32 pixels when off). Velocity, Impulse and Push Motor take engine units, not pixels: a velocity of 1 moves an object roughly 27 pixels per second. Impulse applies a one-time impulse; Push Motor applies a much smaller impulse each time it evaluates, which acts like a steady force when driven every frame. Both are divided by the object's mass.
  • Keys. Keyboard's keyCode is the standard browser key code: Space 32, Enter 13, Esc 27, arrows 37 to 40 (left, up, right, down), letters 65 to 90 (A to Z), digits 48 to 57. A code of 0 means no key is set; -1 means any key.
  • When triggers fire. Once fires on the first frame an instance exists: for placed objects, the first frame after the level loads; for spawned objects, when they appear. After a level restart it fires again for recreated objects, and for objects kept across the restart only when its reset-on-level-start setting is on. Always fires every frame. Keyboard fires the frame a key goes down (down) and the frame it is released (up). With repeats true it also fires down every frame the key is held, or every delay + 1 frames when delay is above 0 (delay is in logic frames and is ignored when repeats is false). Use repeats: true for movement that continues while a key is held; leave it false for a single action such as a jump. Timer fires after its delay, in tenths of a second (section 7).
2

The frame loop

In short
Game logic ticks 60 or 30 times per second, a game setting. Each tick runs physics first, then every object's behaviors, then rendering.

The frame rate is a game setting: games created on the site default to 60, and games that predate the setting run at 30. Physics steps at the same rate as logic. The scene is redrawn once per logic tick; on a 60 Hz display with the game set to 30, every other display frame is skipped. Nodes act only on frame boundaries, so every duration is effectively rounded to whole frames.

One logic tick, in order:

  • Objects destroyed during the previous frame are removed.
  • Physics advances one step. Contacts recorded here become this frame's collision events.
  • Results queued in earlier frames, such as a sound finishing, are delivered.
  • The camera evaluates.
  • Every object with behaviors evaluates: its triggers fire in order (section 3), and each trigger's downstream chain runs to completion (section 4). An object's attachments evaluate during the object's own evaluation.

While the game is paused, physics and behaviors are skipped. Objects whose behaviors are set to run while paused still evaluate, Mouse Click and Gesture triggers fire regardless, and queued asynchronous results (section 4) are still delivered.

3

Trigger evaluation order

In short
Within one object, triggers fire in order of workspace position: left to right, then top to bottom. Only the order within one object is guaranteed.

Each frame, an object's trigger nodes fire one at a time, sorted by workspace position: the x coordinate is compared first, then y. Moving a trigger changes when it runs relative to the object's other triggers. This is the supported way to order work within a frame. If the object's type has a parent type, the parent's triggers all fire first, then the object's own, each set in its own position order.

Triggers inside a bundle sort by the bundle's own position first, so a bundle behaves as a block: everything in a bundle placed to the left runs before everything in a bundle placed to its right. Bundles created before the current bundle format still sort by each trigger's own position.

Mailboxes are not part of this pass. They fire when a message is sent (section 6). Position order applies to them only as a tie-breaker: if one object has several Mailboxes listening to the same message name, a delivery fires them in workspace position order.

Objects evaluate in the level's internal order, which changes as objects spawn and despawn. Do not build logic that depends on which object goes first; within a single object the trigger order above is guaranteed.

4

Signal flow

In short
When an output fires, every linked downstream node evaluates immediately, depth-first, within the same frame. There is no queue between nodes and no per-frame batching anywhere in a chain.

When a trigger fires an output, each linked node evaluates immediately, and its outputs continue downstream before control returns to the trigger. A chain runs as one call stack. When one output links to several inputs, all of them run before the trigger's next output fires. The engine currently runs them top to bottom by the position of the receiving input; do not depend on this.

Many component nodes are pass-through: after acting, they send a value on to a matching output, so chains like Timer → Velocity → Sound carry one value through several nodes. Velocity, Impulse and Push Motor forward the value they received; Position forwards the object's resulting position in pixels.

Two limits stop runaway graphs. Hitting the chain-depth limit, which catches loops, cuts off that branch and lets the rest of the frame continue; hitting the per-frame budget on total evaluations drops all remaining evaluations until the next frame. The first overrun after a level loads shows a warning popup, in the editor and in play alike; later overruns in the same level are silent. The game does not freeze.

Some outputs are asynchronous, such as a sound's done. These are queued and delivered at the start of a later frame's behavior pass, not in the frame that started them.

5

Per-entity state

In short
One graph per object type, but stateful nodes keep separate state per placed instance. Each copy of an object has its own timers, switches, and stored values.

Because a graph belongs to the type (section 1), a node like Timer or Toggle Switch keeps a state record per instance. The record is created when the instance first evaluates the node and discarded when the instance is destroyed.

What resets when:

  • Destroying an object discards its per-instance state. A respawned object starts fresh.
  • Loading a level during play resets most per-instance state (objects are recreated), but Global Variables keep their values across levels and across Restart Game. Global nodes from before that change (node version 1) still reset on every level load.
  • Returning to the editor resets everything to the values set in the editor, including Globals. Save Value data is device storage and is not reset.
  • Game Save snapshots the per-instance state of stateful nodes and restores it on load.

Object Variables are per instance; Global Variables are game-wide.

6

Messages

In short
Messages deliver immediately and synchronously, once per send. There is no queue, no per-frame batching, and no deduplication. Sending a message five times in one frame fires the receiving Mailbox five times, before the sending behavior's next node runs.

When a Message behavior fires, the engine finds every matching Mailbox on the target object and evaluates it immediately, inside the sender's evaluation chain. Control returns to the sender's graph only after the receiver's downstream nodes have finished. Consequences:

  • A Mailbox's downstream logic runs in the same frame as the send.
  • Ordering is depth-first: if a Mailbox's chain sends another message, that second delivery completes before the first sender continues.
  • A Mailbox → Message loop is stopped by the chain-depth limit (section 4) instead of hanging the game.
  • Parent-class Mailboxes receive the message too, and first: delivery walks the target's parent chain before the object's own Mailboxes, so a Mailbox defined on a parent type fires for messages sent to any child instance.

Which objects receive a message depends on the sender's target setting. See Message and Mailbox for the targeting options.

7

Timing

In short
The frame is the smallest unit of time. Every duration a node accepts is rounded to whole logic frames, even when its settings use finer units.
  • Timer delays are set in tenths of a second and cannot resolve finer than one frame. A Timer measures elapsed game time but fires only when its object evaluates; a repeating Timer carries any overshoot into its next interval, so it averages its exact delay.
  • Logic Gate inputs count as simultaneous when they arrive within the gate's time-slack window: 40 ms by default, just over two frames at 60 fps or one frame at 30. The window is adjustable per gate; gates saved before the setting existed keep 0 ms until edited.
  • Collision events are recorded during the physics step and consumed during the same frame's behavior pass. Each object's collision set clears when the object finishes evaluating.
  • Attachments evaluate during their parent object's evaluation and share the chain-depth limit with it.
  • Pausing stops physics and behavior evaluation. When play resumes, Timers subtract the paused interval, so durations exclude paused time. Objects set to run while paused do not get this correction.
8

Choosing between similar nodes

In short
Five ways to detect objects, three ways to move them, four places to keep a value. The main difference in each group is when the engine does the work.

Detecting objects

  • Collision - fires on physical contact, from the physics step. Both objects need collisions enabled. Use for touching.
  • Sensor - fires when something enters or leaves a region around the object, through the physics system. No per-frame scan: the physics engine tracks overlaps itself. Both objects need collisions enabled. Use for zones and ranges.
  • Proximity - checks distance only when its check input fires, so its cost depends on what drives it: Always scans every frame, a Timer scans on that schedule. Works when the scanning object has collisions disabled; targets must be movable or collidable, or they have no physics body and are not seen. Prefer Sensor when both objects have collision shapes.
  • RayCast - casts a line only when its input fires. Use for line-of-sight and ground checks on demand.
  • In View - tests against the camera viewport each frame while in use. Use for on/off-screen logic, not gameplay range.

Moving objects

  • Impulse - a one-time push; physics takes over from there. Use for jumps and knockback.
  • Push Motor - a small push each time it evaluates, so driven by Always it acts as a steady force; the object accelerates against its mass and friction. Use for vehicles and thrust.
  • Velocity - sets speed directly, replacing the current velocity. The new speed persists until physics or another node changes it. x and y each set only their own axis; forward sets both.

All three work with collisions. Collision problems usually come from bypassing physics: setting a position or rotation directly with a property node teleports the physics body, skipping collision response for that move, so it can land overlapping another collider.

Keeping a value

  • Number / Text - a value in the graph, kept per instance; resets with the object.
  • Object Variable - a named value on the instance; other objects' logic can read it by targeting that instance.
  • Global Variable - one value game-wide; survives level changes and restarts (section 5).
  • Save Value - persists on the player's device across sessions.
9

Clipboard JSON

Selecting behaviors and choosing Copy in the wheel menu puts a JSON document on the clipboard. The editor's own Paste re-inserts its last copy; Import accepts the same document pasted into a text box. Both use the same parser, and this page says paste for both.

The examples here are schema "3", which any engine from release 5200 (Kiwi) on can import. Earlier engines read only schema "2" (see 9.7). The envelope:

{"data": {"behavior": {"v": "3", "nodes": [...], "links": [...], "frames": [...]}}}

The keys of data.behavior:

KeyTypeMeaning
vstring behavior schema version - the format of the whole payload. "3" for the examples on this page: settings at their defaults are left out, links are two-element arrays, and node ids are short. Paste also accepts "2", the older format (see 9.7). Unrelated to the numeric v on individual nodes, which versions that node type's ports and settings (see 9.3)
nodesarray one object per behavior node, including the nodes inside copied bundles (see 9.6)
linksarray wires between ports, each a two-element array: output reference, then input reference
framesarray comment frames whose member nodes are all in the selection

A copied payload: a Timer wired into a Number. Each key is explained below the block.

{
  "data": {
    "behavior": {
      "v": "3",
      "nodes": [
        {
          "inputCount": 3,
          "outputCount": 2,
          "behaviorType": "logic.triggers.Timer",
          "x": 120,
          "y": 80,
          "id": "1",
          "v": 3,
          "version": 3
        },
        {
          "inputCount": 3,
          "outputCount": 1,
          "behaviorType": "logic.logic.Value",
          "x": 340,
          "y": 90,
          "id": "2"
        }
      ],
      "links": [
        ["1o0", "2i0"]
      ],
      "frames": []
    }
  }
}
The Timer and Number behaviors connected in the behavior editor
Fig. 1 - the graph this payload describes, as it appears in the behavior editor.
  1. id - a short string, unique within the payload. Copy numbers the nodes "1", "2", … in an engine-determined order, not the order you selected them; treat the values as opaque (9.1). Paste assigns fresh identities, so hand-built ids only need to be unique and consistent with the links entries.
  2. behaviorType - the node's type, and the reliable type key. name is absent here because neither node was renamed: a node carries name only when its display name differs from the type's default, which the appendix lists where it differs from the palette label.
  3. x, y - workspace position in pixels. group is absent because both nodes sit at the top level; a node inside a bundle carries the bundle's id (see 9.6). notes (attached note text) and n_o (1 while the note popup is open on the workbench) also appear only when set.
  4. inputCount / outputCount - the number of ports the node currently shows. A port index in a link reference must be less than this. On paste the engine builds the node with this many ports, so use the count the type shows: too many gives empty ports, too few drops ports and their links.
  5. Settings are absent when they hold their default. This Timer keeps its default delay of 10 and count of 1, and the Number its startVal of 0, so none of those keys appear. The appendix lists every type's settings with the value a freshly added node holds. For most types an absent key restores that value; a few types write their settings unconditionally and substitute nothing when a key is missing (Filter's mode and gateVal, Logic Gate's slack), so hand-built payloads for those types should write every setting. Property names mirror the node's properties panel.
  6. v - the version of the node type's ports and settings; absent means 1. version, when present, repeats v for older engines and can be ignored.
  7. Links are two-element arrays: the output reference first, the input reference second. A reference is a node id followed by a direction letter and a port index: "1o0" is the Timer's first output (“out”), "2i0" the Number's first input (“set”). Port index order is the node's visible top-to-bottom port order, listed per type in the appendix and the Behavior Handbook.

What the payload does not contain: object properties (physics, sprites, layers), runtime values (startVal is the starting value; the running game's current value is never serialized here), and anything about the level. A logic bug caused by a physics setting is invisible in this JSON. Ask for the object's settings.

9.1 Format stability

Stable - safe for tools to depend on: the envelope shape and the schema version string; the universal node fields (id, behaviorType, x, y, inputCount, outputCount always present; name, group, notes, n_o present when set) and the rule that an omitted setting holds its fresh-node value (with the exceptions noted above); the link grammar, output reference first; and each node type's setting names and defaults at its current version, as listed in the appendix. Paste keeps accepting schema "2" documents.

Unspecified - present but not documented, and may change without notice: id values beyond being unique strings (today's copies number them, but a tool must not assume numbers, ordering, or that a saved game uses the same ids as a copy of it); key order; frame ids and portId values; the internals of Custom Behavior bodies; and any field not listed here or in the appendix. A tool that round-trips payloads must preserve fields it does not understand. A type may write a setting even at its default value; presence carries no information. A behavior document taken from a saved game rather than the clipboard can also carry maxId, internal bookkeeping that paste ignores.

The meaning of a given port index changes only with a node's v: when a type gains or reorders ports, new nodes carry a higher v and old payloads keep their meaning. Some types also show more or fewer ports depending on a setting (Sound's ext, Custom Behavior's ports, bundles), which inputCount and outputCount reflect. This page documents the current version of each type.

This documents the clipboard format for reading and re-pasting. It is not a public API: the endpoints the editor saves through are session-authenticated and unsupported for other clients.

9.2 Example: a trigger chain

Mouse Click → Filter → Sound. Three nodes, two links:

{
  "data": {
    "behavior": {
      "v": "3",
      "nodes": [
        {
          "inputCount": 0,
          "outputCount": 4,
          "behaviorType": "logic.triggers.MouseClick",
          "x": 100,
          "y": 60,
          "id": "1",
          "rightClick": false,
          "v": 2,
          "version": 2
        },
        {
          "gateVal": 0,
          "mode": "greater than",
          "inputCount": 2,
          "outputCount": 2,
          "behaviorType": "logic.logic.Filter2",
          "x": 300,
          "y": 70,
          "id": "2"
        },
        {
          "inputCount": 4,
          "outputCount": 5,
          "behaviorType": "logic.components.SoundEffect2",
          "x": 520,
          "y": 60,
          "id": "3"
        }
      ],
      "links": [
        ["2o0", "3i0"],
        ["1o0", "2i0"]
      ],
      "frames": []
    }
  }
}
  1. No node carries a name, so each has its type's default display name. That name does not always match the editor palette: the Sound behavior's is "SoundEffect". behaviorType is the reliable type key; the appendix lists both.
  2. The order of entries in links is not meaningful. Here the second link listed is the first in signal-flow order.
  3. The Filter writes mode and gateVal even though both hold their defaults, and the Mouse Click writes rightClick. Some types always write certain settings. A written default reads the same as a fresh node's value, and these types substitute nothing when the key is missing, so write them.
  4. The Sound node shows 4 inputs and 5 outputs until its extended ports setting (ext) is on, when it shows 8 and 8. The appendix lists the full port set; inputCount and outputCount report what the node shows now.

9.3 Example: per-node versions

Payloads carry two unrelated version fields: the envelope's v is the schema version of the whole document, while a node's numeric v versions that node type's ports and settings. Two Logic Gates of different node versions in one payload:

{
  "data": {
    "behavior": {
      "v": "3",
      "nodes": [
        {
          "inputCount": 2,
          "outputCount": 1,
          "behaviorType": "logic.logic.Gate",
          "x": 100,
          "y": 200,
          "id": "1",
          "gateType": "AND",
          "v": 1,
          "slack": 0,
          "trueZero": false
        },
        {
          "inputCount": 2,
          "outputCount": 1,
          "behaviorType": "logic.logic.Gate",
          "x": 300,
          "y": 200,
          "id": "2",
          "gateType": "AND",
          "v": 2,
          "slack": 40,
          "trueZero": false
        }
      ],
      "links": [],
      "frames": []
    }
  }
}
  1. The v:1 gate predates the time-slack setting and keeps slack: 0; the v:2 gate carries the 40 ms default. A type whose port layout depends on v reads it before building its ports; Logic Gate's version-specific settings are simply read as written, which is how old graphs keep their behavior.
  2. Logic Gate always writes its version, so v appears even at 1 here. For types that leave it out, an absent v means 1.
  3. When a type changes its port layout, the same mechanism applies: port count and order are those of the node's v, not necessarily the current version's.

9.4 Example: Custom Behavior

Custom Behavior nodes define their own ports, so they carry a ports object no other type has:

{
  "data": {
    "behavior": {
      "v": "3",
      "nodes": [
        {
          "body_hash": "",
          "ports": {
            "inputs": [
              {
                "name": "a",
                "type": "Number"
              }
            ],
            "outputs": [
              {
                "name": "out",
                "type": "Number"
              }
            ]
          },
          "v": 1,
          "tag": null,
          "inputCount": 2,
          "outputCount": 1,
          "behaviorType": "logic.logic.Code",
          "x": 100,
          "y": 400,
          "id": "1",
          "version": 1
        }
      ],
      "links": [],
      "frames": []
    }
  }
}
  1. ports lists the user-defined ports by name and type. Type names here are "Number", "Text", "NumberList" or "TextList" (anything else is read as Number), a different spelling from this page's port types.
  2. inputCount is 2 for one defined input: the eval input is always present and is not listed in ports.
  3. tag holds null: the setting is unset. A type may write an unset value as null or leave the key out; read both the same way.
  4. body_hash identifies the script body. The body itself and its storage are unspecified (section 9.1); tools must treat Custom Behavior nodes as opaque beyond their ports.

9.5 Example: a value-carrying chain

A jump: the space bar fires a Number holding 10 into an Impulse's y input. Most game logic has this shape: a trigger, a value, and a component that acts on it.

{
  "data": {
    "behavior": {
      "v": "3",
      "nodes": [
        {
          "inputCount": 0,
          "outputCount": 2,
          "behaviorType": "logic.triggers.Keyboard",
          "x": 100,
          "y": 100,
          "id": "1",
          "keyCode": 32,
          "repeats": false,
          "delay": 0
        },
        {
          "inputCount": 3,
          "outputCount": 1,
          "behaviorType": "logic.logic.Value",
          "x": 300,
          "y": 100,
          "id": "2",
          "startVal": 10
        },
        {
          "inputCount": 3,
          "outputCount": 3,
          "behaviorType": "logic.components.Impulse",
          "x": 500,
          "y": 100,
          "id": "3"
        }
      ],
      "links": [
        ["1o0", "2i1"],
        ["2o0", "3i1"]
      ],
      "frames": []
    }
  }
}
  1. Keyboard's first output ("1o0", down) feeds the Number's second input ("2i1", get); the Number's output feeds the Impulse's second input ("3i1", y). The trigger itself only sends 1; the Number supplies the amount (section 1, values and conventions).
  2. keyCode: 32 is the space bar, a browser key code. Keyboard writes repeats and delay even at their defaults, as some types do. This is a jump, so repeats stays false and the key fires once per press. For walking while a key is held, set repeats: true and route the Number into Velocity's x input instead (section 1, when triggers fire). The field is repeats, plural; Controller's equivalent is repeat.
  3. startVal: 10 is the jump strength. It reaches Impulse's y input, where a positive value pushes up.
  4. Impulse has no settings, and no node is renamed, so the Impulse entry has only its type, position, id and port counts.

9.6 Bundles and frames

A bundle is a node that contains other nodes. Here a bundle named “Blink” holds a Timer wired to the bundle's output; outside it, that output feeds a Number, and a frame labelled “Blink loop” surrounds both top-level nodes:

{
  "data": {
    "behavior": {
      "v": "3",
      "nodes": [
        {
          "inputCount": 0,
          "outputCount": 1,
          "name": "Blink",
          "behaviorType": "logic.NodeGroup",
          "x": 100,
          "y": 100,
          "id": "1",
          "v": 2,
          "version": 2
        },
        {
          "inputCount": 3,
          "outputCount": 2,
          "behaviorType": "logic.triggers.Timer",
          "x": 40,
          "y": 40,
          "group": "1",
          "id": "2",
          "delay": 5,
          "count": 0,
          "v": 3,
          "version": 3
        },
        {
          "inputCount": 1,
          "outputCount": 0,
          "behaviorType": "logic.NodeGroupOutput",
          "x": 260,
          "y": 40,
          "group": "1",
          "id": "3",
          "portId": "1o0"
        },
        {
          "inputCount": 3,
          "outputCount": 1,
          "behaviorType": "logic.logic.Value",
          "x": 340,
          "y": 100,
          "id": "4"
        }
      ],
      "links": [
        ["1o0", "4i2"],
        ["2o0", "3i0"]
      ],
      "frames": [
        {
          "id": "86f6a2781c3e9a40",
          "color": 5934574,
          "label": "Blink loop",
          "group": "",
          "nodeIds": ["1", "4"],
          "x": 80,
          "y": 60,
          "w": 420,
          "h": 160
        }
      ]
    }
  }
}
  1. Copy flattens nesting. The bundle is the node of type logic.NodeGroup; its contents are ordinary entries in the same nodes array whose group is the bundle's id. A bundle inside a bundle follows the same rule. The bundle carries name because it was renamed from the default, and v: 2, the current bundle format.
  2. A bundle's ports are defined by the Bundle Input and Bundle Output nodes inside it (logic.NodeGroupInput, logic.NodeGroupOutput). Each carries portId, the reference of the bundle port it provides, in the same grammar links use: "1o0" is output 0 of node 1, the bundle. The bundle's inputCount and outputCount count these. After paste the engine re-orders a bundle's ports top to bottom by the y of its Bundle Input and Output nodes, so keep portId indices consistent with that vertical order.
  3. Links cross the boundary through those ports. ["2o0","3i0"] wires the Timer to the Bundle Output inside; ["1o0","4i2"] wires the bundle's output to the Number's third input (“+”) outside. The inner Timer is not at its defaults, so delay and count are written.
  4. A frame is a comment box: label, an integer RGB color, its members in nodeIds, a position and size in workspace pixels, and group, the bundle whose workspace holds it (empty at the top level). Copy includes a top-level frame only when every member is in the selection; frames inside a copied bundle are included with it. Frames never affect execution.

9.7 Reading older payloads (schema 2)

Copies made by release 5600 (Orange) and earlier, and most behavior JSON already posted on the forum, use schema "2". The structure is the same. The differences:

Schema 2Schema 3
v"2""3"
node ids16-character hexadecimal stringsshort strings, numbered per copy
links{"output_id": "…o0", "input_id": "…i0"}["…o0", "…i0"]
fieldsevery field written, including name, group ("" at the top level), notes, n_o, and all settingsdefaults omitted, as described above

Paste and Import accept both from release 5200 (Kiwi) on, and both read with the rules on this page. An editor pinned to an older release reads only schema 2. Copy writes schema 3 from release 5700 (Pomegranate) on.

10

Node appendix

Generated from engine version 5600. Ports are listed in index order - the order link references count them. Settings are listed with the value a freshly added node holds; for most types that is what an absent key restores (section 9).

Every node carries these fields, in addition to the per-type settings in the table below:

FieldTypePresentMeaning
idstringalwaysunique within the payload; link references start with it
behaviorTypestringalwaysthe node's type, as listed in the Type column
xnumberalwaysworkspace position, pixels
ynumberalways
inputCountnumberalwaysports the node currently shows
outputCountnumberalways
namestringwhen it differs from the type defaultdisplay name; absent means the type's default (shown under the node name where it differs)
groupstringinside a bundlethe containing bundle's id; absent at the top level
notesstringwhen setattached note text (may be an empty string)
n_onumberwhen non-zero1 while the note popup is open on the workbench; editor state, no effect on logic
vnumberwhen not 1version of the type's ports and settings (see 9.3); some types write it regardless; Level Physics: absent means 0
versionnumbersome typesa copy of v written by most versioned types for older engines; ignore it (Logic Gate writes v alone)
103 of 103 node types
NodeType Ports inPorts outSettings fields
Once
trigger
logic.triggers.Once
  • out num
resetOnLevelStart=false
Always
trigger
logic.triggers.Always
  • out num
MouseMove
trigger
logic.triggers.MouseMove
  • get any
  • x num
  • y num
gameCoords=false
MouseClick
trigger, v2
logic.triggers.MouseClick
  • down num
  • up num
  • over num
  • out num
global=false, rightClick=false, skipAlpha=false, v=2, version=2
LockedMouse
trigger
logic.triggers.LockedMouse
  • on any
  • off any
  • on any
  • off any
  • x num
  • y num
MouseWheel
trigger, name "Mouse Wheel"
logic.triggers.MouseWheel
  • out num
Gesture
trigger
logic.triggers.Gesture
  • x num
  • y num
  • done num
gameCoords=false, gestureType=0, global=false, objCoords=false, touchIdx=0
Keyboard
trigger
logic.triggers.Keyboard
  • down num
  • up num
delay=0, keyCode=0, repeats=false
Controller
trigger, name "Controller 1"
logic.triggers.Controller
  • out num
buttonId=0, controllerId=1, repeat=false
Collision
trigger
logic.triggers.Collision
  • hit num
collideWithEntity=false, collisionFilter=15, delay=0, eName=null, targetClassId=0, targetEntityId=0
Sensor
trigger, v1
logic.triggers.Sensor
  • enter any
  • leave any
  • count num
eName=null, height=32, oX=0, oY=0, pin=false, range=16, shapeType="circle", targetClassId=0, targetEntityId=0, v=1, version=1, verts=null, width=32
Proximity logic.components.Prox2
  • dist num
  • check any
  • x num
  • y num
  • miss any
allObjects=false, contains=false, eName=null, firstObject=true, nearestOnly=false, oX=0, oY=0, pin=false, shape=0, targetClassId=0, targetEntityId=0, threshold=32
Timer
trigger, v3
logic.triggers.Timer
  • delay num
  • reset any
  • start any
  • out num
  • done num
count=1, delay=10, v=3, version=3
Shake
trigger
logic.triggers.Shake
  • out num
Mailbox logic.components.Mailbox
  • out num
dt=2, msg="Hello"
In View
trigger
logic.triggers.InView
  • in num
  • out num
buffer=0
Number logic.logic.Value
  • set num
  • get any
  • + num
  • out num
roundMode=1, startVal=0, tag=null
Expression
v2
logic.logic.Expression
  • A num
  • B num
  • C any
  • out num
default0=0, default1=0, default2=0, default3=0, default4=0, default5=0, expression=null, params=2, tag=null, v=2, version=2
Global Variable
v3
logic.logic.Global
  • set num
  • get any
  • + num
  • out num
dataType=null, passive=true, tag="", v=3, version=3
Object Variable logic.properties.CustomProperty
  • set num
  • get any
  • + num
  • out num
tag=""
Ease
trigger
logic.logic.Ease2
  • time num
  • from num
  • to num
  • start any
  • reverse any
  • pause any
  • out num
  • done num
duration=1, easeFunc="Quadratic", easeType=0, from=0, smartRot=false, to=100
Random
v2
logic.logic.Random
  • min num
  • max num
  • new any
  • out num
max=10, min=0, v=2, version=2
Repeater logic.logic.Repeater
  • count num
  • in any
  • reset any
  • out any
  • done any
repeatCount=0
Filter logic.logic.Filter2
  • set num
  • in num
  • pass num
  • fail num
gateVal=0, mode="greater than"
Switch logic.logic.Switch
  • off any
  • on any
  • in any
  • out any
_startVal=0
Toggle Switch
name "Toggle"
logic.logic.FlipFlop
  • next any
  • in any
  • out1 any
  • out2 any
initialState=0, loop=true
Router logic.logic.Router
  • select num
  • in any
  • out1 any
  • out2 any
loop=true, mode=0, routes=2
Logic Gate
trigger, v2
logic.logic.Gate
  • a num
  • b num
  • out num
gateType="AND", slack=40, trueZero=false, v=2
Function logic.logic.Function
  • input num
  • result num
mode="Sine"
Custom Behavior
v1
logic.logic.Code
  • a num
  • eval any
  • out num
body_hash="", ports={"inputs":[{"name":"a","type":"Number"}],"outputs":[{"name":"out","type":"Number"}]}, tag=null, v=1, version=1
Text
v2
logic.data.TextBlock
  • set str
  • get any
  • + str
  • out str
ext=false, startVal="", tag=null, v=2, version=2
Text Case logic.data.TextCase
  • in str
  • out str
mode=0
Text Length logic.data.TextLength
  • in str
  • out num
To Number logic.data.ToNumber
  • in str
  • out num
Text Compare logic.data.TextCompare
  • A str
  • B str
  • yes str
  • no str
hsv="", mode=0
Text Sanitize logic.data.TextSanitize
  • in str
  • good str
  • bad str
Text List logic.data.TextList
  • set str[]
  • push str
  • all any
  • one num
  • pop any
  • join str
  • find str
  • all str[]
  • one str
  • pop str
  • join str
  • find num
copy=false, startVal=[], tag=null
Number List
v2
logic.data.NumberList
  • set num[]
  • push num
  • all any
  • one num
  • pop any
  • join str
  • find num
  • all num[]
  • one num
  • pop num
  • join str
  • find num
copy=false, startVal=[], tag=null, v=2, version=2
List Modify logic.data.ListModify
  • list any[]
  • index num
  • value num
  • out any[]
copy=false, mode=1
List Order logic.data.ListOrder
  • in any[]
  • out any[]
copy=false, mode=1, numSort=false
List Each
trigger, v3
logic.data.ListEach
  • delay num
  • list any[]
  • reset any
  • index num
  • out num
  • done num
delay=0, v=3, version=3
List Count logic.data.ListCount
  • list any[]
  • count num
Clipboard logic.data.ClipboardCopy
  • copy str
  • out str
Sound
name "SoundEffect"
logic.components.SoundEffect2
  • play num
  • pause num
  • stop num
  • vol num
  • url str
  • pan num
  • pos num
  • pitch num
  • playing num
  • pause num
  • stop num
  • vol num
  • done num
  • pan num
  • pos num
  • pitch num
ext=false, loop=false, mode=0, ol=false, pan=0, pitch=100, pos=0, preload=false, sod=false, sound=null, soundName=null, soundURL=null, synthId=0, url=null, volume=100
Emit
v2, name "Emitter"
logic.components.Emitter
  • angle num
  • emit any
  • out any
angle=0, entityClassId=0, force=2, independent=false, maxAge=10, oX=0, oY=0, pin=false, rotate=false, v=2, version=2
Spawn logic.components.Spawn2
  • x num
  • y num
  • spawn any
  • out any
entityClassId=0, spawnX=0, spawnY=0
Attacher
v2
logic.components.Attachment
  • on any
  • off any
  • x num
  • y num
  • out num
  • out num
entityClassId=0, oX=0, oY=0, pin=false, rotate=false, v=2, version=2
Physics Joint logic.components.Joint
  • on any
  • off any
  • break any
  • on any
  • off any
  • break any
damp=1, ecid=0, frag=0, freq=20, max=100, min=1, stiff=true, type=1, x1=0, x2=0, y1=0, y2=0
Push Motor logic.components.Motor
  • x num
  • y num
  • forward num
  • out num
  • out num
  • out num
Spin Motor logic.components.SpinMotor
  • force num
  • force num
  • spin num
Impulse logic.components.Impulse
  • x num
  • y num
  • forward num
  • out num
  • out num
  • out num
PointAt logic.components.PointAt
  • x num
  • y num
  • rot num
skipRot=false
Destroyer logic.components.Destroyer
  • in any
  • out any
Camera
trigger
logic.components.View
  • set x num
  • set y num
  • move x num
  • move y num
  • zoom num
  • rotate num
  • out num
  • out num
  • out num
  • out num
  • out num
  • out num
bottom=-1, infX=false, infY=false, maxRight=-1, minLeft=0, parallax=100, repeatBG=false, scrollX=true, scrollY=true, subpixel=false, top=0
Message logic.components.Message
  • send num
  • done num
dt=2, eName=null, msg="Hello", route="SendToSelf", targetEntityId=0
RayCast logic.components.RayCast
  • angle num
  • length num
  • cast any
  • hit num
  • miss any
direction=0, earlyOut=false, length=32, oX=0, oY=0, pin=false, targetClassId=0
Calendar logic.components.Calendar
  • now any
  • stamp num
  • year num
  • month num
  • date num
  • day num
Clock logic.components.Clock
  • now any
  • stamp num
  • hour num
  • min num
  • sec num
  • stamp num
fs=false, utc=false
Position logic.properties.Position
  • x num
  • y num
  • +x num
  • +y num
  • x out num
  • y out num
pixelUnits=true, resetVelocity=false
Rotation logic.properties.Rotation
  • set num
  • add num
  • out num
  • out num
fpv=false
Alpha logic.properties.Alpha
  • % num
  • out num
Size logic.properties.Scale
  • % num
  • x num
  • y num
  • out num
  • out num
  • out num
Enabled logic.properties.Enabled
  • true any
  • false any
  • out any
  • out any
Animation logic.properties.Animation
  • start any
  • stop any
  • go to num
  • play any
  • done any
  • go to num
animationName=null, lastFrameSticky=false, loop=false, playAll=false, priority=0
Velocity logic.properties.Physics
  • x num
  • y num
  • forward num
  • out num
  • out num
  • out num
Spin logic.properties.Spin
  • set num
  • spin num
Material logic.properties.Material
  • friction num
  • bounce num
  • density num
  • out num
  • out num
  • out num
Flip logic.properties.Flip
  • flip any
  • back any
  • toggle any
  • out any
  • out any
  • out any
globalAxis=false, spriteOnly=false, vertical=false
Extractor
v3
logic.properties.Extractor
  • get any
  • value num
eClassId=0, eName=null, prop="x", targetId=0, v=3, version=3
Display Order logic.properties.DisplayOrder
  • order num
  • out num
Shader
trigger, v2
logic.properties.Shader
  • lines num
  • curve num
  • on any
  • off any
  • out any
  • out any
mode=1, settings=[100,6], type="retro tv", v=2, version=2
Blending logic.properties.Blending
  • mode num
  • out num
Colors logic.properties.Colors
  • red num
  • green num
  • blue num
  • out num
  • out num
  • out num
Alert logic.hud.Alert
  • show num
  • hide num
  • click num
bgColor=2105376, btnColor=6710886, buttonLabel="Button Message", comp_x=340, comp_y=105, header="Title Message", message="Body Message", textColor=13421772
Bar logic.hud.Bar
  • value num
  • out num
barColor=-5195424, comp_x=0, comp_y=0, frameColor=-10063950, max=10, val=5
OldLabel
name "Label"
logic.hud.Label
  • value str
  • alpha num
  • x num
  • y num
  • out num
  • out num
  • out num
  • out num
borderColor=0, borderSize=0, borderStyle=null, comp_x=320, comp_y=160, fontName="oduda", maxWidth=0, scale=10, text="Label", textAlign="left", textColor=9144974, version=1
Label logic.hud.Label2
  • text str
  • alpha num
  • x num
  • y num
  • text str
  • alpha num
  • x num
  • y num
alpha=100, ext=false, fontName="oduda", kerning=0, lineHeight=1, maxWidth=0, outlineBlur=0, outlineColor=0, outlineSize=0, pin=false, scale=10, text="Label", textAlign="left", textColor=13650064, weight=0, xO=0, yO=0
Cursor logic.hud.Cursor
  • on any
  • off any
  • out any
  • out any
Pause Game
name "Pause"
logic.gameflow.Pause
  • pause any
  • play any
  • out any
  • out any
rwp=false
Load Level
name "LoadLevel"
logic.gameflow.NextLevel
  • go num
  • get num
  • out num
  • out num
levelId=0, levelName=null
Restart Game
name "RestartGame"
logic.gameflow.RestartGame
  • go any
  • out any
Fetch URL logic.gameflow.Link
  • fetch str
  • out str
  • fail num
img=false, load=false, url=null
Save Value
name "Save Number"
logic.logic.Storage
  • save num
  • read any
  • done num
dataType=2, storageKey=null
Leaderboard logic.gameflow.Leaderboard
  • score num
  • get num
  • show any
  • hide any
  • score num
  • get str[]
  • show any
  • hide any
  • failed any
fade=false, mpp=5, reverse=false, theme="Flowlab", xPos=0, yPos=0
Achievement logic.gameflow.Achievement
  • grant num
  • out num
aid=0, fade=null, theme="Flowlab", xPos=0, yPos=0
Level Physics
v1
logic.gameflow.FrameRate
  • speed num
  • drag num
  • gravity num
  • out num
  • out num
  • out num
v=1, version=1
User Info logic.gameflow.UserInfo
  • get any
  • id num
  • name str
Full Screen
trigger
logic.components.FullScreen
  • on any
  • off any
  • toggle any
  • get w any
  • get h any
  • on any
  • off any
  • toggle any
  • width num
  • height num
smIdx=2
Cloud
trigger
logic.logic.CloudStorage
  • name str
  • set num
  • get num
  • clear num
  • set num
  • get num
  • clear num
  • fail num
dataType=2, storageKey="My Cloud Value"
Game Save logic.gameflow.GameState
  • list any
  • save num
  • load num
  • image num
  • delete num
  • all num[]
  • saved num
  • image num
  • deleted num
tSize=256
Ad logic.components.Ad
  • banner num
  • full num
  • hide num
  • reward num
  • out num
  • close num
  • out num
  • reward num
appIdAndroid="ca-app-pub-3940256099942544~3347511713", appIdIos="ca-app-pub-3940256099942544~3347511713", bannerIdAndroid="ca-app-pub-3940256099942544/6300978111", bannerIdIos="ca-app-pub-3940256099942544/6300978111", gravityMode="TOP", interstitialIdAndroid="ca-app-pub-3940256099942544/1033173712", interstitialIdIos="ca-app-pub-3940256099942544/1033173712", rewardIdAndroid="ca-app-pub-3940256099942544/5224354917", rewardIdIos="ca-app-pub-3940256099942544/5224354917", testMode=false
Accelerometer
trigger
logic.triggers.Accelerometer
  • x num
  • y num
  • z num
Vibrate logic.components.Vibrate
  • time num
  • out num
iOS GameCenter logic.components.GameCenter
  • score num
  • display any
  • out num
  • out num
leaderboardID="default"
Device Check logic.logic.DeviceCheck
  • in any
  • browser any
  • mobile any
  • desktop any
Touch Check logic.logic.TouchCheck
  • in any
  • touch any
  • mouse any
Exit Game
name "Exit"
logic.components.ExitGame
  • exit any
Shared logic.multiplayer.SharedValue
  • send num
  • + num
  • sync num
startVal=0, tag=null, uuid="b5abff2e6e4b1c40"
Player Count
trigger
logic.multiplayer.PlayerCount
  • count num
levelOnly=false
Player Check logic.multiplayer.PlayerCheck
  • in num
  • local num
  • remote num
New Bundle
v2
logic.NodeGroup isMenuItem=false, originBundleId=null, originPk=null, ownBundleId=null, v=2, version=2
New Input
name "Bundle Input"
logic.NodeGroupInput
  • out num
dataType=2, portId, tag="input"
New Output
name "Bundle Output"
logic.NodeGroupOutput
  • out num
dataType=2, portId, tag="output"