CAUTION
Input and output channels are an experimental feature and may produce unpredictable or mixed results. Special care is especially advised in batch runs that log data, which can result in large sets of files being written on your hard drive.
Utomata separates computation from the systems that provide data to it and receive data from it.
Fields, formations, and triggers describe what the program computes. Input and output define how values cross the boundary between that program and its host environment.
The division of responsibilities is deliberately strict:
- the Utomata program decides what data is read or produced and when
- the host decides where it comes from or where it goes
This keeps the language independent of filesystems, cameras, terminals, and other environment-specific systems.
Input Values
There are two main ways to introduce changing external values into a Utomata program: uniforms for dynamic numerical values, stream markers for externally supplied realtime data, and source markers for modular source code variations.
Uniform values change data already available to the compiled program. Stream markers indicate large external data inputs, such as a webcam video stream. A source marker is placeholder for Utomata source code, and may therefore alter meaningful sections of a program, such as dimensions, topology, expressions, or other structural properties.
Uniforms
Uniforms provide the simplest runtime input mechanism.
They are declared at top level with the $ sigil:
$threshold = 0.5;
and can be used like ordinary values inside expressions:
#A {
run = lrg(#, $threshold);
}
As elsewhere in Utomata, scalar values are lifted to three component vectors.
Uniform values may be changed by the host while the program is running. Updating a uniform writes a new value into the existing GPU binding and does not require recompilation.
This makes uniforms appropriate for parameters that may change frequently:
$speed = 0.01;
$scale = (4 , 4, 1);
$threshold = -0.5;
Changing the resolution or structure of a field is different. Properties such as dim are compile-time configuration and cannot be driven by a runtime uniform. For those cases, source markers provide the appropriate mechanism.
Input Streams
Streams provide external data that can be sampled by Utomata expressions.
A named stream is referenced through angle brackets:
#cam{
dim = (64, 48, 1);
run = <camera>
}
For image-like inputs, this resolves to an input stream that can be sampled by fields or formations.
Streams are independent of field dimensions. Their native resolution is mapped across normalized coordinates when sampled, so a stream does not need to match the resolution of the field reading it. A typical image input can therefore be treated like another spatial data source without first copying it into a field.
The runtime currently supports image streams directly. The same stream abstraction is also used by the desktop host for webcam input, where new image frames are uploaded continuously while the program runs.
Source Markers
The same <name> syntax can also represent a value that is substituted directly into the source before compilation.
This is useful when an input needs to change something structural:
#A {
dim = <size>;
}
A uniform cannot change dim, because the field dimensions are fixed when the program is compiled. A source marker can, because its value becomes part of the source itself. Changing such a marker therefore requires recompilation.
This is the central trade-off:
$uniform -> change a runtime value
<marker> -> change the source
Source markers should normally define a fallback value so the program remains valid before an external sequence begins:
<size> -> 64
The fallback is used while editing or whenever no active input value has been supplied. Without one, a program containing the marker may have no valid source to compile outside the input run.
When a marker's input advances, Utomata substitutes the new value and waits for the resulting program to finish recompiling before execution continues. This makes structural parameter sweeps possible without exposing compilation logic inside the Utomata language itself.
Advancing Source markers
Source input files like .jsonl typically contain several entries.
They can be advanced explicitly by the host, or from a trigger during batch execution:
@advance(step == 100) {
next();
}
next() advances the input bindings currently used by the program. A particular binding may also be advanced independently by the host.
The collection itself is not stored by Utomata. The host owns the sequence and supplies one value at a time. This allows an input to represent anything from a folder of images to a large dataset or a value generated dynamically during the run.
Output
Output is initiated from triggers using log().
@snapshot(step % 10 == 0) {
log(#A, frames);
}
The first argument selects the data — a whole field, or a single cell:
log(#A[0, 0], probe);
The second argument names an output channel. A keyless form is also available for simple diagnostic output:
log(#A[0, 0]);
As described in the Triggers chapter, log() and the other output actions operate only during batch or offline execution. They do not emit output during normal realtime execution.
Output Formats
Output channels currently support three formats:
| Format | Result |
|---|---|
image |
image output, written as .png by file-based hosts |
txt |
text rows |
jsonl |
JSON Lines rows |
The format name is image, not png. PNG is an encoding used by hosts when writing an image artifact to disk. Raw binary output is not currently an author-facing output format.
Whole-field logging is required for image output. A single-cell lookup produces only one sampled value and therefore cannot produce an image.
Output Rows
Several logged values can contribute to the same output row.
For example:
@sample(step % 10 == 0) {
log(#A[0, 0], x);
log(#B[0, 0], y);
}
may produce a row containing both x and y.
A row is completed when one of its keys is encountered again, or when the output is explicitly flushed or ended.
Conceptually:
log(..., x)
log(..., y)
log(..., x)
commits the first { x, y } observation when the second x begins the next one.
This allows repeated measurements to accumulate naturally without requiring flush() after every row.
Batch Input and Output
Inputs and outputs become especially useful together during batch execution.
For example:
$threshold = 0.5;
#SIM {
dim = (<gridSize>, <gridSize>, 1);
set = rand(1, 2, 3);
run = ...;
}
@snapshot(step % 10 == 0) {
log(#SIM, frames);
}
@probe(step % 10 == 0) {
log(#SIM[0, 0], values);
}
@finish(step == 300) {
next();
end();
}
Here three different kinds of external control coexist:
$thresholdcan change without recompiling<gridSize>can change the structure of the program and therefore recompileslog()sends computed results back to the host
The language does not need to know whether those values came from a file, an interface, a camera, or another process. Those concerns remain with the host.
Host Support
Input and output capabilities depend partly on the environment running Utomata.
The desktop application currently provides the most complete implementation, including runtime uniforms, file-backed input sequences, image inputs, webcams, recompilation for source markers, and output handling.
Some headless and CLI paths remain less complete. In particular, image input under Node/Dawn is currently unavailable, and headless image encoding still depends on unresolved host-side support. These are host limitations rather than limitations of the Utomata language or bridge model.
The important architectural rule is therefore to treat input and output as capabilities supplied by the host. A program may describe an input or output operation correctly even when a particular host cannot currently provide that capability.
Input & Output Reference
Runtime Inputs
| Syntax | Role | Description |
|---|---|---|
$name |
uniform | runtime vec3 value; changing it does not recompile |
<name> |
input / marker | external stream or source substitution |
INPUT(name) |
stream sample | internal form used to sample a bound stream |
Output Actions
| Action | Description |
|---|---|
log(#A, key) |
output a whole field |
log(#A[x,y], key) |
output a single sampled field value |
log(#A[x,y]) |
keyless diagnostic output |
flush() |
commit pending output rows |
end() |
finish the batch run |
Output Formats
| Name | Description |
|---|---|
image |
image artifact |
txt |
text rows |
jsonl |
JSON Lines rows |
Input and output deliberately remain outside Utomata's computational core. Uniforms expose inexpensive runtime values, streams expose external spatial data, source markers allow structural variation, and triggers determine when data enters or leaves a run.
Together they let a Utomata program participate in a larger system without making files, cameras, datasets, or host-specific APIs part of the language itself.