Core DSL Built-ins Reference

Core built-ins are primitive operations registered by the NodeForge add-on and available without imports.

Type Names

Type Meaning
Geometry Blender geometry socket.
Float Numeric value or field.
Int Integer value or field.
Bool Boolean value or field.
Vector 3-component vector value or field.
Material Blender material socket.
Object Blender object socket with Object Info access.
String Blender string socket. String literals can also be used as compile-time names and options.
Bundle Blender bundle socket containing named runtime values.
Float, Int, Bool, Vector, Geometry, Material, Object, String, Bundle Type tokens used by node(..., typ=...), node(..., outputs=...), local parameter annotations, and bundle_get(..., typ=...).

NodeForge values are typed socket wrappers. A value can be a constant lowered to a node, a linked runtime field, or geometry. Most built-ins accept either literal values or runtime values of the declared type.

Compile-Time Constants

NodeForge exposes three numeric constants in every source file.

Constant Value
pi π, approximately 3.141592653589793
tau 2π, approximately 6.283185307179586
e Euler’s number, approximately 2.718281828459045
turn = tau
half_turn = pi
base = e
output('Turn', turn)
output('Half Turn', half_turn)
output('Base', base)

Compile-Time Helper Calls

These helpers are evaluated during compilation. They do not create Geometry Nodes sockets and cannot operate on runtime values.

range(stop)

range(start, stop)

range(start, stop, step)

Creates a compile-time list of integers. Use it mainly for unrolled for loops or compile-time indexing.

Parameter Type Description
start compile-time Int First integer. Defaults to 0.
stop compile-time Int Exclusive upper bound.
step compile-time Int Step size. Defaults to 1.

Returns: compile-time List[Int].

BASE_COUNT = 4
EXTRA_COUNT = 2
COUNT = BASE_COUNT + EXTRA_COUNT

items = []
for i in range(COUNT):
    offset = vector(i * 1.25, 0, 0)
    geo = cube(size=1.0)
    moved = transform(geo, translation=offset)
    items.append(moved)
result = join(items)
output('Geometry', result)

len(value)

Returns the length of a compile-time list, tuple, or string.

Parameter Type Description
value compile-time List, Tuple, or String Sequence whose length is known during compilation.

Returns: compile-time Int.

sizes = [0.5, 1.0, 1.5]
count = len(sizes)
step = 1.0 / count
value = input_float('Value', default=step)
output('Value', value)

sum(value)

Returns the numeric sum of a compile-time list or tuple.

Parameter Type Description
value compile-time numeric List or Tuple Sequence whose elements can be added during compilation.

Returns: compile-time number.

sizes = [0.5, 1.0, 1.5]
total = sum(sizes)
count = len(sizes)
average = total / count
geo = cube(size=average)
output('Geometry', geo)

Outputs

output(value)

output(name, value)

output(name="Name", value=value)

Creates a group output socket and connects a runtime value to it.

Parameter Type Description
name String Optional output socket name. When omitted, the output socket is named out. Duplicate output names receive suffixes such as _2.
value runtime value Float, Int, Bool, Vector, Geometry, Material, Object, String, or Bundle value to expose on the node group. Arrays and multi-output results cannot be output directly; index or unpack them first.

Returns: statement only.

geo = cube(size=2.0)
height = input_float('Height', default=1.0)
vec_1 = vector(1, 1, height)
geo_2 = transform(geo, scale=vec_1)
output('Geometry', geo_2)
output(name='Height', value=height)

Automatic final outputs are part of the source language semantics. See DSL Syntax and Semantics.

Active Geometry stream statements

These statement-only forms operate on an implicit Geometry input/output stream. When a script contains store(...) or statement-form set_position(...), NodeForge creates a Geometry group input named Geometry and a Geometry group output named Geometry.

Use these forms when the node group is meant to modify geometry that is passed into it. Use expression-form store_named_attribute(geometry, ...) and set_position(geometry, ...) when you want to operate on an explicit Geometry value inside the script.

store(name, value, selection=True, domain="POINT", type=None)

