Skip to main content

Overview

Sequence management is central to MA2 plugin functionality. Plugins automate the creation of sequences, cues, and executor assignments to build complex playback systems. This guide covers the patterns used across the MA2 plugin collection.

Sequence Creation Workflow

The typical sequence creation workflow follows these steps:
1

Enter Blind Edit Mode

All sequence creation should happen in blind edit to avoid affecting live output:
cmd('BlindEdit On')
2

Create Sequences

Store new sequences with labels:
cmd("Store Sequence "..seqCurrent.." /o")
cmd("Label Sequence "..seqCurrent.." \""..groups[seq+1].."\"") 
3

Create and Store Cues

Build cue content and store to sequences:
cmd("Group "..group.." At Preset 4."..preset)
cmd("Store Cue "..cueNum.." Sequence "..seqNum)
cmd("Label Sequence "..seqNum.." Cue "..cueNum.." \"Full L\"")
4

Assign to Executors

Link sequences to executor buttons:
cmd("Assign Sequence "..seq.." At Executor "..executor)
5

Exit Blind Edit

Return to normal operation:
cmd('BlindEdit Off')

Creating Sequences

Basic Sequence Storage

From Color Picker Update:
function createSequences()
  -- Create New Sequences
  for seq=0, #groups-1 do
    local seqCurrent = seqStart + seq
    cmd("Store Sequence "..seqCurrent.." /o")
    cmd("Label Sequence "..seqCurrent.." \""..groups[seq+1].."\"") 
  end
end
The /o flag means “overwrite” - this will replace an existing sequence at that number without prompting.

Sequence Deletion

