Skip to main content

Overview

MAtricks (MA Tricks) is GrandMA2’s powerful selection and timing manipulation system. The MA2 Plugins use MAtricks commands to create sophisticated timing patterns for pulses, waves, and delay effects.

MAtricks Commands

MAtricksWings

Creates symmetrical patterns from the center or edges of a selection.
wingValue
number
required
Wing mode: 0 = no wings, 2 = symmetrical wings
-- Select group and apply wings
cmd('Group '..grp)
cmd('MAtricksWings '..wing)
Usage in PulseGenerator:
local function PG_create()
  cmd('BlindEdit On')
  
  cmd('Group '..PG_grp)
  cmd('MAtricksWings '..PG_wing)
  
  -- Rest of pulse creation
end
Usage in PulseWaveGen:
-- Determine wing value based on direction
local function PWG_getWing(direction)
  if direction == "in" or direction == "out" then
    return 2  -- Use wings for center-based effects
  else
    return 0  -- No wings for left/right
  end
end

local wing = PWG_getWing("in")
cmd("Group " .. grp)
if wing > 0 then
  cmd("MAtricksWings " .. wing)
end
Wings value of 2 creates a symmetrical pattern where fixtures are selected from the center outward or edges inward, perfect for “in” and “out” directional effects.

MAtricksInterleave

Divides the selection into interleaved blocks for pulse effects.
amount
number
required
Number of interleaved blocks to create
cmd('Group '..PG_grp)
cmd('MAtricksWings '..PG_wing)
cmd('MAtricksInterleave '..PG_amount)
Complete Example from PulseGenerator:
-- Setup
PG_grp = 1      -- Group 1
PG_amount = 4   -- 4 interleaved blocks
PG_wing = 0     -- No wings

-- Apply MAtricks
cmd('Group '..PG_grp)
cmd('MAtricksWings '..PG_wing)
cmd('MAtricksInterleave '..PG_amount)

-- Store cue pairs
while PG_cue <= PG_amount * 2 do
  cmd('Next')  -- Select next interleave block
  cmd('At 100')
  cmd('Store Sequence '..PG_seq..' Cue '..PG_cue)
  
  cmd('At 0')
  cmd('Store Sequence '..PG_seq..' Cue '..(PG_cue + 1))
  
  PG_cue = PG_cue + 2
end
With MAtricksInterleave 4, the Next command cycles through 4 different fixture blocks. This creates 4 pulse pairs (8 cues total) for a 4-way interleaved effect.

ShuffleSelection

Randomizes the order of the currently selected fixtures.
-- Random pulse order
cmd('Group '..PG_grp)
if(PG_rnd == 'true') then
  cmd('ShuffleSelection')
end
cmd('MAtricksInterleave '..PG_amount)
Random Delay Pattern Example:
-- From Color Sweep Update plugin
gma.cmd('ClearAll')

for i, group in ipairs(rows) do
  gma.cmd('Group '..group)
end

gma.cmd('ShuffleSelection')  -- Randomize all fixtures

for i, time in ipairs(timeList) do
  gma.cmd('PresetType '..pTypes_str..' At Delay 0 Thru '..time)
  gma.cmd('Store Preset 0.'..presetCurrent..storeOptions)
  gma.cmd('Label Preset 0.'..presetCurrent..' "'..timeList[i]..'s RND"')
  presetCurrent = presetCurrent + 1
end
Combine ShuffleSelection with delay spreads to create organic, random-feeling chase effects.

Delay Patterns with MAtricks

Linear Delay Spread

Create linear timing progressions across selections.
-- Left to right delay
cmd('Group '..grp)
cmd('At 100')
cmd('Delay 0 Thru '..delayTime)
cmd('Store Sequence '..seq..' Cue '..cueNum)

-- Right to left delay
cmd('Group '..grp)
cmd('At 100')
cmd('Delay '..delayTime..' Thru 0')
cmd('Store Sequence '..seq..' Cue '..cueNum)

Symmetrical Delay Spread

Create center-out or outside-in timing patterns.
-- Center out (wings mode)
local halfTime = delayTime / 2
cmd('Group '..grp)
cmd('At 100')
cmd('Delay '..halfTime..' Thru 0 Thru '..halfTime)
cmd('Store Sequence '..seq..' Cue '..cueNum)

-- Outside in (wings mode)
cmd('Group '..grp)
cmd('At 100')
cmd('Delay 0 Thru '..halfTime..' Thru 0')
cmd('Store Sequence '..seq..' Cue '..cueNum)
From Color Sweep Update:
-- Horizontal patterns with optional wings multiplier
local chaserWings_mult = 1
if chaserWings then chaserWings_mult = 0.5 end