Stores a named attribute on the active Geometry stream.

Parameter Type Default Description
name compile-time or runtime String required Attribute name.
value Float, Int, Bool, or Vector required Attribute value field. Arrays are rejected.
selection Bool True Optional field mask.
domain compile-time String "POINT" "POINT", "EDGE", "FACE", "CORNER", "CURVE", or "INSTANCE".
type compile-time String or None None Optional Blender data type override, for example "FLOAT", "INT", "BOOLEAN", "VECTOR", or "COLOR".

Returns: statement only.

height = position().z
store('height', height, domain='POINT', type='FLOAT')

The attribute name can come from input_string(...) when it must be selected at runtime.

set_position(position, selection=True)

Sets point positions on the active Geometry stream.

Parameter Type Default Description
position Vector required New position field.
selection Bool True Optional field mask.

Returns: statement only.

pos = position()
height = pos.x * 0.5
offset = vector(0, 0, height)
new_pos = pos + offset
set_position(new_pos)

Inputs

Input built-ins create group input sockets. The name argument must be a compile-time string. Defaults must be compile-time values.

Use each input_*() call as the complete right-hand side of a simple assignment. Every call creates a separate interface socket; name is its displayed label rather than the identity of the declaration. Two declarations may therefore use the same label and keep independent defaults.

input_geometry(name)

Creates a Geometry input socket.

Parameter Type Default Description
name String required Input socket name.

Returns: Geometry.

geo = input_geometry('Geometry')
vec_1 = vector(1.5, 1.5, 1.5)
geo_2 = transform(geo, scale=vec_1)
output('Geometry', geo_2)

input_float(name, default=0.0)

Creates a Float input socket.

Parameter Type Default Description
name String required Input socket name.
default compile-time Float 0.0 Socket default value.

Returns: Float.

radius = input_float('Radius', default=2.0)
geo_1 = cube(size=radius)
output('Geometry', geo_1)

input_int(name, default=0)

Creates an Int input socket.

Parameter Type Default Description
name String required Input socket name.
default compile-time Int 0 Socket default value. Numeric constants are converted to integer defaults.

Returns: Int.

count = input_int('Count', default=32)
geo = points(count)
output('Geometry', geo)

input_bool(name, default=False)

Creates a Bool input socket.

Parameter Type Default Description
name String required Input socket name.
default compile-time Bool False Socket default value.

Returns: Bool.

enabled = input_bool('Enabled', default=True)
output('Enabled', enabled)

input_vector(name, default=vector(0, 0, 0))

Creates a Vector input socket.

Parameter Type Default Description
name String required Input socket name.
default compile-time Vector or 3-number tuple/list vector(0, 0, 0) Socket default value.

Returns: Vector.

vec_1 = vector(0, 0, 2)
offset = input_vector('Offset', default=vec_1)
geo_2 = cube()
geo_3 = transform(geo_2, translation=offset)
output('Geometry', geo_3)

input_material(name)

Creates a Material input socket.

Parameter Type Default Description
name String required Input socket name.

Returns: Material.

material = input_material('Material')
geo = set_material(cube(size=1.0), material)
output('Geometry', geo)

input_object(name)

Creates an Object input socket. Read the selected object's geometry and transforms through the Object properties described in Object values.

Parameter Type Default Description
name String required Input socket name.

Returns: Object.

source = input_object('Source')
source.info(transform_space='RELATIVE', as_instance=False)
output('Geometry', source.geometry)

input_string(name, default="")

Creates a String input socket.

Parameter Type Default Description
name compile-time String required Input socket name.
default compile-time String "" Socket default value.

Returns: runtime String.

attribute_name = input_string('Attribute', default='weight')
geo = store_named_attribute(cube(), attribute_name, position().z)
output('Geometry', geo)

input_bundle(name)

Creates a Bundle input socket.

Parameter Type Default Description
name String required Input socket name.

Returns: Bundle.

data = input_bundle('Data')
factor = bundle_get(data, 'factor', typ=Float)
output('Factor', factor)