Before creating new sequences, plugins often clean up old ones:
function deleteSequence()
  -- Delete old Sequences and Cues
  cmd("Delete Sequence "..(seqStart).." Thru "..(seqStart+#groups-1).." /nc")
end
The /nc flag means “no confirm” - sequences are deleted immediately without user confirmation. Use carefully.

Working with Cues

Creating Cues in Sequences

From Color Picker Update:
function createCues()
  fb("--- Creating Cues")
  for group=grpStart, #groups do
    local presetCurrent = presetStart + ((group-1)* presetWidth)
    for start=1, colNb do
      local preset = presetCurrent + start - 1
      local seqCurrent = seqStart + group - 1
      
      -- Build cue content
      cmd("Group "..group.." At Preset 4."..preset)
      
      -- Store to sequence
      cmd("Store Cue "..start.." Sequence "..seqCurrent)
      
      -- Label the cue
      cmd("Label Sequence "..seqCurrent.." Cue "..start.." \""..groups[group].." "..colSwatchBook[start].."\"") 
    end
  end
  clear()
end

Cue Pairs for Effects

From Pulse Generator - creating ON/OFF cue pairs:
while PG_cue <= PG_amount * 2 do
  cmd('Next')
  cmd('At 100')
  if(PG_white == 'true') then
    cmd('At Gel 1.1')
  end
  
  -- Store ON cue
  cmd('Store Sequence '..PG_seq..' Cue '..PG_cue)
  cmd('Label Sequence '..PG_seq..' Cue '..PG_cue..' "ON"')
  
  -- Store OFF cue
  if(PG_white == 'true') then
    cmd('At 100')
  else
    cmd('At 0')
  end
  cmd('Store Sequence '..PG_seq..' Cue '..(PG_cue + 1))
  cmd('Label Sequence '..PG_seq..' Cue '..(PG_cue + 1)..' "OFF"')
  
  -- Configure OFF cue trigger
  cmd('Assign Sequence '..PG_seq..' Cue '..(PG_cue + 1)..' /trig=time /trigtime='..PG_trigTime..' /fade='..PG_fade..' /mode=release')
  
  PG_cue = PG_cue + 2
end
Cue pairs with auto-triggered OFF cues create self-resetting effects - perfect for bumps and pulses.

Wave Cue Pairs

From Pulse Wave Generator:
local function PWG_createCuePair(grp, direction, cueNum)
  local wing = PWG_getWing(direction)
  local delayStr = PWG_getDelayString(direction, PWG_delay)
  
  PWG_clear()
  
  cmd("Group " .. grp)
  if wing > 0 then
    cmd("MAtricksWings " .. wing)
  end
  
  cmd("PresetType \"DIMMER\"")
  
  -- Full cue with delay
  cmd("At 100")
  PWG_sleep(0.05)
  cmd("Delay " .. delayStr)
  PWG_sleep(0.05)
  cmd("Store Sequence " .. PWG_seq .. " Cue " .. cueNum)
  cmd("Label Sequence " .. PWG_seq .. " Cue " .. cueNum .. " \"Full " .. PWG_dirShortNames[direction] .. "\"")
  
  -- Off cue with delay
  cmd("At 0")
  PWG_sleep(0.05)
  cmd("Delay " .. delayStr)
  PWG_sleep(0.05)
  cmd("Store Sequence " .. PWG_seq .. " Cue " .. (cueNum + 1))
  cmd("Label Sequence " .. PWG_seq .. " Cue " .. (cueNum + 1) .. " \"Off " .. PWG_dirShortNames[direction] .. "\"")
  cmd("Assign Sequence " .. PWG_seq .. " Cue " .. (cueNum + 1) .. " /trig=time /trigtime=" .. PWG_trigTime .. " /fade=" .. PWG_fade .. " /mode=release")
end

Delay Timing Patterns

Directional Delays

From Pulse Wave Generator:
local function PWG_getDelayString(direction, delayVal)
  if direction == "left" or direction == "out" then
    return delayVal .. " Thru 0"
  else
    return "0 Thru " .. delayVal
  end
end

-- Usage:
cmd("At 100")
cmd("Delay " .. delayStr) -- e.g., "0.2 Thru 0" or "0 Thru 0.2"

Complex Delay Presets

From Color Sweep Update:
for loop = 1, 4 do
  for i = 1, #timeList do
    for group = 1, #rows do
      gma.cmd('Group '..rows[group])
      
      if loop == 1 then 
        gma.cmd('PresetType '..pTypes_str..' At Delay 0 Thru '..timeList[i])
      elseif loop == 2 then 
        gma.cmd('PresetType '..pTypes_str..' At Delay '..(timeList[i] * 0.5)..' Thru 0')
      elseif loop == 3 then 
        gma.cmd('PresetType '..pTypes_str..' At Delay '..(timeList[i] * 0.5)..' Thru 0 Thru '..(timeList[i] * 0.5))
      elseif loop == 4 then 
        gma.cmd('PresetType '..pTypes_str..' At Delay 0 Thru '..(timeList[i] * 0.5)..' Thru 0')
      end
    end
    
    gma.cmd('Store Preset 0.'..presetCurrent..storeOptions)
    gma.cmd('Label Preset 0.'..presetCurrent..' "'..timeList[i]..'s '..directionNames[loop]..'"')
    presetCurrent = presetCurrent + 1
  end
end

Executor Assignment

Basic Assignment

function assignSequences()
  for seq = seqStart, seqStart + #groups - 1 do
    local executor = execPage..".."..(execStart + seq - seqStart)
    cmd("Assign Sequence "..seq.." At Executor "..executor)
  end
end

Advanced Executor Configuration

From Pulse Generator:
cmd('Assign Sequence '..PG_seq..' Executor '..PG_exec)
cmd('Assign Sequence '..PG_seq..' /track=off')
cmd('Assign Exec '..PG_exec..' /restart=next /priority=htp /offtime=0.2')
Disables tracking - each cue contains only its own values, not values from previous cues.
Enables tracking - values persist until changed (common for batch mode).
Pressing GO while sequence is running advances to next cue instead of restarting.
Uses Highest Takes Precedence priority mode.
Fade time when executor is released or turned off.
From Pulse Wave Generator:
cmd("Appearance Sequence " .. PWG_seq .. " /b=100 /r=50")
cmd("Assign Sequence " .. PWG_seq .. " Executor " .. PWG_exec)

if PWG_batch then
  cmd("Assign Sequence " .. PWG_seq .. " /track=on")
else
  cmd("Assign Sequence " .. PWG_seq .. " /track=off")
end

cmd("Assign Exec " .. PWG_exec .. " /restart=next /priority=htp /offtime=0.2")
cmd("Label Sequence " .. PWG_seq .. " \"" .. seqName .. "\"")
cmd("Label Exec " .. PWG_exec .. " \"" .. seqName .. "\"")

Sequence Appearance

Color Coding

-- Blue background, red text
cmd('Appearance Sequence '..PG_seq..' /b=100 /r=50')

-- Format: /b=hue (background) /r=hue (text)
Common color values:
  • /b=0 - Red
  • /b=50 - Orange
  • /b=100 - Blue
  • /b=200 - Green
  • /b=300 - Purple

Sequence Naming

Dynamic Sequence Names

From Pulse Wave Generator:
local grpName = ""
if #PWG_groups == 1 then
  grpName = "G" .. PWG_groups[1]
else
  grpName = "G" .. PWG_groups[1] .. "-" .. PWG_groups[#PWG_groups]
end

local dirName = ""
if PWG_dir == "rnd" then
  dirName = "Rnd" .. PWG_amount
else
  dirName = PWG_dirShortNames[PWG_dir] or PWG_dir
end

local seqName = "Wave " .. grpName .. " " .. dirName
-- Result: "Wave G1-4 L" or "Wave G5 Rnd4"

cmd("Label Sequence " .. PWG_seq .. " \"" .. seqName .. "\"")
cmd("Label Exec " .. PWG_exec .. " \"" .. seqName .. "\"")
Use descriptive, abbreviated names that convey the sequence’s purpose at a glance. Include group references and effect type.

Cue Trigger Configuration

Time-Based Triggers

-- Auto-trigger after specified time
cmd('Assign Sequence '..seq..' Cue '..cue..' /trig=time /trigtime='..trigTime)

-- With fade and release mode
cmd('Assign Sequence '..seq..' Cue '..cue..' /trig=time /trigtime='..trigTime..' /fade='..fade..' /mode=release')
Cue triggers automatically after a time delay.
The time in seconds before auto-triggering.
Fade time for the triggered cue.
Cue triggers when previous cue releases (for OFF cues).

Preset-Based Sequences

Storing Presets First

From Color Picker Update:
function createPresets()
  for group=grpStart, #groups do
    local presetCurrent = presetStart + ((group-1)* presetWidth)
    
    for start=1,colNb do
      local preset = presetCurrent+start-1
      cmd("Group "..group.." At Gel 1."..colSwatchIndex[start])
      cmd("Store Preset 4."..preset)
      cmd("Label Preset 4."..preset.." \""..groups[group].." "..colSwatchBook[start].."\"") 
    end
    clear()
  end
end

function createCues()
  for group=grpStart, #groups do
    local presetCurrent = presetStart + ((group-1)* presetWidth)
    for start=1, colNb do
      local preset = presetCurrent + start - 1
      local seqCurrent = seqStart + group - 1
      
      -- Reference preset instead of raw values
      cmd("Group "..group.." At Preset 4."..preset)
      cmd("Store Cue "..start.." Sequence "..seqCurrent)
    end
  end
end
This two-step approach (presets then cues) allows for easier updates - change the preset and all cues update automatically.

Store Options

Common store command flags from Color Sweep Update:
local storeOptions = ' /s /o /so=Prog /use=Active /v=false /vt=true /ef=false'

cmd('Store Preset 0.'..presetCurrent..storeOptions)
  • /s - Selective (only store changed attributes)
  • /o - Overwrite existing
  • /so=Prog - Store from Programmer
  • /use=Active - Use active values
  • /v=false - No verbose output
  • /vt=true - Use preset type values
  • /ef=false - Exclude effects

Progress Indication

For long sequence creation operations:
if totalPairs > 1 then
  PWG_progressHandle = gma.gui.progress.start("Creating Wave Sequence")
  gma.gui.progress.setrange(PWG_progressHandle, 1, totalPairs)
end

for i = 1, totalPairs do
  if PWG_progressHandle then
    gma.gui.progress.set(PWG_progressHandle, i)
    gma.gui.progress.settext(PWG_progressHandle, "Cue pair " .. i .. " of " .. totalPairs)
  end
  PWG_createCuePair(grpList[i], dirList[i], cueNum)
  cueNum = cueNum + 2
end

if PWG_progressHandle then
  gma.gui.progress.stop(PWG_progressHandle)
  PWG_progressHandle = nil
end

Complete Sequence Creation Example

Here’s a complete example combining all patterns:
local seqStart = 300
local execPage = 100
local execStart = 101

function buildCompleteSequence()
  cmd('BlindEdit On')
  
  -- Delete old sequences
  cmd("Delete Sequence "..seqStart.." Thru "..(seqStart+6).." /nc")
  
  -- Create new sequences
  for seq=0, 6 do
    local seqCurrent = seqStart + seq
    cmd("Store Sequence "..seqCurrent.." /o")
    cmd("Label Sequence "..seqCurrent.." \"Group "..string.char(65+seq).."\"") 
  end
  
  -- Create cues in each sequence
  for group=1, 7 do
    local seqCurrent = seqStart + group - 1
    for cue=1, 11 do
      cmd("Group "..group.." At Preset 4."..((group-1)*16 + cue))
      cmd("Store Cue "..cue.." Sequence "..seqCurrent)
      cmd("Label Sequence "..seqCurrent.." Cue "..cue.." \"Color "..cue.."\"") 
    end
    cmd('ClearAll')
  end
  
  -- Assign to executors
  for seq = seqStart, seqStart + 6 do
    local executor = execPage..".."..(execStart + seq - seqStart)
    cmd("Assign Sequence "..seq.." At Executor "..executor)
    cmd('Assign Sequence '..seq..' /track=off')
    cmd('Assign Exec '..executor..' /priority=htp')
  end
  
  cmd('BlindEdit Off')
  cmd('ClearAll')
end

Best Practices

1

Always Use Blind Edit

Wrap all sequence creation in blind edit mode to avoid affecting live output.
cmd('BlindEdit On')
-- ... sequence operations ...
cmd('BlindEdit Off')
2

Clean Up Old Sequences

Delete old sequences before creating new ones to avoid conflicts.
cmd("Delete Sequence "..start.." Thru "..finish.." /nc")
3

Use Descriptive Labels

Label sequences and cues clearly for easy identification.
cmd("Label Sequence "..seq.." Cue "..cue.." \"Full L\"")
4

Clear After Each Operation

Clear programmer after each cue/preset to avoid value bleeding.
cmd('Store Cue '..cue..' Sequence '..seq)
cmd('ClearAll')
5

Configure Tracking Appropriately

Use /track=off for independent cues, /track=on for building looks.

Build docs developers (and LLMs) love