/** * @file VisualScripting2.ts * @description Visual Scripting 2.0 — Node-based Scripting System with Debugger * PRO-1.4: Professional Editor Features * * Features: * - Node-based visual programming (like Unreal Blueprints) * - Real-time debugger with breakpoints * - Step-by-step execution * - Watch expressions * - Variable inspection * - Call stack visualization * - Live preview in editor */ import type { EntityId, Vec2 } from '../core/types'; import type { EventBus } from '../core/EventBus'; /** Extended data types for visual scripting */ export type VSDataType = 'flow' | 'bool' | 'int' | 'float' | 'string' | 'vec2' | 'vec3' | 'color' | 'entity' | 'component' | 'asset' | 'array' | 'map' | 'struct' | 'object' | 'enum' | 'delegate' | 'wildcard'; /** Type color mapping for visual identification */ export declare const VS_TYPE_COLORS: Record; export interface VSPort { id: string; name: string; direction: 'input' | 'output'; type: VSDataType; subType?: VSDataType; structDef?: string; enumDef?: string; defaultValue?: unknown; description?: string; /** Multiple connections allowed (outputs only) */ multi?: boolean; /** Optional execution flow port */ optional?: boolean; /** Hidden in compact mode */ advanced?: boolean; } export type VSNodeCategory = 'event' | 'flow' | 'math' | 'logic' | 'string' | 'array' | 'entity' | 'component' | 'physics' | 'audio' | 'animation' | 'input' | 'ui' | 'time' | 'transform' | 'debug' | 'variable' | 'function' | 'macro' | 'comment' | 'reroute' | 'custom'; export interface VSNodeDefinition { type: string; name: string; category: VSNodeCategory; description: string; keywords?: string[]; icon?: string; color?: string; ports: VSPort[]; /** Is this a pure node (no side effects, can be cached)? */ pure?: boolean; /** Is this a latent node (async, takes multiple frames)? */ latent?: boolean; /** Is this node deprecated? */ deprecated?: boolean; /** Compact display (single-line) */ compact?: boolean; /** Minimum required license tier */ licenseTier?: 'free' | 'pro' | 'enterprise'; /** Execute function */ execute: (inputs: Record, context: VSExecutionContext) => Record | Promise> | void; /** Validate node configuration */ validate?: (node: VSNodeInstance) => VSValidationResult[]; /** Custom rendering callback */ renderCustom?: (node: VSNodeInstance, ctx: CanvasRenderingContext2D) => void; } export interface VSValidationResult { severity: 'error' | 'warning' | 'info'; message: string; portId?: string; } export interface VSNodeInstance { id: string; type: string; position: Vec2; size?: Vec2; /** Input port values (overrides defaults) */ inputs: Record; /** Cached output values */ outputs: Record; /** User comment */ comment?: string; /** Is node collapsed? */ collapsed?: boolean; /** Is node disabled? */ disabled?: boolean; /** Breakpoint set on this node */ breakpoint?: VSBreakpoint; /** Custom data for specific node types */ customData?: Record; } export interface VSConnection { id: string; fromNode: string; fromPort: string; toNode: string; toPort: string; /** Connection style */ style?: 'bezier' | 'linear' | 'stepped'; /** Reroute points for wire organization */ reroutePoints?: Vec2[]; } export interface VSVariable { id: string; name: string; type: VSDataType; subType?: VSDataType; structDef?: string; enumDef?: string; value: unknown; defaultValue: unknown; /** Variable scope */ scope: 'local' | 'graph' | 'instance' | 'global'; /** Is this variable exposed to editor? */ exposed?: boolean; /** Category for organization */ category?: string; /** Description */ description?: string; /** Replicated in multiplayer */ replicated?: boolean; /** Save in game save */ savedGame?: boolean; } export interface VSFunction { id: string; name: string; description?: string; category?: string; /** Input parameters */ inputs: VSPort[]; /** Output values */ outputs: VSPort[]; /** Local variables */ localVariables: VSVariable[]; /** Is this a pure function? */ pure?: boolean; /** Function graph */ graph: VSGraph; } export interface VSMacro { id: string; name: string; description?: string; /** Input tunnels */ inputs: VSPort[]; /** Output tunnels */ outputs: VSPort[]; /** Contained graph */ graph: VSGraph; /** Instance color */ color?: string; } export interface VSGraph { id: string; name: string; description?: string; nodes: VSNodeInstance[]; connections: VSConnection[]; variables: VSVariable[]; functions: VSFunction[]; macros: VSMacro[]; /** Graph-level parameters (for subgraph use) */ parameters: VSPort[]; /** Graph type */ graphType: 'blueprint' | 'function' | 'macro' | 'animgraph' | 'statemachine'; /** Parent entity/component this graph is attached to */ parentEntity?: EntityId; parentComponent?: string; /** Metadata */ metadata?: { author?: string; version?: string; created?: number; modified?: number; tags?: string[]; }; } export interface VSStructDefinition { name: string; description?: string; fields: Array<{ name: string; type: VSDataType; defaultValue?: unknown; }>; } export interface VSEnumDefinition { name: string; description?: string; values: Array<{ name: string; displayName?: string; value?: number; }>; } export interface VSExecutionContext { /** Current entity */ entityId: EntityId | null; /** Delta time */ dt: number; /** Total elapsed time */ time: number; /** World reference */ world: unknown; /** Event bus */ events: EventBus; /** Graph variables */ variables: Map; /** Global variables */ globals: Map; /** Service locator */ services: Map; /** Trigger flow output */ triggerFlow: (portId: string) => void; /** Get component */ getComponent: (entityId: EntityId, componentType: string) => T | null; /** Set component data */ setComponent: (entityId: EntityId, componentType: string, data: unknown) => void; /** Spawn entity */ spawnEntity: (prefab: string, position: Vec2) => EntityId; /** Destroy entity */ destroyEntity: (entityId: EntityId) => void; /** Find entities */ findEntities: (tag: string) => EntityId[]; /** Log message */ log: (level: 'info' | 'warn' | 'error', message: string) => void; /** Print to screen */ print: (message: string, duration?: number, color?: string) => void; } export interface VSBreakpoint { id: string; nodeId: string; enabled: boolean; condition?: string; hitCount?: number; logMessage?: string; temporary?: boolean; } export interface VSWatchExpression { id: string; expression: string; value: unknown; type: VSDataType; error?: string; } export interface VSCallStackFrame { nodeId: string; nodeName: string; graphId: string; graphName: string; functionName?: string; variables: Map; } export type VSDebuggerState = 'running' | 'paused' | 'stepping' | 'stopped'; export interface VSDebuggerSession { state: VSDebuggerState; /** Current execution position */ currentNode: string | null; currentGraph: string | null; /** Call stack */ callStack: VSCallStackFrame[]; /** Breakpoints */ breakpoints: Map; /** Watch expressions */ watches: VSWatchExpression[]; /** Execution history for step-back */ history: VSExecutionSnapshot[]; historyIndex: number; /** Profiling data */ profiling: VSProfilingData; } export interface VSExecutionSnapshot { timestamp: number; nodeId: string; inputs: Record; outputs: Record; variables: Map; } export interface VSProfilingData { enabled: boolean; nodeExecutionTimes: Map; totalFrameTime: number; frameCount: number; } export type VSDebuggerEventType = 'breakpoint-hit' | 'step-completed' | 'execution-error' | 'variable-changed' | 'node-executed' | 'graph-started' | 'graph-completed'; export interface VSDebuggerEvent { type: VSDebuggerEventType; timestamp: number; data: unknown; } export declare class VSDebugger { private session; private eventListeners; constructor(); private createSession; start(): void; pause(): void; resume(): void; stop(): void; getState(): VSDebuggerState; stepOver(): void; stepInto(): void; stepOut(): void; stepBack(): void; addBreakpoint(nodeId: string, options?: Partial): VSBreakpoint; removeBreakpoint(breakpointId: string): void; toggleBreakpoint(nodeId: string): VSBreakpoint | null; setBreakpointCondition(breakpointId: string, condition: string): void; enableBreakpoint(breakpointId: string, enabled: boolean): void; getBreakpoints(): VSBreakpoint[]; addWatch(expression: string): VSWatchExpression; removeWatch(watchId: string): void; updateWatches(context: VSExecutionContext): void; getWatches(): VSWatchExpression[]; pushStack(frame: VSCallStackFrame): void; popStack(): VSCallStackFrame | undefined; getCallStack(): VSCallStackFrame[]; getCurrentFrame(): VSCallStackFrame | null; recordSnapshot(snapshot: VSExecutionSnapshot): void; getHistory(): VSExecutionSnapshot[]; enableProfiling(enabled: boolean): void; recordNodeTime(nodeId: string, timeMs: number): void; getNodeAverageTime(nodeId: string): number; getProfilingData(): VSProfilingData; evaluateExpression(expr: string, context: VSExecutionContext): unknown; private getNestedValue; on(event: VSDebuggerEventType, listener: (event: VSDebuggerEvent) => void): void; off(event: VSDebuggerEventType, listener: (event: VSDebuggerEvent) => void): void; private emit; onNodeStartExecution(nodeId: string, inputs: Record): boolean; onNodeCompleteExecution(nodeId: string, outputs: Record, timeMs: number): void; } export declare class VSGraphExecutor { private nodeLibrary; private debugger; private executionQueue; constructor(debuggerInstance?: VSDebugger); registerNode(definition: VSNodeDefinition): void; registerNodes(definitions: VSNodeDefinition[]): void; getNodeDefinition(type: string): VSNodeDefinition | undefined; getAllNodeDefinitions(): VSNodeDefinition[]; searchNodes(query: string): VSNodeDefinition[]; execute(graph: VSGraph, entryType: string, context: VSExecutionContext): void; executeNode(graph: VSGraph, node: VSNodeInstance, context: VSExecutionContext): void; private followFlowConnections; getDebugger(): VSDebugger; resumeExecution(): void; } export declare function createBuiltInNodes(): VSNodeDefinition[]; export declare function createVSGraph(name: string): VSGraph; export declare function createVSNode(type: string, position: Vec2): VSNodeInstance; export declare function createVSConnection(fromNode: string, fromPort: string, toNode: string, toPort: string): VSConnection; export declare function createVSDebugger(): VSDebugger; export declare function createVSExecutor(debuggerInstance?: VSDebugger): VSGraphExecutor;