Stoatworks Labs

Shunt

Shapes that queue, bank up and are drawn away

Betav0.2.0Plugin & ModuleC++ / GLSL
Shunt — Shapes that queue, bank up and are drawn away
Rendered by the plugin's own offline harness, which drives the real plugin class through a headless GL context — not a Resolume screen capture. Five discs entering from the left, banked up against the head of the queue with the newest overlapping the one in front, shaded and hue-spread along the train.

What it does

Two FFGL plugins for Resolume Arena and Avenue, from one core. SW Shunt is a source that draws its queue over its own background on its own layer. SW Shunt Mask is an effect that draws the same queue over the clip it sits on, or cuts it into it: show the clip only inside the shapes, hide it only inside them, or tint it through them. It's two bundles rather than one because FFGL resolves a single entry point per binary.

Underneath it's an accumulating conveyor, which is what a shunting yard is. Shapes are released from one edge at a steady rate and run in at a steady speed. The head of the queue stops at the distance you set, and everything behind it stops one gap further back, overlapping the shape in front. Each one stands for its dwell and then carries on off the far side, so the queue empties from the front while it's still filling from the back.

How much those two overlap is one continuous control, not two modes, and that was the design decision I took the most care over. Turn Dwell down and shapes cross slowly: the head's still leaving as the fourth one arrives, and the train never stands complete. Turn it up and they cross fast: the whole train is standing before the head moves at all, then it peels off one at a time. Everything in between is reachable, and nothing in the code branches on it.

You can set the gap in two units because neither does the other's job. In multiples of the shape's own thickness, one means edge to edge and anything below that is overlap, and the train still looks right when the size changes. In absolute pixels it's exact, so you can match it to a fixture pitch: a 64-pixel gap measures 64.00 pixels at 1080p and at 720p alike.

A shape's position is a closed-form function of its slot and a single phase number. There's no queue object anywhere, nothing asks whether the shape in front has gone yet, and no frame depends on the one before. That all comes from one choice: the slide speed is worked out rather than set, so every shape's run is exactly one cycle long whatever slot it stands at, and the runs tile the cycle exactly. So the procession can't drift when the host's frame rate sags, any frame can be rendered on its own, and locking the whole thing to the track doesn't need a separate code path.

  • Two plugins from one core — a source with its own background, and an effect that masks the clip
  • Eight primitives — circle, square, triangle, hexagon, star, cross, ring and bar — with stretch, roundness, outline and edge softness
  • Entry from any of the four edges, with the shape's angle measured from the direction of travel so changing sides does not mean re-dialling it
  • Gap in multiples of the shape's own thickness, or in absolute pixels for a pixel map
  • Dwell as one continuous dial from a queue that never stops to one that stacks completely before anything moves
  • Newest shape drawn on top, with the draw order rotating as the queue turns over
  • Free-running, beat-locked, bar-locked, or driven entirely by an external Phase control
  • Four mask modes on the effect — shapes over the clip, reveal, hide, or colourise through them — and a matte or inverse matte from the source, for another layer to key against
  • Lanes: each new set of shapes steps across the frame, or jumps to a random lane never closer than one shape to the last
  • Drop shadows falling away from the same light the shading uses, each landing on the shapes it has slid over
  • Pictures on the shapes — one image, every image in a folder, or a sprite sheet cut into a grid; the same on every shape, random, or in order
  • Seven factory presets, and a hard edge when the output is feeding fixtures rather than a screen
  • Universal macOS bundle (Apple Silicon and Intel) and a Windows DLL

Where it stands

v0.2.0, and still early days. It answers the first field report, from the operator who asked for the plugin: the source's Mask Mode and Mix did nothing in 0.1.0 and now make a matte and fade the output, and lanes, drop shadows and pictures on the shapes are new, each with its own measured check, with all 47 controls shown to reach the picture. Its Windows build passed the Arena gate in Resolume Arena 7.27.1 before release, with all 50 controls per plugin as declared and a picture loaded into the new Image control. The rest of this is the record from 0.1.0, the first release. An offline harness drives the real plugin in a headless GL context and reads the answers off rendered frames: 27 shapes landed within 1.5 px of an independent prediction across four entry sides and five aspect ratios, a 64-pixel gap measures 64.00 px at both 1080p and 720p, the head of the queue stops within 0.1 px of where it's told to, a standing shape stands for 23, 119 and 215 frames of 240 where Dwell at 10%, 50% and 90% predicts 24, 120 and 216, and the newer of two overlapping shapes is the one you see at every phase. Ninety-two slot runs across nine configurations confirm the invariant the whole design rests on, and all 33 controls are shown to reach the picture. Both plugins load and run in Resolume Arena 7.27.1: the shipped Windows build was checked in a real Arena on 2026-09-22, where both register with the right name, id and type, all 38 controls on each match what the plugin declares, and both render with a clean log. That run was on software rendering, so it says nothing about a GPU. It hasn't been used in a show yet, and there's no OpenFX build. The macOS builds are signed and notarised. Try it on a spare layer first.

Watch it running

Shunt video thumbnail

Nothing loads from YouTube until you press play.Watch it there instead