Visual Scripts
Visual scripts let you build game logic using a node-based editor — no code required. You connect nodes together to define behaviors, reactions to events, and game flow. Behind the scenes, visual scripts are compiled to JavaScript.
The Visual Editor
The visual editor is built on React Flow and provides a canvas where you create and connect nodes:
- Drag nodes from the node palette onto the canvas
- Connect nodes by dragging from an output port to an input port
- Pan and zoom the canvas to navigate large graphs (the zoom range accommodates very large graphs)
- Minimap in the corner provides an overview of the entire graph
- Color-coded edges help trace data flow between nodes
- Alignment guides — while dragging a node, blue helper lines appear when its edges align with another node, and the node snaps into alignment
- Auto-save — changes are saved automatically a couple of seconds after you stop editing, with a brief "Saved" indicator
Creating a Visual Script
- Open the Scripts tab in the assets panel
- Click the create button and choose to create a visual script
- Provide a name for the script
- The visual editor opens with an empty canvas
Script Scope
Visual scripts have two scope options:
| Scope | Description |
|---|---|
| Entity | Attached to a specific entity. The start(entity) method runs when the entity loads. Use for entity-specific behaviors like movement, reactions, and animations |
| Level | Attached to the level itself. The onCreate() method runs when the level loads. Use for global game logic, initialization, and level-wide event handling |
Node Palette
The node palette is a searchable, categorized list of all available nodes. Drag any node from the palette onto the canvas to add it to your graph. The palette is filtered by script scope — level scripts see level lifecycle events (On Create / On Start / On Update), entity scripts see entity lifecycle events (On Start / On Update).
Event Nodes
Event nodes trigger the connected logic when a specific event occurs:
| Node | Description |
|---|---|
| Keyboard Listener | Fires on key press/release |
| Is Key Pressed | Query whether a key is currently held |
| Mouse Click / Down / Up / Move | Fires on mouse interaction |
| Get Mouse Position | Read the current mouse position |
| Element Click | Fires when a specific entity is clicked |
| Gamepad Button / Axis / Connected | Fires on gamepad input |
| Touch Start / End / Move | Fires on touch screen input |
Entity Nodes
| Node | Description |
|---|---|
| Entity | Reference to a specific entity (use entity picker to select) |
| Self | Reference to the entity this script is attached to |
| Get Position / Rotation / Scale | Read the entity's current transform |
| Get Name | Get the entity's name |
| Find Entity By Name | Look an entity up at runtime |
| Clone Entity | Create a copy of an entity |
| Destroy Entity | Remove an entity from the scene |
| Set Data / Get Data | Store and read arbitrary values on an entity |
Transform Nodes
| Node | Description |
|---|---|
| Set Position / Rotation / Scale | Set absolute transform values |
| Translate | Move relative to current position |
| Look At | Orient entity to face a target |
| Get / Set Position By Key | Read or write one component (x, y, z) of position, chosen by a string key |
| Get / Set Rotation By Key | Read or write one component of rotation by key |
| Get / Set Scale By Key | Read or write one component of scale by key |
| Get / Set Quaternion By Key | Read or write one component of the quaternion by key |
By-key nodes
The By Key nodes take the axis as a key input (a string like "y") instead of a fixed node per axis — handy when the axis is computed or comes from a variable. Passing an invalid key raises a clear runtime error.
Transition Nodes
| Node | Description |
|---|---|
| Go To / Rotate To / Scale To | Smoothly animate to a target value |
| Fade To | Smoothly animate opacity |
Material Nodes
| Node | Description |
|---|---|
| Set Color | Change material color |
| Set Opacity | Change transparency |
| Set Visible | Show or hide entity |
| Set Wireframe | Toggle wireframe rendering |
| Set Metalness / Roughness | Adjust PBR material properties |
| Set Emissive / Emissive Intensity | Control self-illumination |
Animation Nodes
| Node | Description |
|---|---|
| Play Animation | Start an animation by name |
| Stop Animation | Stop a specific animation |
| Stop All Animations | Stop all running animations |
| Crossfade To | Smoothly blend to another animation |
| Set Animation Speed | Change an animation's playback speed |
| Set Animation Weight | Set an animation's blend weight |
Physics Nodes
| Node | Description |
|---|---|
| Enable / Disable Physics | Turn the physics body on or off at runtime |
| Set / Get Linear Velocity | Control linear movement speed |
| Set / Get Angular Velocity | Control rotational speed |
| Get Physics State | Read the body's simulation state |
| On Collision | Fires when the entity collides |
| Set Physics Position / Rotation | Teleport the physics body |
Controls Nodes
| Node | Description |
|---|---|
| First Person Control | Enable first person controls |
| Third Person Control | Enable the third person character controller |
| Disable Controls | Turn active controls off |
Audio Nodes
| Node | Description |
|---|---|
| Play / Stop / Pause Sound | Control audio playback |
| Set Volume | Adjust audio volume |
Light Nodes
| Node | Description |
|---|---|
| Set Light Color | Change light color |
| Set Light Intensity | Change light brightness |
| Set Light Shadow | Toggle shadow casting |
Camera Nodes
| Node | Description |
|---|---|
| Set Camera Position | Move the camera |
| Set Camera Look At | Point the camera at a target |
| Set Orbit Enabled | Enable/disable orbit controls |
Variable Nodes
| Node | Description |
|---|---|
| Number | A numeric constant |
| String | A text constant |
| Vector2 | A 2D vector (X, Y) |
| Vector3 | A 3D vector (X, Y, Z) |
| Quaternion | A quaternion rotation (X, Y, Z, W) |
| Variable Reference | Reuse another variable anywhere in the graph without a long edge — pick any named variable node and its outputs are mirrored |
Logic Nodes
| Node | Description |
|---|---|
| Branch (If/Else) | Route execution based on a condition |
| Lower Than / Greater Than | Numeric comparison |
| Equal / Not Equal | Equality comparison |
| And / Or / Not | Boolean operators |
| Has Tag | Check if an entity has a specific tag |
Math Nodes
| Node | Description |
|---|---|
| Add / Subtract / Multiply / Divide / Modulo | Arithmetic |
| Negate | Invert a value's sign |
| Clamp | Constrain a value to a range |
| Lerp | Linear interpolation between two values |
| Random Float / Random Int | Random number generation |
| Get Distance | Distance between two positions |
| Deg to Rad | Convert degrees to radians |
Tag Nodes
| Node | Description |
|---|---|
| Add Tag | Add a tag to an entity |
| Remove Tag | Remove a tag from an entity |
Debug Nodes
| Node | Description |
|---|---|
| Console Log | Print a value to the console (visible in the preview console) |
Action Nodes
Action nodes are special container nodes. You can drag other nodes inside them to group related logic. This helps organize complex graphs into clear, logical blocks.
Node Groups
Groups bundle several nodes into a single labelled container you can collapse, reuse, and reason about as a unit.
Creating a group
Select two or more nodes, then press Ctrl/Cmd+G — or right-click and choose Group N nodes. The nodes are wrapped in a labelled container.
Collapsing and expanding
Double-click a group to collapse it to a compact node (or expand it again) — collapsed groups expose one handle per boundary port and hide their internals. You can also use Collapse / Expand from the right-click menu.
Group ports
Right-click a node inside a group to Expose input or Expose output for one of its handles — this promotes that handle to a named port on the group's edge, so you can wire the group from outside without expanding it. Exposed ports persist even when nothing is connected; choose Unexpose to remove one.
Ungrouping
Press Ctrl/Cmd+Shift+G, or right-click and choose Ungroup, to dissolve a group back into its individual nodes.
Right-click menu
The canvas context menu adapts to what's under the cursor and offers, as applicable: Group N nodes, Collapse / Expand, Ungroup, Add to library, and per-handle Expose / Unexpose options.
Block Library
A block is a saved, reusable snapshot of a group — its nodes, internal wiring, and ports — that you can drop into any script. Unlike a group (which lives in one script), a block persists in a library and can be reused freely.
Saving a block
Right-click a group and choose Add to library to open the Save block to library dialog:
- Block name — a descriptive name (the group is renamed to match)
- Available in all projects — when on (the default), the block is saved to your account and appears in every project; when off, it's saved to the current project only
Using blocks
The node palette has a Library section at the bottom, split into:
- This project — blocks scoped to the current project
- My library — your account-wide blocks
Each entry shows the block's name and port count. Drag a block onto the canvas to add an instance, or use its delete button to remove it from the library.
Block instances
A dropped block is a read-only instance linked to the library block it came from. You can expand it to see its nodes and wiring, but you can't select, move, delete, or rewire anything inside it, edit its ports, ungroup it, or add it to the library again. Moving and connecting the instance as a whole works like any other group.
To change an instance, right-click it and choose Detach from library (make editable). It becomes an ordinary group that you can edit freely, and it's no longer linked to the library block.
Variable Reference Node
The Variable Reference node lets you reuse a variable's value anywhere in the graph without dragging a long wire across the canvas — pick a named variable and its outputs are mirrored at the reference. See the Variable Nodes list.
Entity Picker
When working with Entity nodes, you can click "Pick from Scene" to enter entity picker mode. The 3D viewport then lets you click on any entity to select it as the reference for that node — no need to type entity names manually.
Compiling
Visual scripts are compiled to JavaScript before they can be used in a build. The compilation:
- Performs a topological sort of the graph
- Generates JavaScript code for each node
- Assembles everything into a class that extends
BaseScript(entity scope) orLevel(level scope)
You can preview the compiled code at any time by opening the compiled code preview modal. Any compilation errors are displayed here as well.
Code Preview
The editor includes a read-only code view that shows the compiled JavaScript output of your visual script. This is useful for understanding what the graph produces and for debugging.
TIP
You can switch between the visual editor and the compiled code view using the mode toggle at the top of the editor.