Interface Panels

panel([input_a, input_b, ...], name="Name", collapsed=False)

Places existing group input sockets in a native Blender interface panel. Write panel(...) as a standalone top-level declaration after the referenced inputs.

Parameter Type Default Description
inputs literal list or tuple of input variable names required One or more group inputs in their panel order.
name compile-time String required Non-empty panel name. Panel names must be unique.
collapsed compile-time Bool False Whether the panel is closed by default.

Returns: statement only.

Each group input can belong to one panel. Inputs omitted from panel(...) remain at the root of the group interface. The DSL creates root-level panels. Computed values and function results are not interface inputs and cannot be panel members.

radius = input_float('Radius', default=1.0)
segments = input_int('Segments', default=32)
panel([radius, segments], name='Shape', collapsed=True)

geo = cube(size=radius)
output('Geometry', geo)

Object Values

An Object value exposes the outputs of Blender's Object Info node as properties.

Property Returns Description
.geometry Geometry Geometry from the selected object.
.location Vector Object location in the configured transform space.
.rotation Vector Object rotation.
.scale Vector Object scale.

object.info(transform_space="ORIGINAL", as_instance=True)

Configures the Object Info node used by subsequent property access and returns the same Object value.

Parameter Type Default Description
transform_space compile-time String "ORIGINAL" "ORIGINAL" or "RELATIVE".
as_instance compile-time Bool True Return geometry as an instance when enabled.

You may call .info() more than once to set the options separately. Configure it before reading any Object property; the configuration is fixed when the first property creates the Object Info node.

source = input_object('Source')
source.info(transform_space='RELATIVE')
source.info(as_instance=False)

offset = source.location
geo = transform(source.geometry, translation=-offset)
output('Geometry', geo)

Bundles

Bundles carry named runtime values through one Blender socket. Bundle items support Float, Int, Bool, Vector, Geometry, Material, Object, String, and nested Bundle values. Bundles can cross group and reusable-function sockets and can be carried through runtime if and repeat_range(...) state.

bundle(**items)

Creates a Bundle from named keyword items. The keyword names become item names.

Returns: Bundle.

weight = input_float('Weight', default=0.5)
data = bundle(
    geometry=cube(size=1.0),
    weight=weight,
)
output('Data', data)

bundle_get(bundle, path, typ=Type)

Reads an item from a Bundle.

Parameter Type Description
bundle Bundle Bundle to read.
path String Runtime bundle item path.
typ type token Expected item type and output socket type.

Returns: the runtime type selected by typ.

typ= is required because an incoming Bundle does not declare the type of each item to the script. The path can be a string literal or a runtime String.

data = input_bundle('Data')
path = input_string('Path', default='weight')
weight = bundle_get(data, path, typ=Float)
output('Weight', weight)

bundle_set(bundle, path, value)

Stores or replaces one item and returns the resulting Bundle.

Parameter Type Description
bundle Bundle Input Bundle.
path String Runtime bundle item path.
value supported runtime value Item value to store.

Returns: Bundle.

The stored item type is inferred from value.

data = input_bundle('Data')
path = input_string('Path', default='weight')
weight = input_float('Weight', default=1.0)
updated = bundle_set(data, path, weight)
output('Data', updated)

Field inputs

Field built-ins read Blender Geometry Nodes context fields. They take no arguments and do not accept keywords.

Function Returns Description
position() Vector Current element position field.
normal() Vector Current element normal field.
index() Int Current element index field.
id() Int Current element ID field.

position()

Returns the current element position field. Use it when a formula should be relative to the existing point or vertex position.

pts = points(32)
base_position = position()
offset = vector(0, 0, 1)
new_position = base_position + offset
pts = set_position(pts, new_position)
output('Geometry', pts)

normal()

Returns the current element normal field. Use it for displacement or orientation formulas that depend on surface direction.

geo = cube(size=2.0)
surface_normal = normal()
displacement = surface_normal * 0.25
base_position = position()
new_position = base_position + displacement
geo = set_position(geo, new_position)
output('Geometry', geo)