for loop = 1, 4 do
  for i = 1, #timeList do
    for group = 1, #rows do
      gma.cmd('Group '..rows[group])
      
      if loop == 1 then
        -- Left to right
        gma.cmd('PresetType '..pTypes_str..' At Delay 0 Thru '..timeList[i])
      elseif loop == 2 then
        -- Right to left
        gma.cmd('PresetType '..pTypes_str..' At Delay '..(timeList[i] * chaserWings_mult)..' Thru 0')
      elseif loop == 3 then
        -- Center out
        gma.cmd('PresetType '..pTypes_str..' At Delay '..(timeList[i] * chaserWings_mult)..' Thru 0 Thru '..(timeList[i] * chaserWings_mult))
      elseif loop == 4 then
        -- Outside in
        gma.cmd('PresetType '..pTypes_str..' At Delay 0 Thru '..(timeList[i] * chaserWings_mult)..' Thru 0')
      end
    end
    
    gma.cmd('Store Preset 0.'..presetCurrent..storeOptions)
    presetCurrent = presetCurrent + 1
  end
end

Advanced Patterns

Multi-Group Wave Effects

PulseWaveGen Single Stack Mode:
local function PWG_createSingleStack()
  cmd("BlindEdit On")
  
  local wing = PWG_getWing(PWG_dir)
  local delayStr = PWG_getDelayString(PWG_dir, PWG_delay)
  
  PWG_clear()
  
  -- Build Full cue with all groups
  for i, grp in ipairs(PWG_groups) do
    cmd("Group " .. grp)
    if wing > 0 then
      cmd("MAtricksWings " .. wing)
    end
    cmd("PresetType \"DIMMER\"")
    cmd("At 100")
    PWG_sleep(0.05)
    cmd("Delay " .. delayStr)
    PWG_sleep(0.05)
  end
  
  cmd("Store Sequence " .. PWG_seq .. " Cue 1")
  
  -- Build Off cue with same pattern
  PWG_clear()
  
  for i, grp in ipairs(PWG_groups) do
    cmd("Group " .. grp)
    if wing > 0 then
      cmd("MAtricksWings " .. wing)
    end
    cmd("At 0")
    PWG_sleep(0.05)
    cmd("Delay " .. delayStr)
    PWG_sleep(0.05)
  end
  
  cmd("Store Sequence " .. PWG_seq .. " Cue 2")
end
When combining multiple groups with delays in a single cue, apply the delay command after each group selection to ensure proper timing stacking.

Vertical Delay Arrays

From Color Sweep Update:
-- Calculate proportional delays for rows
local divisions = {}
if (#groups > 1) then
  local divCt = #groups - 1
  local interval = 1 / divCt
  local proportion = 0
  
  for grp = 1, #groups do
    divisions[grp] = proportion
    proportion = proportion + interval
  end
end

-- Apply delays to each row
for time = 1, #timeList do
  for grp = 1, #groups do
    cmd('Group '..rows[grp])
    
    local delayTime = timeList[time] * divisions[grp]
    cmd('PresetType 4 At Delay '..trunc(delayTime, 0.001))
  end
  
  cmd('Store Preset 0.'..presetCurrent..' /s /o')
  presetCurrent = presetCurrent + 1
end

Best Practices

Order of Operations: Always apply MAtricks commands in this order:
  1. Select group(s)
  2. Apply wings (if needed)
  3. Apply interleave/shuffle (if needed)
  4. Set values (At, Delay, etc.)
  5. Store
PresetType Filtering: When applying delays to specific preset types, specify the type before the At/Delay command:
cmd('PresetType "DIMMER"')
cmd('At 100')
cmd('Delay 0 Thru 0.5')
Delay Precision: Use the trunc() helper to avoid scientific notation in delay values:
-- Bad: 0.123456789 might display as 1.23e-1
cmd('At Delay '..delayValue)

-- Good: Truncate to 3 decimal places
cmd('At Delay '..trunc(delayValue, 0.001))

Common MAtricks Workflows

Pulse Effect Workflow

1

Select and configure MAtricks

cmd('Group '..grp)
cmd('MAtricksWings '..wings)
if random then cmd('ShuffleSelection') end
cmd('MAtricksInterleave '..amount)
2

Create ON cue

cmd('Next')  -- Select first interleave block
cmd('At 100')
cmd('Store Sequence '..seq..' Cue '..cueNum)
3

Create OFF cue with auto-release

cmd('At 0')
cmd('Store Sequence '..seq..' Cue '..(cueNum + 1))
cmd('Assign Sequence '..seq..' Cue '..(cueNum + 1)..' /trig=time /trigtime=0.1 /mode=release')
4

Repeat for remaining interleave blocks

Loop through steps 2-3 for each interleave block.

Wave Effect Workflow

1

Determine direction parameters

local wing = PWG_getWing(direction)  -- 0 or 2
local delayStr = PWG_getDelayString(direction, delayTime)
2

Apply to group

cmd('Group '..grp)
if wing > 0 then
  cmd('MAtricksWings '..wing)
end
3

Apply values with delay

cmd('At 100')
cmd('Delay '..delayStr)
cmd('Store Sequence '..seq..' Cue '..cueNum)

Build docs developers (and LLMs) love