Skip to main content

Overview

The MA2 Plugins share several common helper functions that simplify plugin development and improve code readability. These utilities handle sleep timing, programmer clearing, group parsing, and preset management.

Basic Utilities

sleep()

Wrapper function for gma.sleep() to simplify timing control.
s
number
required
Number of seconds to pause
function sleep(s)
  gma.sleep(s)
end

-- Usage
sleep(0.1)
sleep(0.5)
Alternatively, plugins may use local scoped versions:
local function PG_sleep(s)
  gma.sleep(s)
end

local function PWG_sleep(s)
  gma.sleep(s)
end

clear()

Clears all programmer content (selections, values, delays).
function clear()
  cmd('ClearAll')
end

-- Usage
clear()  -- Clear programmer after storing
Local versions:
local function PG_clear()
  cmd('ClearAll')
end

local function PWG_clear()
  cmd("ClearAll")
end
Always clear the programmer after storing presets or cues to prevent unintended data in subsequent stores.

Group Management

getGroup()

Retrieves the fixture/channel list from a group by exporting to XML and parsing.
grpNum
number
required
Group number to retrieve fixtures from
groupList
table
Array of fixture/channel strings (e.g., {"Fixture 1", "Fixture 2.1", "Channel 50"})
function getGroup(grpNum)
  gma.cmd('SelectDrive 1')
  
  local file = {}
  file.name = 'tempfile_getgroup.xml' 
  file.directory = gma.show.getvar('PATH')..'/'..'importexport'..'/'
  file.fullpath = file.directory..file.name
  
  gma.cmd('Export Group ' .. grpNum .. ' "' .. file.name .. '"')
  
  local t = {}
  for line in io.lines(file.fullpath) do
    t[#t + 1] = line
  end
  os.remove(file.fullpath)
  
  local groupList = {}
  for i = 1, #t do
    if t[i]:find('Subfixture ') then
      local indices = {t[i]:find('"%d+"')}
      indices[1], indices[2] = indices[1] + 1, indices[2] - 1
      
      local fixture
      if t[i]:find('fix_id') then
        fixture = 'Fixture ' .. tostring(t[i]:sub(indices[1], indices[2]))
      elseif t[i]:find('cha_id') then
        fixture = 'Channel ' .. tostring(t[i]:sub(indices[1], indices[2]))
      end
      
      if t[i]:find('sub_index') then
        local indices = {t[i]:find('"%d+"', indices[2]+2)}
        indices[1], indices[2] = indices[1] + 1, indices[2] - 1
        fixture = fixture .. '.' .. tostring(t[i]:sub(unpack(indices)))
      end
      
      groupList[#groupList + 1] = fixture
    end
  end
  
  return groupList
end
Usage:
-- Generate group arrays for multiple rows
local groups = {}
for i = 1, #rows do
  groups[i] = getGroup(rows[i])
end

-- Result: groups[1] = {"Fixture 1", "Fixture 2", ...}
--         groups[2] = {"Fixture 10", "Fixture 11", ...}
This function creates a temporary XML file in the show’s importexport directory and deletes it after parsing. Ensure the console has write access to this directory.

Delay String Helpers

PWG_getDelayString()

Generates delay command strings based on wave direction.
direction
string
required
Direction: “left”, “right”, “in”, or “out”
delayVal
number
required
Maximum delay time in seconds
delayString
string
Formatted delay command (e.g., “0.2 Thru 0” or “0 Thru 0.2”)
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
local delayStr = PWG_getDelayString("left", 0.2)
cmd("Delay " .. delayStr)  -- Results in: Delay 0.2 Thru 0

PWG_getWing()

Determines wing value for MAtricks based on direction.
direction
string
required
Direction: “left”, “right”, “in”, or “out”
wing
number
Wing value: 2 for “in”/“out”, 0 for “left”/“right”
local function PWG_getWing(direction)
  if direction == "in" or direction == "out" then
    return 2
  else
    return 0
  end
end

-- Usage
local wing = PWG_getWing("in")  -- Returns 2
if wing > 0 then
  cmd("MAtricksWings " .. wing)
end

Random Selection Helpers

PWG_pickRandomAvoid()

Selects a random item from a list while avoiding the last selection.
list
table
required
Array of items to choose from
lastPick
any
Previously selected item to avoid (optional)
selection
any
Randomly selected item (different from lastPick if possible)
local function PWG_pickRandomAvoid(list, lastPick)
  if #list == 0 then
    return nil
  end
  if #list == 1 then
    return list[1]
  end
  
  local available = {}
  for _, item in ipairs(list) do
    if item ~= lastPick then
      table.insert(available, item)
    end
  end
  
  if #available == 0 then
    available = list
  end
  
  return available[math.random(1, #available)]
end

PWG_getRandomDirections()

Generates a list of random directions, avoiding consecutive duplicates.
count
number
required
Number of random directions to generate
directions
table
Array of direction strings
local function PWG_getRandomDirections(count)
  local baseDirections = {"left", "right", "in", "out"}
  local result = {}
  local lastDir = nil
  
  for i = 1, count do
    local newDir = PWG_pickRandomAvoid(baseDirections, lastDir)
    table.insert(result, newDir)
    lastDir = newDir
  end
  
  return result
end

-- Usage
local dirList = PWG_getRandomDirections(4)
-- Result: {"left", "out", "right", "in"}

PWG_getRandomGroups()

Generates a random sequence of groups, avoiding consecutive duplicates.
groupList
table
required
Array of group numbers to choose from
count
number
required
Number of random groups to generate
groups
table
Array of group numbers
local function PWG_getRandomGroups(groupList, count)
  local result = {}
  local lastGrp = nil
  
  for i = 1, count do
    local newGrp = PWG_pickRandomAvoid(groupList, lastGrp)
    table.insert(result, newGrp)
    lastGrp = newGrp
  end
  
  return result
end

-- Usage
local PWG_groups = {"1", "2", "3"}
local grpList = PWG_getRandomGroups(PWG_groups, 6)
-- Result: {"2", "1", "3", "2", "3", "1"}

Mathematical Utilities

trunc()

Truncates a number to a specified precision to avoid scientific notation.
num
number
required
Number to truncate
mod
number
required
Precision modulus (e.g., 0.001 for 3 decimal places)
result
number
Truncated number
function trunc(num, mod)
  local x = num - (num % mod)
  return x
end

-- Usage
local delay = 0.123456789
local truncated = trunc(delay, 0.001)  -- Returns 0.123

gma.cmd('PresetType 4 At Delay '..trunc(divisionTimes[set][time][grp], 0.001))

Reset Functions

Plugins should reset their variables after completion to prevent state pollution.

ColorPickerUpdate Reset

function resetValues()
  updateMode = 0
end

PulseGenerator Reset

local function PG_resetValues()
  PG_grp = 0
  PG_seq = 0
  PG_exec = 0
  PG_amount = 0
  PG_wing = 0
  PG_trigTime = 0.1
  PG_fade = 0.05
  PG_rnd = 'false'
  PG_cue = 1
  PG_white = 'false'
end

PulseWaveGen Reset

local function PWG_resetValues()
  PWG_batch = false
  PWG_singleStack = false
  PWG_groups = {}
  PWG_dir = "left"
  PWG_seq = 0
  PWG_exec = 0
  PWG_amount = 1
  PWG_delay = 0.2
  PWG_trigTime = 0.1
  PWG_fade = 0.05
end
Always call reset functions at the end of plugin execution to ensure clean state for subsequent runs.

Build docs developers (and LLMs) love