Skip to content

Object Flow integration ​

Components are not a separate scripting language—they plug into the same Object Flow graphs you already use for taps, drags, and scene logic.


Node catalog ​

When an object is selected in Object Flow, the node library includes a Components group built from:

  1. Attached components on that object (actions + conditions).
  2. Optionally, catalog entries derived from the global registry (see catalog.js).

Each catalog item becomes either:

Catalog kindFlow node action.type / condition.typeLabel example
componentActioncomponentActionhealth.damage
componentConditioncomponentConditionhealth.isAlive

Payload shape for actions:

json
{
  "type": "componentAction",
  "component": "health",
  "method": "damage",
  "params": { "amount": 10 }
}

Payload shape for conditions:

json
{
  "type": "componentCondition",
  "component": "health",
  "method": "isAlive",
  "params": {}
}

The Flow Inspector renders dropdowns for component, method, and typed parameters based on the definition schema.

Built-in Flow nodes and custom Flow nodes from Script Studio share the same catalog. A custom node appears once it compiles — you do not edit a central type list.


Wired action parameters ​

Registry actions (moveTo, positionAbove, snapToTarget, …) expose param: data pins derived from their field schema. Connect a Get Value node (for example Active Turn Object Id or Event Payload Field) into param:targetObjectId or param:objectId so the target updates at runtime without duplicating rules per combatant.

The Position Above action snaps or tweens an object above another using each thing’s height plus an optional offsetY.

Runtime execution ​

During Play, the graph calls into the object's components:

  • Conditions: check(component, method, params)
  • Actions: run(component, method, params)

The active event still carries event, source, and target, so actions can respect who tapped whom.

Component actions target the object that owns the graph, unless the action itself looks up another object (for example Team conditions with an object picker).


Expressions in graph fields ​

Many flow node fields accept inline expressions prefixed with =:

text
=self.hp > 0
=params.amount * 2
=Math.min(self.hp, self.maxHp)

Available bindings ​

IdentifierDescription
selfComponent fields when the node targets a componentAction / componentCondition; otherwise null
paramsNode parameter bag
eventActive event payload (includes payload for custom / component events)
source / targetInteraction actors
thingResolved object for the node (objectId or event actor)
varsBinding/scripting view of state (vars.counters / vars.flags still resolve for expressions; prefer declared GameState and object variables)
get(id)Sibling component fields on thing, e.g. get("health")?.hp
MathStandard Math object

Event Payload Getters ​

Component events can declare a typed payload:

javascript
events: {
  damaged: {
    label: "Damaged",
    payload: {
      amount: { type: "number", label: "Amount" },
      sourceId: { type: "objectRef", label: "Source" },
    },
  },
}

Object Flow uses that schema to populate Event Data getter nodes and typed data pins on explicit event nodes for the active component event graph. The persisted getter nodes stay generic getValue records with valueSource.source === "eventField" and paths such as payload.amount.

Event nodes are explicit start nodes, not a generated list of every possible rule. A designer places or opens the event they need, such as On Tap for a button object or On Event for start_game, then wires that event node into actions like Emit Event. Other objects can subscribe by placing/opening their own explicit On Event graph for the same key.

Opening an object's Flow Graph shows the explicit event nodes that have been placed on that object. It does not create a node for every event type or every legacy rule. Right-clicking the canvas can place On Tap, On Event, or a component-defined event; action nodes belong to whichever event flow they are added to or connected from.

Value nodes and data wires ​

Object Flow supports typed value wires alongside exec wires:

NodePurpose
Number / Text / Boolean (literal)Constant value on the graph
Get (getValue)Read GameState / scene variables, object variables, component fields, event fields, or active turn id
Set Value (setValue)Write GameState / object variables or exposed component fields when exec reaches the node

Connect a value node's value pin (right) to an action's param: pin (left), e.g. param:amount on health.damage. Data edges use gold cables; exec edges stay white/green.

Component fields can opt into setter nodes:

javascript
fields: {
  hp: { type: "number", default: 10, flow: { set: true } },
}

Fields, params, actions, conditions, and events can also use flow.expose: false to stay out of the graph catalog. Action params can use flow.pin: false to remain editable without creating a data pin.

Safety rules ​

Expressions must be single expressions (no ;, no if/for, no new, no eval/Function, no window/document). Failures log a warning and evaluate to undefined so play mode keeps running.

Use Script action nodes when you need multiple statements.


Script action node ​

Flow node type: action.type === "script".

Body is a multi-statement script compiled with compileScript:

javascript
// Example body in Flow Inspector
const hp = thing.components.get("health")?.fields;
if (hp && hp.hp > 0) {
  thing.components.run("health", "damage", { amount: params.power || 5 });
}

Available: self, params, event, source, target, thing, components.


Expression condition node ​

Flow node type: condition.type === "expression".

Body is one expression returning truthy/falsey:

text
self?.hp > 0

Branches use standard true / false ports to chain actions.


Subscribing to component events (graphs) ​

Component events (e.g. health.died) are declared on the definition. To react in graphs:

  1. Use On Event / custom event nodes where the engine bridges component emissions into the rule system, or
  2. Call follow-up actions in the same graph after a componentAction node.

Some built-ins also react to sibling events with no graph at all — Health Bar flashes on health.damaged.


Scene Flow vs Object Flow ​

ScopeGraph locationComponent nodes
Per objectObject FlowYes — catalog from attachments
Scene-wideScene FlowUse Script / scene actions unless scene rules gain component targets

For battle controllers, either attach Turn Queue to a dedicated object and use Object Flow on that object, or invoke component actions from scene rules via script that looks up the controller by id.


Empty graphs and “On Tap” ​

The editor only counts flows with real logic when showing “events with logic,” and avoids auto-creating empty On Tap rules. Component nodes count as logic once placed on the canvas.


Debugging checklist ​

SymptomCheck
Node missing in catalogComponent attached? Registry loaded?
Action no-opMethod name typo? Params coerced? invulnerable?
Condition always falseParams default? Wrong object ref?
Expression undefinedMissing =? Forbidden token?
Works in editor, not playPlay reset restored fields? onPlayStart refill?
Warning badgeMissing component/action/condition/event/field, stale param, or component not attached

Back to Getting started · Built-in reference