Specialized components
Visual scripting
Node definition
19 min
overview node definitions serve as the blueprints for all node types available in the ir engine visual scripting system they define the structure, behavior, and appearance of each type of node that can be used in visual scripts by providing a formal specification for node types, node definitions enable the system to create consistent instances of nodes, validate connections between them, and execute their logic correctly this chapter explores the concept, structure, and implementation of node definitions within the ir engine core concepts definition purpose node definitions serve several essential purposes in the visual scripting system type specification they define the unique characteristics of each node type interface declaration they specify what inputs and outputs a node has behavior implementation they contain the logic that executes when the node is activated visual representation they provide information about how the node should appear in the editor organization they categorize nodes to make them easier to find and use by centralizing this information in a formal definition, the system can ensure consistency and provide a framework for extending the available node types definition components a complete node definition includes several key components type identifier a unique string that identifies the node type (e g , "math/add", "events/ontrigger") category a grouping for organization in the editor (e g , "math", "events", "logic") label the display name shown on the node in the visual editor input sockets specifications for all input connection points output sockets specifications for all output connection points configuration properties optional settings that can be adjusted on individual instances execution logic the code that runs when the node is activated these components provide all the information needed to create, display, and execute instances of the node type implementation node definition interface the core interface for node definitions is inodedefinition // simplified from src/engine/nodes/nodedefinitions ts export interface inodedefinition< tinput extends socketsdefinition = socketsdefinition, toutput extends socketsdefinition = socketsdefinition \> { typename string; // unique identifier (e g , "math/add") category? nodecategory; // grouping for the editor (e g , "math") label? string; // display name (e g , "add") helpdescription? string; // documentation for the node in tinput; // input socket definitions out toutput; // output socket definitions configuration? nodeconfigurationdescription; // configurable properties readonly nodefactory nodefactory; // function to create node instances } this interface defines the structure that all node definitions must follow, ensuring they provide all necessary information for the system socket definition input and output sockets are defined using the socketdefinition interface // simplified from src/engine/nodes/nodedefinitions ts export interface socketdefinition { valuetype string; // data type (e g , "number", "string", "flow") defaultvalue? any; // default value if no connection exists label? string; // display name for the socket choices? choices; // optional list of allowed values description? string; // documentation for the socket } // sockets are typically defined in a map export type socketsmap = record\<string, socketdefinition | string>; socket definitions specify what type of data the socket accepts or provides default values for input sockets when not connected display information for the visual editor any constraints on the values (e g , a list of allowed options) specialized node definitions different types of nodes have specialized definition interfaces that extend the base inodedefinition function node definition for nodes that process data without participating in execution flow // simplified from src/engine/nodes/nodedefinitions ts export interface ifunctionnodedefinition< tinput extends socketsdefinition = socketsdefinition, toutput extends socketsdefinition = socketsdefinition \> extends inodedefinition\<tinput, toutput> { exec (context { read \<t>(inputname string) => t; write \<t>(outputname string, value t) => void; configuration record\<string, any>; }) => void; } the exec function defines the node's data processing logic, with helpers for reading inputs and writing outputs flow node definition for nodes that participate in execution flow // simplified from src/engine/nodes/nodedefinitions ts export interface iflownodedefinition< tinput extends socketsdefinition = socketsdefinition, toutput extends socketsdefinition = socketsdefinition \> extends inodedefinition\<tinput, toutput> { triggered (context { read \<t>(inputname string) => t; write \<t>(outputname string, value t) => void; configuration record\<string, any>; commit (outputflowname string) => void; }) => void; } the triggered function includes all the capabilities of exec plus a commit function to continue execution through a specific output flow socket event node definition for nodes that initiate execution flow // simplified from src/engine/nodes/nodedefinitions ts export interface ieventnodedefinition< tinput extends socketsdefinition = socketsdefinition, toutput extends socketsdefinition = socketsdefinition \> extends inodedefinition\<tinput, toutput> { init (context { trigger (outputflowname string) => void; configuration record\<string, any>; }) => void; dispose? () => void; } the init function sets up event listeners, and the trigger function initiates execution flow when the event occurs helper functions the system provides helper functions to simplify the creation of node definitions // simplified from src/engine/nodes/nodedefinitions ts export function makefunctionnodedefinition< tinput extends socketsdefinition = socketsdefinition, toutput extends socketsdefinition = socketsdefinition \>(definition omit\<ifunctionnodedefinition\<tinput, toutput>, 'nodefactory'>) ifunctionnodedefinition\<tinput, toutput> { // create the node factory function const nodefactory nodefactory = (graph, configuration) => { // create a new function node instance const node = new functionnodeinstance( definition, graph, configuration || {} ); return node; }; // return the complete definition with the factory return { definition, nodefactory }; } similar helper functions exist for other node types ( makeflownodedefinition , makeeventnodedefinition , etc ) these functions take a partial definition without the nodefactory create an appropriate factory function for the node type return a complete definition with the factory attached example "add" node definition let's examine a complete definition for a simple "add" node that adds two numbers // example of a function node definition const addnodedefinition = makefunctionnodedefinition({ typename 'math/add', category 'math', label 'add', helpdescription 'adds two numbers together', // input socket definitions in { numbera { valuetype 'number', label 'number a', defaultvalue 0 }, numberb { valuetype 'number', label 'number b', defaultvalue 0 } }, // output socket definitions out { sum { valuetype 'number', label 'sum' } }, // node logic exec ({ read, write }) => { // read input values const a = read\<number>('numbera'); const b = read\<number>('numberb'); // calculate result const sum = a + b; // write to output write\<number>('sum', sum); } }); this definition identifies the node as "math/add" in the "math" category specifies two input sockets for numbers, with default values of 0 defines one output socket for the sum implements the logic to add the inputs and write the result to the output node creation process when a user adds a node to a visual script graph, the system follows this process sequencediagram participant user participant editor participant registry participant nodedef participant factory participant node user >>editor select "add" node from palette editor >>registry request node type "math/add" registry >>nodedef retrieve definition editor >>factory call nodefactory from definition factory >>node create new node instance factory >>node set up input/output sockets factory >>node configure with default values node >>editor return completed node instance editor >>user display node on graph the user selects a node type from the editor palette the editor requests the node definition from the registry the editor calls the nodefactory function from the definition the factory creates a new node instance with the appropriate structure the factory sets up input and output sockets based on the definition the factory configures the node with any default values the completed node instance is returned to the editor the editor displays the node on the graph node execution when a node is executed during script runtime, the system uses the definition's logic function node execution // simplified concept from src/engine/nodes/functionnode ts function executefunctionnode(node functionnodeinstance) void { // get the node definition const definition = node definition as ifunctionnodedefinition; // create the execution context const context = { read \<t>(inputname string) t => { // find the input socket const socket = node inputs find(s => s name === inputname); if (!socket) throw new error(`input socket '${inputname}' not found`); // read the value from the socket return readinputfromsocket(socket) as t; }, write \<t>(outputname string, value t) void => { // find the output socket const socket = node outputs find(s => s name === outputname); if (!socket) throw new error(`output socket '${outputname}' not found`); // write the value to the socket writeoutputtosocket(socket, value); }, configuration node configuration }; // execute the node's logic definition exec(context); } this process retrieves the node's definition creates a context with helper functions for reading inputs and writing outputs calls the definition's exec function with this context the exec function reads inputs, performs calculations, and writes outputs next steps with an understanding of how node definitions specify the structure and behavior of node types, the next chapter explores the data types that can flow through sockets, known as value types next valuetype docid\ x3xue9bape5inoh7m3hw2