--- name: qlcplus description: "Helps with QLC+ workspace files (.qxw), scenes, chasers, sequences, collections, EFX, RGB matrices, fixture definitions (.qxf), Virtual Console, and timing calculations. Use for creating or editing QLC+ shows, debugging timing and crossfades, generating fixture definitions, configuring plugins, repairing corrupt workspaces, or troubleshooting HTP and LTP conflicts. Also trigger for SpeedModes, FadeIn, Hold, Duration, FixtureVal, RunOrder, and QLC+ function types. Do not trigger for general DMX hardware questions without QLC+ context, fixture buying advice, DAW-only questions, or custom protocol implementations." --- # QLC+ Lighting Programming Skill You are helping with QLC+ (Q Light Controller Plus) v5 lighting automation. This covers everything from fixture setup through show programming. ## Key Concepts ### DMX Fundamentals - 512 channels per universe, values 0-255 - QLC+ supports unlimited universes (4 default) - Fixtures are patched at a universe + start address ### HTP vs LTP (Critical for understanding conflicts) | Rule | Channel types | Behavior | | ------------------------------ | ------------------------------------------------- | ----------------------------------- | | HTP (Highest Takes Precedence) | Intensity, dimmer, color intensity (R/G/B/W/A) | Highest active value wins | | LTP (Latest Takes Precedence) | Pan, tilt, gobo, strobe, speed, all non-intensity | Most recently started function wins | HTP uses the higher value when two active scenes set the same dimmer. LTP gives control of non-intensity channels to the function that started last. Start order matters and can cause unexpected jumps. During crossfades: HTP levels transition smoothly. LTP levels may jump immediately (gobo) or transition (pan/tilt) depending on fade time. ### Fade Out Only Affects HTP This is a common source of confusion. A scene's Fade Out time only fades intensity/HTP channels to zero. LTP channels (strobe mode, gobo position, pan/tilt) retain their values until another function overwrites them. ### Grand Master Final master slider before DMX output. Two modes: - **Reduce**: channels reduced by percentage (50% GM = all channels at 50% of current) - **Limit**: channels cannot exceed the GM value (GM at 127 = max output 127) Usually affects only Intensity channels, but can be set to affect all. ### Blackout Sets ALL HTP channels in ALL universes to zero. Channels stay at zero regardless of running functions. When switched off, functions resume control. ### Palettes (v5) A Palette abstracts a fixture feature (color, position, zoom). Can be used in Scenes to make looks fixture-independent. If you change a Palette, all Scenes using it update. --- ## Function Types ### Scene A snapshot of channel values. Key properties: - **Selective channel control**: Only enabled channels are affected. Disabled channels are NEVER touched. This enables layering. - **Fade In**: Time to fade all HTP and LTP channels to their target values. Only scenes apply Fade In to LTP channels. - **Fade Out**: Time to fade HTP channels to zero. Fade Out does not affect LTP channels, which retain their values. - **No duration**: Scenes persist until stopped or overridden - Monolithic scenes (all channels enabled) work well for chaser-driven workflows where only one scene is active at a time - Partial scenes (only some channels) enable layering but require careful management - **Crossfade blending**: When a chaser transitions between two scenes, it calls `setBlendFunctionID`. The new scene reads its starting values from the previous scene, which prevents snapping. ### Chaser Runs steps sequentially. Each step is a Function (usually a Scene). **The timing model (from source code):** ``` duration = fadeIn + hold ``` - `duration` is the TOTAL step time, not just hold - `hold = duration - fadeIn` - The step ends when `elapsed >= duration` - On step end, `prevStepRoundElapsed = elapsed % duration` carries overshoot into the next step (prevents timing drift) - **FadeOut is not included in duration**. It overlaps with the next step or runs after stop **SpeedModes behavior from the source:** | Mode | Meaning | | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | **Common** | All steps use the chaser's own `` values | | **PerStep** | Each `` attribute is used directly | | **Default** | Passes `Function::defaultSpeed()` (sentinel value UINT_MAX-1) to the child function, meaning the child uses its OWN fade times. The chaser does not override them. | In Duration mode, `Default` and `Common` both use the chaser's `duration()`. **Practical implications:** - With `SpeedModes FadeIn="Default" Duration="PerStep"`: the step's Hold attribute IS the total step time. The child function's own FadeIn is used for crossfading. The Hold value is what contributes to the timeline. - With `SpeedModes FadeIn="PerStep" Duration="PerStep"`: the step's FadeIn overrides the child function's fade. Duration = FadeIn + Hold. **Run orders:** Loop, SingleShot, PingPong, Random **Direction:** Forward, Backward **Beat tempo:** `elapsedBeats` increments by 1000 on each beat. Duration in beats = multiples of 1000 (e.g., 4000 = 4 beats). Set ``. **Infinite speed** (`Function::infiniteSpeed()`): Step never auto-advances. Used for manual cue lists. The runner checks: `if (duration != infiniteSpeed && elapsed >= duration)`. ### Sequence A sequence is a chaser bound to one parent scene. Every step controls the same channels, and the sequence appears under its parent scene in the Function Manager. **Sequence step values format** (inside ``): ``` fixtureID:channel,value,channel,value:fixtureID:channel,value,... ``` Fixture chunks separated by `:`, channel/value pairs by `,`. Only non-zero values saved. ### Collection Runs multiple functions **simultaneously** (parallel, not serial). All members start in `preRun()`. Collection stops when all children finish (`m_runningChildren` becomes empty). - Cannot contain itself (self-containment check in `postLoad`) - Duplicate function IDs are rejected - No speed settings of its own ### EFX Automates pan/tilt (or RGB/dimmer) along mathematical paths. Algorithm types: Circle, Eight, Line, Line2, Diamond, Square, SquareChoppy, SquareTrue, Leaf, Lissajous. **Propagation modes:** Parallel (all fixtures move together), Serial (offset start), Asymmetric (mirror offset). ### RGB Matrix Graphic patterns/text on a grid of RGB fixtures. Requires a Fixture Group defining pixel layout. Has Fade In, Fade Out, Duration per frame. Extensible via ECMAScript RGB scripts. ### Show Timeline-based function (Show Manager). Places functions on time tracks with precise timing. Best for pre-programmed sequences synced to music or a metronome. **Show Manager key concepts:** - Multitrack view similar to a DAW. Each track is bound to a Scene - Sequences on a track can only control channels of that track's Scene - Functions can be placed at precise time positions, dragged, copied - Supports BPM grid (4/4, 3/4, 2/2) with snap-to-grid for music sync - Tracks support mute/solo states - Playback always starts from cursor position, can resume **Sequences vs Chasers in Show Manager:** - Sequence steps are values of ONE Scene's channels (bound to track). Chaser steps can be ANY function. - Sequences in Show Manager always play Forward. Chasers support all run orders. - Sequence editing: new steps copy previous step's values (adjust differences). Chaser editing: pick existing functions. - Sequences are better for extending shows (add track + sequence for new fixtures). Chasers require complex Collections for sync. ### Script ECMAScript-based automation of QLC+ functions in sequential order. --- ## Workspace XML (.qxw) Structure The .qxw file is XML. Common attributes on ``: `ID`, `Type`, `Name`, `Path` (folder), `Hidden`, `BlendMode`. ```xml ... ... ... ... ... id,level,id,level ch_num,value,ch_num,value,... Forward SingleShot scene_id function_id function_id Parallel Circle 127 127 0 Forward Loop ... ... ``` ### Scene FixtureVal format `channel,value,channel,value,...` - Channel numbers are 0-indexed relative to the fixture - Values are 0-255 - Empty FixtureVal (``) means fixture participates but no values set ### Chaser Step format `function_id` - Times in milliseconds - function_id references the Function ID of the step content - Tempo Type="Beats": values are multiples of 1000 (1000 = 1 beat) --- ## Virtual Console ### Button Triggers a function. Modes: toggle, flash (held), blackout. ### Slider Direct channel control or playback fader (controls HTP intensity of a running function). ### Cue List - Can ONLY be assigned a Chaser - Steps through with Next/Previous/Play/Stop - Crossfade fader for manual transitions - Set step duration to infinite (∞) for manual crossfade control - Duration=0 causes rapid looping. Always set explicit durations ### Solo Frame Only ONE button active at a time. Starting a new function stops the previous. Essential for mutually exclusive looks. ### Frame Visual grouping. Can collapse. No exclusive behavior. --- ## Fixture Definitions Fixtures are defined in XML (.qxf) with: - Manufacturer, Model, Type - Physical properties (bulb, beam angle, dimensions) - Channels with groups (Intensity, Pan, Tilt, Gobo, Color, Speed) - Capabilities per channel (value ranges → names/functions) - Modes (different channel configurations for the same fixture) ### Fixture Modes Many fixtures have multiple modes (e.g., 8-bit vs 16-bit pan/tilt). Each mode defines which channels are active and their order. ### Heads A head is an individual light output in a multi-head fixture (e.g., LED bar with 4 RGB segments). Heads share some properties but can be controlled individually. --- ## Input/Output & Plugins QLC+ supports: - **Art-Net** (network DMX) - **E1.31/sACN** (network DMX) - **DMX USB** (Enttec, FTDI adapters) - **MIDI** (input/output for controllers) - **OSC** (Open Sound Control) - **HID** (joysticks, gamepads) - **Loopback** (internal routing) Input profiles map physical controller knobs/faders to QLC+ controls. --- ## Common Pitfalls 1. **Hold="0" on sub-chaser steps:** QLC+ skips these steps entirely 2. **SpeedModes FadeIn="PerStep" on a song chaser:** This can cause timing drift compared with `Default` 3. **Expecting Fade Out to affect LTP channels:** Only HTP channels fade out 4. **Two scenes setting the same LTP channel:** The scene started last wins, which can cause unexpected jumps 5. **Cue List steps with duration=0:** These loop rapidly without a visible result 6. **Forgetting channel enablement:** A scene never changes a disabled channel 7. **Layering monolithic scenes:** When both scenes set intensity, the highest HTP value wins, not the value from the current scene ## Timing Calculations When programming song chasers, always verify: - `sum(all step Hold values) == song duration` (for SingleShot chasers) - Sub-chaser Hold = sum of sub-chaser's own steps' total durations - FadeIn happens WITHIN the Hold window (with Default SpeedMode), not in addition to it ## Best Practices - Use `SpeedModes FadeIn="Default" FadeOut="Default" Duration="PerStep"` for song chasers - Give sub-chaser steps explicit Hold values matching their total runtime - Never hold a single static scene longer than ~12s in performance - Create front/rear intensity contrast for depth (not symmetric values) - Use Solo Frames to prevent accidental scene stacking - Keep strobe for punctuation, not atmosphere