Eos Lightmedia · R+D

CNDL

A plain-text scene format for addressable lighting.

The idea

An open scene format for lighting.

A plain-text file format, a small set of rules, and deterministic output. No cue lists, no timelines, no transport layer. What it doesn't do is left to the runtime.

CNDL Maker showing text editor, node graph, and 3D point-cloud preview
Plain text, spatial by default

Each line is one named operation.

The runtime evaluates them per frame, per fixture, using the fixture's physical coordinates, frame timing, and any number of input signals. Because animations are tied to coordinates, the result is inherently spatial: a wave travels along whatever physical path the fixtures follow, regardless of the layout.

Example

A complete scene in plain text

Coordinates as color, time as a pulse. An external input controls the speed.

RX01  SPEED                   # external speed control
MULT  SCALED    SPEED  TIME   # scale time by speed
MOVE  TIMELINE  TIMELINE SCALED # accumulate
LOOP  PHASE     TIMELINE      # wrap to 0..1
WAVE  PULSE     PHASE         # smooth sine pulse
TX01  RED       XPOS          # output red from X position
TX02  GREEN     YPOS          # output green from Y position
TX03  BLUE      PULSE         # output blue from pulse
The pipeline

Three stages, every frame

Inputs feed operations, operations feed outputs.

1 · Inputs

Coordinates, signals, time.

Fixture positions (XPOS, YPOS, ZPOS), typically from a survey or layout file. Frame delta (TIME). Any number of external signals (RX01, RX02, …) for sliders, sensors, or upstream control. Two random sources: RAND (per frame) and SNOW (per fixture).

2 · Processing

Named operations, evaluated in order.

Each line is an opcode, a name, and its parameters. Nodes reference other nodes by name — including themselves. Self-reference is a feedback loop: the core technique for accumulators, decays, and time-based animation without a timeline.

3 · Outputs

Channel values, clamped 0–1.

Any number of TX channels (TX01, TX02, …) per scene. Each TX binds a computed node to an output column. What those columns mean (RGB, RGBW, intensity, etc.) is up to the runtime and the fixtures it drives.

Primitives

The operation set

A minimal set of compute primitives and any number of input and output channels. Every scene is composed from this set.

Sources

XPOS · YPOS · ZPOS
Where each fixture is physical position from your layout — a wave across XPOS travels along your installation
TIME
How long since the last frame use it to make things move — multiply by TIME to get smooth, speed-independent animation
RAND
A random number that changes every frame same value for all fixtures — use it for global flicker, random color shifts, or chaos
SNOW
A random number per fixture, per frame every fixture gets its own value — TV-static sparkle, snowfall, or independent shimmer

Arithmetic

MOVE
Add two values together layer effects on top of each other, combine signals, offset a position
DIFF
Subtract one value from another measure the distance between a fader and a fixture, remove a baseline
MULT
Multiply two values scale intensity with a fader, control speed, dim a channel
DIVI
Divide one value by another safe — returns 0 if you divide by zero

Functions

FADE
Smoothly blend between two values the workhorse — crossfade between looks, ease toward a target, create trails and decays
GATE
On or off at a threshold turns a smooth signal into a hard cut — fixtures are either on (1) or off (0)
LOOP
Wrap a value back to 0 when it passes 1 repeating ramps, chases, and tiling patterns that cycle endlessly
WAVE
A smooth sine pulse from 0 to 1 and back the building block for breathing, pulsing, and oscillating effects
ABSO
Make negative values positive mirror a signal around zero — a V-shape instead of a line, bounce instead of cross
CLIP
Keep a value within bounds clamp between a low and high — prevent overshoot, limit intensity, create hard edges in soft effects

Channels

RXnn
Receive a signal from the outside world a fader, a sensor, a button, a timecode input — anything that feeds into your scene
TXnn
Send a value to your fixtures each TX is one output channel — assign it to red, green, blue, intensity, whatever your rig needs
A wave traveling along a string of fixtures, color phasing along the path
Authoring tool

CNDL Maker

No-code authoring for lighting designers. CNDL Maker lets you connect visual blocks like routing wires on a circuit board, though you can still edit the corresponding code if you prefer. Preview your scenes in real time against your actual installation by importing 3D layout files (.obj). Works on macOS, Windows, and Linux.

Why CNDL

One format, two worlds

Coming from shaders

You already think in UV space, noise functions, and per-pixel compute. CNDL is that, but for physical fixtures instead of fragments. The operation set compiles directly to WGSL. Write it once, deploy to any target — GPU or microcontroller.

Coming from lighting control

You know Pharos, Madrix, or DMX consoles. CNDL handles what those tools can't: scenes that run on-device without a PC, arbitrary 3D fixture layouts instead of 2D pixel maps, and files that travel with the installation — not the software license.

Where CNDL runs

Simple enough to be implemented practically anywhere.

A compliant runtime is a short project in any language. Here are some of the places a .cndl file can run.

Microcontrollers

Arduino, RP2040, ESP32.

Parse the file on a small device, evaluate per frame, drive LEDs directly — no PC in the loop. The Eos Pixel Driver does this today on RP2040, outputting to addressable LEDs or DMX.

Single-board computers

Raspberry Pi, BeagleBone.

Run the scene on a Linux board and stream output over Art-Net, sACN, or whatever protocol the install needs. More headroom than a microcontroller, same file.

Desktop & Web

Any tool that can do arithmetic.

The format is open. Integrate CNDL into TouchDesigner, Blender, Unreal Engine, or build your own runtime in C, C++, Python, Rust, JavaScript, Swift, Go — any language that can do arithmetic. CNDL Maker is ours.

GPU

WebGPU, CUDA, compute shaders.

The operation set maps directly to GPU compute. CNDL Maker already compiles scenes to WGSL. For large fixture counts, a GPU runtime handles what embedded hardware cannot.

If you can evaluate addition, multiplication, and a sine wave, you can run CNDL.