index()

Returns the current element index field. Use it for per-element spacing, alternating patterns, and procedural ordering.

pts = points(32)
i = index()
x = i * 0.1
z = i * 0.25
pos = vector(x, 0, z)
pts = set_position(pts, pos)
output('Geometry', pts)

id()

Returns the current element ID field. Use it as a stable per-element random seed when available.

pts = points(64)
element_id = id()
offset = (element_id % 10) * 0.1
base_position = position()
delta = vector(0, 0, offset)
new_position = base_position + delta
pts = set_position(pts, new_position)
output('Geometry', pts)

Vector construction and vector math

vector(x, y, z)

Creates a Vector from three numeric components. Positional arguments and x=, y=, z= keywords are supported.

Parameter Type Description
x Float X component.
y Float Y component.
z Float Z component.

Returns: Vector.

height = input_float('Height', default=2.0)
offset = vector(x=0.0, y=0.0, z=height)
geo_1 = cube()
geo_2 = transform(geo_1, translation=offset)
output('Geometry', geo_2)

Vector components can be read with .x, .y, and .z.

vec_1 = vector(1, 2, 3)
v = input_vector('Vector', default=vec_1)
vec_2 = vector(v.x, v.y, 0)
value_3 = length(vec_2)
output('Length XY', value_3)

Vector functions

Function Signature Returns Description
length length(v) Float Vector length.
distance distance(a, b) Float Distance between two vectors.
dot dot(a, b) Float Dot product.
normalize normalize(v) Vector Normalized vector.
cross cross(a, b) Vector Cross product.
reflect reflect(a, b) Vector Reflection vector.
project project(a, b) Vector Projection vector.
vec_1 = vector(1, 1, 0)
n = normalize(vec_1)
vec_2 = vector(0, 0, 1)
side = cross(n, vec_2)
pos = n + side * 0.5
output('Position', pos)

Geometry

points(count)

Creates point geometry with count points.

Parameter Type Description
count Int Number of points. Compile-time constants and runtime Int values are supported.

Returns: Geometry.

count = input_int('Count', default=32)
pts = points(count)
value_1 = index()
vec_2 = vector(value_1 * 0.1, 0, 0)
pts = set_position(pts, vec_2)
output('Geometry', pts)

grid(width, height)

Creates a planar mesh grid on the XY plane and stores the generated UV field for grid_uv() in the current script scope.

Parameter Type Description
width Int Number of vertices in X.
height Int Number of vertices in Y.

Returns: Geometry.

geo = grid(16, 16)
uv = grid_uv()
height = (uv.x + uv.y) * 0.5
position = vector(uv.x * 2.0, uv.y * 2.0, height)
geo = set_position(geo, position)
output('Geometry', geo)

grid_uv()

Returns the UV coordinates produced by the most recent grid(width, height) call in the current script scope. grid_uv() requires a preceding grid(...) call.

Returns: Vector with .x and .y in the 0..1 range.

geo = grid(8, 8)
uv = grid_uv()
height = (uv.x - 0.5) * (uv.y - 0.5)
base_position = position()
offset = vector(0, 0, height)
geo = set_position(geo, base_position + offset)
output('Geometry', geo)

set_position(geometry, position, selection=True)

Sets point positions on geometry.

Parameter Type Default Description
geometry Geometry required Input geometry.
position Vector required New position field.
selection Bool True Optional field mask.

Returns: Geometry.

pts = points(32)
i = index()
mask = (i % 2) == 0
pos = vector(i * 0.1, 0, i * 0.02)
pts = set_position(pts, pos, selection=mask)
output('Geometry', pts)

store_named_attribute(geometry, name, value, selection=True, domain="POINT", type=None)

Stores a named attribute on geometry.

Parameter Type Default Description
geometry Geometry required Input geometry.
name compile-time or runtime String required Attribute name.
value Float, Int, Bool, or Vector required Attribute value field. Arrays are rejected.
selection Bool True Optional field mask.
domain compile-time String "POINT" "POINT", "EDGE", "FACE", "CORNER", "CURVE", or "INSTANCE".
type compile-time String or None None Optional Blender data type override, for example "FLOAT", "INT", "BOOLEAN", "VECTOR", or "COLOR".

