Skip to content

Data Tracks ​

Data Tracks are timeline lanes with a built-in curve editor for keyframe-based animation. You draw a curve directly in the Timeline; while the composition plays, Exaplay reads the curve at the playhead and sends the value to external systems (lighting consoles, control systems, custom hardware) over OSC, UDP, TCP or Art-Net — or writes it into one of Exaplay's own values: a shader parameter, a volume, a clip's position (see Driving Exaplay's own values).

Data Tracks with Linear and Step interpolation curves

What Are Data Tracks? ​

A Data Track is a timeline lane containing keyframes: points in time (in seconds) with a value. The lane draws the curve between them. While the composition plays, the engine evaluates the curve at the playhead and sends the value to the track's Output.

  0 s:  value = 0
  30 s: value = 1
  60 s: value = 0
  → value ramps up to 1 and back to 0 over 60 seconds

Data Tracks belong to Timeline compositions; a Playlist has none.

Creating a Data Track ​

  1. Add the track in one of three ways:

    • Right-click anywhere in the Timeline dropzone area and choose Add Data Track,
    • click the caret (▾) next to the + under the track list and choose + Data Track — it is added at the bottom, or
    • right-click a track and choose Add Data Track — it is added right after that track.

    A Data Track can live inside a Group like any track: right-click the gap under a group's header and choose Add Data Track, or drag an existing one in. Hiding the group hides (and silences) the Data Tracks in it.

  2. The new track is selected; configure it in the Inspector:

    • Name — the title at the top of the Inspector
    • Color — the track's accent colour
    • Min Value / Max Value — the range of the curve (default 0 – 1)
    • Interpolation — Linear or Step
    • Output — where the value goes (see Output types)

A new track sends OSC to 127.0.0.1, port 9000, OSC path /data-track, at up to 120 Hz — change the Output before you play. Switching the Format to ArtNet moves a port that is still 9000 to the Art-Net port 6454 (and back to 9000 when you leave ArtNet with the port still at 6454); a port you typed yourself is kept.

To move a Data Track, drag the grip (⋮⋮) on its row in the track list to the gap under another row — at the top level, into a group or out of one — the same gesture that sorts a track.

Right-click a Data Track (its name on the left or its curve row) for its own menu:

EntryEffect
Delete Data TrackRemoves the track
Add Data Track Above / BelowAdds a new, empty Data Track next to this one
Duplicate Data TrackCopies the track with its keyframes and all its settings; the copy is named after it with " copy" appended
Copy CurveCopies the whole curve (its keyframes and its Linear/Step mode)
Paste Curve (n keyframes)Replaces this track's curve with the copied one — also onto an empty track. Shown once a curve has been copied

The track's name panel on the left carries three buttons: the eye switches the track on and off (see Visibility), the bin deletes it, and the magnifier opens the expanded editor.

Editing Keyframes with the SVG Curve Editor ​

The curve editor is embedded directly in the Data Track row in the Timeline.

ActionResult
Double-click on the curve areaAdds a keyframe at that time and value
Click a keyframe handleSelects it — its time and value appear in the Inspector for precise editing
Drag a keyframe handleMoves it in time and value
Right-click a keyframe handleOpens its menu: Copy value, Paste value, Copy curve, Paste curve, Delete keyframe
Arrow Left / RightMoves the selected keyframe 1 s earlier/later (0.1 s with Shift)
Arrow Up / DownNudges the selected keyframe's value by 1 % of the track's range (0.1 % with Shift)
Delete / BackspaceRemoves the selected keyframe
EscapeDeselects the keyframe
Ctrl+ZUndoes a keyframe edit — adding, moving, deleting, pasting

The keyboard works once a keyframe is selected (clicking it gives the curve the keyboard focus).

  • Snapping: times sit on a 0.1 s grid and never go below 0; values are kept inside the track's Min–Max and rounded to three decimals. There is no snapping to other keyframes or to the playhead.
  • One keyframe at a time: there is no multi-select; to move a whole curve, copy it onto another track or change it keyframe by keyframe.
  • No handles or easing: the curve between two keyframes is a straight ramp (Linear) or a hold (Step).
  • Keyframes are always kept sorted by time. A value label (e.g. f30: 0.75 — the time in seconds, then the value) appears next to the handle while you drag it or while it is selected.

Copy and paste. Copy value / Paste value carry one keyframe's value to another; a value pasted onto a track with a different Min–Max lands at the same relative height (80 % of 0–1 becomes 204 on a 0–255 track). Paste curve replaces the whole curve: the keyframes keep their times, their values are re-read into this track's Min–Max the same way, and the Linear/Step mode comes along. The same menu is on a clip's Opacity/Volume keyframes, see Property Keyframes.

Expanded editor ​

The magnifier on the track's name panel opens a larger editor with a time ruler. It edits the same curve, with the same gestures and keys, plus:

ActionResult
Scroll / ← / → (no keyframe selected)Pans the view
Ctrl+Scroll, Ctrl+= / Ctrl+-Zooms in / out
Ctrl+← / Ctrl+→Pans the view, also while a keyframe is selected
Ctrl+0 or 100%Back to 100 % at the start
HomeBack to the start

The hint line under the toolbar lists these keys: ← / → move a selected keyframe by 1 s (0.1 s with Shift) and ↑ / ↓ change its value by 1 % of the track's range (0.1 % with Shift), exactly as in the Timeline row.

Keyframe Inspector ​

When a keyframe is selected, the Inspector shows:

PropertyDescription
FrameThe keyframe's time in seconds — the field is labelled Frame (editable)
ValueThe value at this keyframe (editable, within the track's Min–Max)

Track Appearance ​

  • The track name is shown in the track's left panel.
  • The curve line and keyframe handles use the track's accent colour (Color in the Inspector); a selected handle turns yellow.
  • A hidden track's row is dimmed and its eye is red.

Interpolation Modes ​

ModeBehaviour
LinearStraight ramp between keyframe values (drawn as straight segments, not a spline)
StepThe value holds until the next keyframe, then jumps (no interpolation)

Before the first keyframe the curve holds the first keyframe's value, after the last one it holds the last value — the curve never extrapolates. A track with a single keyframe sends that one value throughout.

When a Data Track sends ​

  • Only while its composition plays. The engine reads the curve at the composition's playhead on its playback tick (about every 8 ms) and sends at most Rate (Hz) values per second (1–120, default 120).
  • OSC, UDP, TCP and Art-Net send continuously while playing, whether the value changed or not — also after the last keyframe, which keeps sending its value until the composition stops. Exaplay value writes only when the value changes.
  • Pause and stop end the sending. Nothing is sent on stop, so the receiving device keeps the last value it got. An Exaplay value hands its property back its original value on stop (a pause holds) — see below.
  • Seeking while playing sends the value at the new position on the next tick; seeking while stopped or paused sends nothing.
  • A hidden track (Visibility off) and a track without keyframes send nothing.
  • On a multiclient rig, only the master sends. Every machine plays its own copy of the track from its own synced clock, but OSC, UDP, TCP and Art-Net leave only the master (or a standalone machine) — a device receives each value once, not once per machine. On a client the track sends nothing and Status reads client — master sends (nothing sent from this machine); its Live value row says client — master sends and shows the value the master is sending. Exaplay value is not affected: it drives a property of the engine it runs on, so every machine keeps writing its own.

Output Types ​

FormatWhat goes out
OSCOne OSC message to Address:Port over UDP: the OSC Path as the address, the curve value as one float32 argument
UDPOne datagram per value: the curve value as a raw 4-byte big-endian float32 — no text, no terminator
TCPThe Command text, with every {value} replaced by the curve value (six decimals, e.g. 0.750000) and escapes such as \r, \n or \x0D turned into bytes. Each value opens a new connection to Address:Port, sends, and closes. An empty Command sends nothing
ArtNetThe track's Min–Max scaled onto 0–255 and written into one DMX channel of an Art-Net universe — see ArtNet & DMX
Exaplay valueWrites the value into one of Exaplay's own properties — a shader parameter, a volume, a clip position — addressed by the same dotted path the TCP set: syntax uses, scaled onto a target range. See Driving Exaplay's own values.

OSC, UDP and TCP send the curve value as drawn: set the track's Min Value / Max Value to the units the receiver expects (0–100, 0–255, degrees…). Only ArtNet and Exaplay value rescale it.

The Control Panel format was removed

Earlier versions had a Control Panel format. Use Exaplay value to drive a property inside Exaplay: it scales the value onto the property's range, reports what it resolved in Status, and hands the property back its original value when the composition stops. A project saved with a Control Panel track still opens; the track sends nothing, its Format reads Control Panel (no longer supported) and Status says Control Panel output is no longer supported — nothing sent; use Exaplay value.

TCP connects in the background, one attempt at a time per track: the engine hands each value over and never waits for the device, so a device that is off or unreachable cannot hold up playback or the other tracks. Each connection attempt gives up after 0.3 s; after a failed one the track leaves that address alone for 2 s, drops the values in between, and Status reads cannot connect to 10.0.0.5:9000 — retrying. When the device answers again, Status goes back to sending to …. A value is only ever replaced by a newer one, never queued, so a slow device gets the latest value rather than a backlog. For a continuous value prefer OSC or UDP.

Inspector Properties ​

PropertyDescription
NameThe track's label (the title at the top of the Inspector)
ColorAccent colour of the curve and the track's name
VisibilityOff: the track sends nothing. For an Exaplay value it also releases the property (see below)
Range › Min Value / Max ValueThe range of the curve, −10000 to 10000 (default 0 – 1). Changing it rescales the existing keyframes so the curve keeps its shape — a keyframe at the top of 0–1 is at the top of 0–255 afterwards. Set the range first when you want to type real numbers
Range › InterpolationLinear (default) or Step
Output › Live valueWhat the track sends at the composition's playhead right now, after the format's own scaling — for ArtNet the DMX byte and for Exaplay value the written value, each with the curve value it came from. It says sending while the composition plays, not playing (the value a play from here would send), track hidden, no keyframes, client — master sends (a network format on a multiclient client) or format no longer supported
Output › FormatOSC, UDP, TCP, ArtNet or Exaplay value
Output › AddressDestination IP address (OSC / UDP / TCP / ArtNet; default 127.0.0.1), or a named route such as $Console — a variable that carries host:port sets the port too
Output › PortDestination port (default 9000). Switching the Format to ArtNet sets 6454 while the port is still the default, and leaving ArtNet sets 9000 back while it is still 6454; a port you typed is never changed
Output › OSC PathOSC message address (default /data-track, e.g. /fixture/1/dimmer). The path only: the track adds the value as the message's one argument. The ⚡ Wizard button builds it — leave its argument list empty
Output › CommandTCP: the text to send, with {value} where the value goes (e.g. SET DIM {value}\r\n). The ⚡ Wizard button builds the text
Output › UniverseArtNet universe, 0–32767 (default 0)
Output › ChannelArtNet DMX channel, 1–512 (default 1)
Output › Fixture LibraryArtNet: pick a fixture profile, universe, starting address and destination IP, and get one ArtNet track per fixture channel. Profiles can be imported as JSON or GDTF XML — see Fixture profiles and library
Output › TargetExaplay value: the dotted path of the value to drive, e.g. comp1.media3.realtime.params.u_speed. The field completes the path as you type it (the project tree, then the object's values) and the ⚡ wizard browses the project for one
Output › ScalingExaplay value: how the curve's value becomes the written one — Out range (default: the track's Min–Max onto Out Min–Out Max), Factor (value × factor + offset) or As drawn (written unchanged)
Output › Out Min / Out MaxExaplay value, Out range mode: the range the track's Min–Max is scaled onto (default 0 – 1). Filled in automatically when the picked property has a known range (0–100 for an opacity or a volume)
Output › Factor / OffsetExaplay value, Factor mode: the multiplier (default 1) and the offset (default 0) applied to the curve's value
Output › Restore on stopExaplay value: when on (default), the property gets the value it had before the curve first wrote to it back as soon as the track lets go — the composition stops, the track is hidden or deleted, the target changes
Output › StatusWhat the engine reports (read-only). OSC / UDP / TCP / ArtNet: sending to 10.0.0.5:8000 — the address the route resolved to — or unknown variable $Console — nothing sent / no address, in which case nothing is sent; on a multiclient client client — master sends (nothing sent from this machine); for TCP also cannot connect to … — retrying. Exaplay value: the resolved target, a release, or why nothing is written (see below)
Output › Rate (Hz)Maximum send rate, 1–120 Hz (default 120)
Import › Import CSVReplaces the curve with keyframes from a CSV file — see Importing a curve from CSV

A change that the engine refuses (for example while it is loading a project) is not kept silently: a message says the Data Track change was not stored.

Importing a curve from CSV ​

Import › Import CSV in the track's Inspector fills the curve from a text file (.csv, .tsv, .txt) with one row per keyframe:

  1. Choose file… and check the Delimiter — Auto detects comma, semicolon or tab; or pick ,, ; or Tab.
  2. Pick the Time column and the Value column. A first row with text in it is read as column names; a column called time, frame, t, sec, seconds or ms is picked as the time column.
  3. Set the Time unit — Seconds (default) takes the time column as it is; Frames divides it by the FPS shown next to it (filled with the composition's frame rate), so frame 45 at 30 FPS becomes 1.5 s. A time column named frame or frames selects Frames, one named time, t, sec or seconds selects Seconds. Then set the Track name (default: the value column's name) and the Interpolation mode (Linear or Step (hold)).
  4. The Preview shows the first rows and how many keyframes will be imported; rows whose time or value is not a number are skipped and counted.
  5. Import n keyframes.

The import replaces every keyframe of the track and sets its name and interpolation. The values are taken as they are — set Min Value / Max Value to the data's range before importing, because changing the range afterwards rescales the imported values. Imported times are not moved onto the 0.1 s grid.

In the Monitor ​

With the Monitor open, a Data Track logs every value it sends as an OUT row: OSC DataTrack [datatrack1] → /fixture/1/dimmer = 0.750000, UDP DataTrack [datatrack1] = 0.750000, TCP DataTrack [datatrack1] → SET DIM 0.750000 (only once the value was delivered). That is up to Rate rows a second per track.

Art-Net is logged per destination, not per packet: one ArtNet OUT row when the track starts sending — DataTrack [datatrack1] → ArtNet 10.0.0.50:6454 universe 0 channel 1 — sending (DMX 128) — one when it stops (… — stopped (last DMX 255), when the composition stops, the track is hidden or deleted, or its Format changes), and a stop plus a new start when the address, port, universe or channel changes. Pausing does not end it. The value itself is in the track's Live value row.

Exaplay value writes are not logged there — read the track's Live value and Status instead. An address that cannot be resolved, a TCP device that does not answer, and a client leaving the sending to its master show in Status (and in the engine log, once per change), not as Monitor rows.

Driving Exaplay's own values ​

Everything a Data Track can send to a lighting desk it can also send to Exaplay itself. With Output › Format set to Exaplay value, the curve drives one property of any object in the show — the same properties the Inspector edits and the TCP set: syntax addresses — so a timeline can move a clip, ride a volume, sweep a shader parameter or blink a layer, with no external controller in the loop.

Target ​

Target is a dotted path in the same grammar as the TCP/UDP dotted commands: the object's tree path, then the property.

comp1.media3.realtime.params.u_speed    a generative source's parameter
comp1.audio.volume                      a composition's volume (0–100)
comp1.track1.media2.mapping.x           a clip's horizontal position (px)
Main Show.alpha                         a composition by NAME (varnames win)
comp1.media3.show                       a clip's visibility (on/off)
  • The field completes the path as you type it, the way the cue editor completes a command: type comp1. and the composition's tracks, groups, clips and cues are listed, then the object's own values — its position, size, opacity and volume first, then everything else. A listed object or value group takes a . and keeps going; a value completes the path. Arrow keys move through the list, Enter or Tab pick, Escape closes it.
  • The ⚡ wizard next to the field browses the same project tree (compositions, tracks, groups, clips) and lists the values an operator drives, by their plain names and with the range each one will be scaled to: Opacity, Volume, Position X / Y, Size W / H, Rotation, Visible — plus every parameter of the generative source that clip actually runs, named and ranged from its catalog. The list describes the object you picked: a composition or a track offers its own opacity and volume and no position. Anything else the object carries — colour correction, a crop corner, an EQ band, or a new key inside an existing group such as realtime.vars.<name> (the show-control hook a generative source's bindings read) — is typed into the Other value field below the list, or into the Target field itself, which still completes every path in the dictionary.
  • A line pasted from a cue script or the TCP docs works as it is: comp1.set:audio.volume=80 names the target comp1.audio.volume; the verb and the argument are ignored.
  • The project. prefix is optional — project.comp1.audio.volume and comp1.audio.volume name the same value, and the field completes through either.

Scaling ​

The curve is drawn in the track's Min Value – Max Value range. Scaling picks how a curve value becomes the written one:

ScalingWritten valueUse it for
Out range (default)the track's Min–Max scaled linearly onto Out Min – Out Max, clamped to that rangeone 0–1 curve driving anything — and the range is filled in for you (below)
Factorcurve value × Factor + Offset, not clampedyour own arithmetic: a 0–1 curve × 100, a metre curve × 1000 into millimetres
As drawnthe curve value, unchangeda curve drawn in the property's own units — set the track's Min / Max Value to that range before drawing (changing it later rescales the keyframes) and the editor shows the real numbers

Out Min / Out Max are filled in when the target is picked (typed, completed or chosen in the wizard) whenever the property has a known range and Scaling is Out range: an opacity or a volume is 0–100, a rotation 0–360, a size stored as a percent 0–100, a generative source's parameter its catalog range (plasma's Speed is 0–4).

A position or size in pixels is ranged too, against the surface that clip is positioned on — the field it is mapped to, else the screen it is routed to — so a 0–1 curve on Position X lands on 0 – 1664 for a clip on a 1664×832 LED wall, not on 0 – 1. That size is read from the clip itself, so it is right on every machine and every wall; where it cannot be read (an older engine, an object with no position at all) the range is left alone rather than guessed. A property nobody can range — a variable — leaves it alone as well; set it yourself, or switch to Factor or As drawn.

Curve (Min–Max)ScalingWritten
0 – 1, at 0.5Out range 0 – 1920960 — a clip moved to the middle of a Full HD screen
0 – 1, at 0.75Out range 0 – 10075 — a volume or an opacity at 75 %
0 – 255, at 255Out range 0 – 100100 — a DMX-style curve riding a 0–100 property
0 – 1, at 1Out range 100 – 00 — inverted (Out Min above Out Max is allowed)
0 – 1, at 0.3Factor 100, Offset −50-20 — the operator's own arithmetic, never clamped
0 – 100, at 37As drawn37

The target's own type and unit decide the rest: an on/off property switches on in the upper half of the curve's range and off below it (whatever the scaling); a size stored as a percent (mapping.w = 100%) is written as a percent (50%), so driving it to 0–100 scales the clip instead of shrinking it to pixels — switch the size to pixels in the clip's Inspector first if pixels are what you want; everything else receives the value as it is, at full precision. Positions (mapping.x/y) are in pixels of the screen the clip is placed on.

Sweeping a generator's parameter

Point Target at a generative clip's parameter — comp1.track1.media1.realtime.params.u_speed, or pick it in the ⚡ wizard, which lists the parameters of the source that clip actually runs and fills in their catalog range. A 0 → 1 curve then sweeps Speed across 0–4, Audio react across 0–1, and so on, live on the next frame.

The same parameters are drivable from Inputs and from a TCP/UDP line, a REST call or a cue-script line (comp1.track1.media1.set:realtime.params.u_speed=2.4) — one grammar, several sources. A parameter you want several things to feed can instead be bound to a variable in the clip's Inspector (realtime.vars.<name>), and then the curve, the tracker or the desk drives that one variable.

Moving a clip across the screen

Draw a 0 → 1 ramp over 5 seconds, set Target to comp1.media3.mapping.x and Out Max to the screen width (1920). Add a second Data Track for mapping.y to move diagonally. The clip's Inspector shows the position following the curve while the composition plays — and the clip is back where you placed it when the composition stops.

Scaling a clip

Target comp1.media3.mapping.w (Size W (scale)): with the size stored as a percent the out range is filled with 0–100 and a 0 → 1 curve grows the clip from nothing to its full size. Add mapping.h on a second track to keep the aspect ratio.

What happens on the engine ​

  • The write takes the same path as an Inspector edit or a TCP set: line, so it applies live on the next frame — a shader parameter, a fader, a position, a visibility switch all react immediately; nothing reloads.
  • The curve is evaluated while the composition plays; an unchanged value is not re-written (a flat curve costs nothing), and after a pause the value is re-asserted when playback resumes, so the curve always owns the property while it runs.
  • The property gets its original value back when the track lets go. The value it had before the curve's first write is remembered, and written back when the composition stops (a pause holds), when the track is hidden or deleted, or when the Target or the Format is changed — so a clip a curve slid across the screen is back where you placed it, and a volume a curve ducked is back at its fader. Restore on stop switches this off for a show that wants the last written value to stick. A value the curve created itself (a new realtime.vars.<name>) has no original and is left as written.
  • The written value becomes the property's value exactly as if you had set it yourself — while the curve runs it is what the project saves, and on a multiclient rig every engine evaluates its own copy of the track from its own synced clock, so all machines follow without any extra sync. (This is why Exaplay value keeps running on a client while the network formats leave the sending to the master.)
  • Status reports what the engine resolved: driving media3.realtime.params.u_speed when the write lands, released media3.image.alpha — back to 100 when the track let go, no target — pick a value with the wizard or type comp1.media3.<property> while Target is empty, target not found: … for a mistyped object, property not found: … on … for a mistyped property (a property inside a group the object has never declared is refused rather than silently created), and write refused: … / restore refused: … when the property did not take the value. The engine log carries the same line, once per change.
  • Rate (Hz) still applies; a rate below 120 Hz simply thins the writes.

See it done ​

A recorded walkthrough draws a curve and watches the value it sends: ☰ menu → Walkthroughs → Playlists & timelines → A curve that drives a value — Data Tracks. Two more show the same editing: ☰ menu → Walkthroughs → Playlists & timelines → Fades, curves and tween keyframes (keyframes, their menu and copy/paste on a clip's curve) and ☰ menu → Walkthroughs → Playlists & timelines → A cue that sets a value — the Command Wizard (picking an object and a value by name, as the ⚡ Target wizard does).

Exaplay 3 User Documentation