Skip to content

Python Scripting

The graph system comes with IronPython 3.4.2 built-in, allowing you to inject custom logic directly into node attributes.


✍️ How to Use Scripting

Any node port can use a script by holding Ctrl and middle-clicking the attribute field in the Inspector.
This converts the field into a script editor, enabling dynamic evaluation.


🧬 Internal Variables

When scripting, you have access these internal variables:

  • self — represents the node executing the script
  • comp — a class that holds global functions such as:
  • SetFrame(frame_number) — sets the current timeline frame
  • GetFrame() — gets the current timeline frame
  • Play() / Stop() — controls playback
  • GetCurrentClip() — returns the currently playing item in vTask
  • GetCurrentFilePath() — returns the file path of the current project
  • GetTotalClock() — returns the total remaining time
  • GetCurrentClipClock() — returns the remaining time of the current clip
  • SetFrameStart(frame) / SetFrameEnd(frame) — sets timeline boundaries
  • GetFrameStart() / GetFrameEnd() — retrieves timeline boundaries
  • SetFrameLoop(bool) / GetFrameLoop() — toggles looping
  • IsPlaying() — checks if the timeline is currently playing

🧬 Internal Functions

  • GetNode(node_name) — returns a node in the graph that matches the name

🧬 Node & Port Access

The self variable is an instance of SafeNode, giving you access to node-level properties and ports:

Node Properties

  • self.Name — name of the node
  • self.Type — type of the node
  • self.NodeType — editable node type
  • self.Position — position of the node in the graph
  • self.Width, self.Height — dimensions of the node
  • self.isSelected — whether the node is selected
  • self.isProccessing — whether the node is actively processing
  • self.isOpen — whether the node is expanded
  • self.isRoot — whether the node is the root of a graph
  • self.isCollapsed — whether the node is collapsed
  • self.isEditing — whether the node is being edited
  • self.isActivePreview — whether the node is previewing output
  • self.ParentGraph — parent graph node (if applicable)
  • self.Connections — list of connections to/from this node
  • self.Nodes — child nodes if this is a graph node
  • self.GetErrors() — returns a list of port errors

Port Access

  • self.GetInputPort(name) — returns a SafePort for an input port
  • self.GetOutputPort(name) — returns a SafePort for an output port

Each SafePort supports:

  • Name, Type, DataType — metadata about the port
  • GetData() / SetData(value) — read/write port data
  • GetDataAsString() — get data as a string
  • GetError() / SetError(message) — manage port errors
  • IsConnected — check if the port is connected
  • IsOverlayOn — check if overlay is active

Each SafeConnection supports:

  • SourcePort — the origin of the connection
  • TargetPort — the destination of the connection

Note:

You can replace self with a variable when GetNode is used


🧮 Evaluation Behavior

  • A single-line expression will be evaluated and its result returned directly to the field.
  • For multi-line scripts, use result = ... to define the return value.

🔗 Referencing Other Ports

You can reference the value of any other node’s port using the syntax: nodename::portname Let’s say you want a node to output double the value of another node called Waver with output port named amount.

Single-line script:

Waver::amount * 2

Multi-line script:

v = Waver::amount
result = v \* 2

Using GetNode:

waverNode = GetNode("Waver")
v = waverNode.GetOutputPort("amount").GetData()
result = v \* 2

To return a vector, use string formatting with comma-separated values. For example, to return a 3D vector based on other ports:

x = GetNode("Control").GetOutputPort("x").GetData()
y = GetNode("Control").GetOutputPort("y").GetData()
z = GetNode("Control").GetOutputPort("z").GetData()
result = "{},{},{}".format(x, y, z)

🕒 Timeline & Clip Control via comp

You can use the comp object to interact with the timeline and clip system. Here are some examples:

total = comp.GetTotalClock()
clipTime = comp.GetCurrentClipClock()
result = "Total: {}, Clip: {}".format(total, clipTime)

Set timeline range dynamically

comp.SetFrameStart(0)
comp.SetFrameEnd(250)
result = "Timeline set from 0 to 250"

✅ Applying & Detaching Scripts

  • After making changes to a script, you must click Apply to activate it.
  • To detach a script and revert the field to its original style:
  • Clear the script field
  • Click Apply

This restores the field to its default input mode, removing the script editor.

🧠 Tip: Use scripting to drive dynamic behavior, automate values, or respond to timeline changes in real time.