Returns: Geometry.

pts = points(64)
i = index()
height = i * 0.02
pos = vector(i * 0.05, 0, height)
pts = set_position(pts, pos)
pts = store_named_attribute(pts, 'height', height, domain='POINT', type='FLOAT')
output('Geometry', pts)

The attribute name can also be a runtime String, for example a value returned by input_string(...).

capture_attribute(geometry, value, selection=True, domain="POINT", type=None)

Captures a field on geometry as an anonymous attribute. The function returns both the updated Geometry and the captured field value.

Parameter Type Default Description
geometry Geometry required Geometry on which to capture the field.
value Float, Int, Bool, or Vector required Field to capture.
selection Bool True Optional field mask.
domain compile-time String "POINT" "POINT", "EDGE", "FACE", "CORNER", "CURVE", or "INSTANCE".
type compile-time String or None None Optional result type override: "FLOAT", "INT", "BOOLEAN", or "VECTOR". The value type is used when omitted.

Returns: (Geometry, captured value).

geo = grid(16, 16)
height = position().z
geo, captured_height = capture_attribute(
    geo,
    height,
    domain='POINT',
)
output('Geometry', geo)
output('Height', captured_height)

The two results can also be stored as one result and selected with a compile-time index.

captured = capture_attribute(cube(), normal())
geo = captured[0]
captured_normal = captured[1]

set_material(geometry, material)

Assigns a material to geometry. Pass a runtime Material value or a compile-time material name. A named material is created when it does not exist.

Parameter Type Description
geometry Geometry Input geometry.
material Material or compile-time String Material socket value or Blender material name.

Returns: Geometry.

geo = cube(size=2.0)
geo = set_material(geo, 'NodeForge Material')
output('Geometry', geo)
material = input_material('Material')
geo = set_material(cube(size=2.0), material)
output('Geometry', geo)

empty_geometry()

Creates a valid Geometry value with zero elements. Use it as the neutral starting value for generated geometry collections, optional branches, and repeat-loop accumulators.

Returns: Geometry.

geo = empty_geometry()
count = input_int('Count', default=3)
for i in repeat_range(count):
    part = transform(cube(0.25), translation=vector(i, 0, 0))
    geo = join(geo, part)
output('Geometry', geo)

geometry_builder()

Creates a script-local Geometry accumulator for procedural construction. The builder is a compiler object, not a Geometry value. Add Geometry values with add(...) or extend(...), then read builder.geometry when a Geometry snapshot is needed.

Supported operations:

Operation Description
builder.add(geometry) Append one Geometry value.
builder.extend([geometry_a, geometry_b]) Append an array of Geometry values in order.
builder.geometry Return the accumulated Geometry at that source position.

A new builder with no additions returns the same empty Geometry value as empty_geometry(). Builder objects cannot be output, aliased, captured by local functions, or passed to built-ins; use builder.geometry whenever a normal Geometry value is required.

builder = geometry_builder()
for size in [0.5, 1.0, 1.5]:
    builder.add(cube(size))
output('Geometry', builder.geometry)

Inside repeat_range(...), builder mutations become Repeat Zone Geometry state updates. The same builder can combine compile-time additions, runtime-loop additions, and post-loop additions.

builder = geometry_builder()
pos = vector(0, 0, 0)
steps = input_int('Steps', default=4)
for i in repeat_range(steps):
    next_pos = pos + vector(1, 0, 0)
    builder.add(line(pos, next_pos))
    pos = next_pos
output('Geometry', builder.geometry)

point(position)

Creates one point and sets its position. position can be a literal vector expression or a runtime Vector value.

Parameter Type Description
position Vector Point position.

Returns: Geometry.

pos = input_vector('Position', default=(0, 0, 1))
geo = point(pos)
output('Geometry', geo)

line(start, end)

Creates a curve line segment between two endpoints. start and end can be literal vector expressions or runtime Vector values.

Parameter Type Description
start Vector Start endpoint.
end Vector End endpoint.

Returns: Geometry.

start = input_vector('Start', default=(0, 0, 0))
end = input_vector('End', default=(1, 0, 0))
geo = line(start, end)
output('Geometry', geo)

cube(size=1.0)

Creates a cube mesh.

Parameter Type Default Description
size Float, Int, or Vector 1.0 Cube side length or per-axis size. Positional and size= forms are supported.

Returns: Geometry.

size = input_float('Size', default=1.0)
geo_1 = cube(size=size)
output('Geometry', geo_1)

join(geometry, ...)

join([geometry_a, geometry_b, ...])

Joins multiple geometry values. Arguments can be separate geometry values, arrays of geometry values, or one literal list/tuple of geometry values. A supplied empty array such as join([]) returns empty_geometry(). A call with no arguments is still invalid.

Parameter Type Description
geometry Geometry values or an array of Geometry values Geometry values to join. A supplied array may be empty.

Returns: Geometry.

geo_1 = cube(size=0.4)
vec_2 = vector(-1, 0, 0)
geo_3 = transform(geo_1, translation=vec_2)
geo_4 = cube(size=0.4)
vec_5 = vector(1, 0, 0)
geo_6 = transform(geo_4, translation=vec_5)
geo_7 = points(8)
parts = [geo_3, geo_6, geo_7]
geo_8 = join(parts)
output('Geometry', geo_8)

empty_parts = []
empty = join(empty_parts)

transform(geometry, translation=None, scale=None, rotation=None)

Transforms geometry. translation, scale, and rotation can be supplied by keyword. The first two transform options can also be supplied as positional arguments after geometry.

Parameter Type Default Description
geometry Geometry required Input geometry.
translation Vector no transform Translation vector.
scale Float, Int, or Vector no transform Scale value. Use vector(x, y, z) for non-uniform scale.
rotation Vector no transform Euler rotation in radians.

Returns: Geometry.

geo = cube(size=1.0)
vec_1 = vector(0, 0, 1)
vec_2 = vector(2, 1, 0.5)
geo = transform(geo, translation=vec_1, scale=vec_2)
output('Geometry', geo)

polyline(points)

Creates curve geometry from a compile-time list of vector points.

Parameter Type Description
points compile-time list of vectors Ordered points for the polyline.

Returns: Geometry.

vec_1 = vector(-1, 0, 0)
vec_2 = vector(0, 1, 0)
vec_3 = vector(1, 0, 0)
shape = polyline([vec_1, vec_2, vec_3])
output('Geometry', shape)

Instancing

instance_on_points(instance, points, selection=True, scale=None, rotation=None, realize=True)

Instances one geometry value on point geometry.

Parameter Type Default Description
instance Geometry required Geometry to instance.
points Geometry required Point geometry receiving the instances.
selection Bool True Points on which to create instances.
scale value accepted by the underlying instance helper Blender default Optional instance scale.
rotation value accepted by the underlying instance helper Blender default Optional instance rotation.
realize compile-time Bool True When true, realizes instances before returning.

Returns: Geometry.

pts = points(12)
value_1 = index()
vec_2 = vector(value_1 * 0.3, 0, 0)
pts = set_position(pts, vec_2)
geo_3 = cube(size=0.15)
vec_4 = vector(1, 1, 1)
selection = index() % 2 == 0
geo = instance_on_points(geo_3, pts, selection=selection, scale=vec_4, realize=True)
output('Geometry', geo)

realize_instances(geometry)

Realizes instances on geometry.

Parameter Type Description
geometry Geometry Geometry containing instances.

Returns: Geometry.

pts = points(6)
geo_1 = cube(size=0.2)
instanced = instance_on_points(geo_1, pts, realize=False)
geo_2 = realize_instances(instanced)
output('Geometry', geo_2)

Raw Blender node construction

node(bl_idname, props={...}, inputs={...}, output=..., typ=...)

node(bl_idname, props={...}, inputs={...}, outputs={...})

Creates a Blender node directly. Use this for Blender node types that are not exposed through a dedicated NodeForge built-in. The dictionary expressions shown here are a special compile-time syntax accepted only in arguments to node(...); general DSL dictionaries remain unsupported.

bl_idname, props keys and values, input socket names, output socket names, and type tokens are compile-time declarations. Runtime values are allowed inside inputs={...} and are linked to the corresponding Blender input socket.

Single-output mode requires both output= and typ=. Multi-output mode uses outputs={"Socket": TypeToken, ...} and returns a result object whose outputs can be accessed with attribute syntax or item syntax.

Supported type tokens: Float, Int, Bool, Vector, Geometry, Material, Object, String, and Bundle.

Parameter Type Default Description
bl_idname String required Blender node type identifier, for example "ShaderNodeMath".
props literal dict {} Blender node properties to assign before linking inputs. Custom properties are not supported.
inputs literal dict {} Maps enabled input socket names to literal defaults, runtime values, or a literal list for multi-input fanout.
output String required in single-output mode Enabled output socket name to return.
typ type token required in single-output mode NodeForge type of output.
outputs literal dict of String: type token required in multi-output mode Enabled output sockets to expose.

Returns: a Value in single-output mode; a multi-output result in outputs= mode.

value = input_float('Value', default=0.25)
rounded = node('ShaderNodeMath', props={'operation': 'ROUND'}, inputs={'Value': value}, output='Value', typ=Float)
output('Rounded', rounded)
value_1 = position()
separate = node('ShaderNodeSeparateXYZ', inputs={'Vector': value_1}, outputs={'X': Float, 'Y': Float, 'Z': Float})
height = separate.Z
output('Height', height)

Runtime loops

Runtime loops compile to Blender Repeat Zones. Use repeat_range(...) when the iteration count or loop state must be represented in the generated Geometry Nodes graph. Use compile-time range(...) for fixed authoring loops that should be unrolled during compilation.

for i in repeat_range(steps): ...

Updates existing Geometry, Vector, Float, Int, Bool, and Bundle variables inside one Repeat Zone. The body supports assignments, geometry_builder method statements, nested if blocks, and nested repeat_range(...) loops. It must update at least one existing variable or builder state. Assigned names that did not exist before the loop are iteration-local temporaries rather than Repeat Zone state items.

State item order follows first assignment in the loop body, including nested branches. Conditional branches preserve omitted state values and merge changed state through Switch nodes. The loop index name cannot also be state, and state names cannot collide with Repeat Zone system socket names such as Iterations or Iteration.

Part Type Description
steps Int Repeat count. May be an integer literal, compile-time integer, or runtime Int value.
state variables Geometry, Vector, Float, Int, Bool, or Bundle Existing variables assigned inside the loop.
n = input_int('N', default=8)
geo = cube(0.1)
pos = vector(0, 0, 0)
angle = input_float('Angle', default=45)
for i in repeat_range(n):
    next_pos = pos + vector(1, 0, 0)
    part = transform(cube(0.05), translation=next_pos)
    geo = join(geo, part)
    pos = next_pos
    angle = -angle
output('Geometry', geo)
output('Position', pos)
output('Angle', angle)

range(...) does not create Repeat Zones. A non-constant range(...) count raises CompileError; use repeat_range(...) for runtime repetition.

Lists, tuples, and unrolled loops

Script lists and tuples are compile-time collections of compiled values. They are useful for building a fixed list of geometry parts and then passing the list to join(...).

parts = []
vec_1 = vector(-1, 0, 0)
vec_2 = vector(0, 0, 0)
vec_3 = vector(1, 0, 0)
for offset in [vec_1, vec_2, vec_3]:
    geo_4 = cube(size=0.25)
    geo_5 = transform(geo_4, translation=offset)
    parts.append(geo_5)
geo_6 = join(parts)
output('Geometry', geo_6)

Lists and tuples cannot be output directly and cannot be used as runtime socket values.