Posts by hepi


    Hi ALL !

    Can we ask for documentation please for the Object API.

    Does anyone have direct contact with MA Lighting?
    What are they saying about this lack of documentation ??

    Here is a list of all the known functions (not documented), in TypeScript definition

    This simple plugin (which uses an undo block) causes a crash when it is "Oops"-ed

    return function()
      local undo = CreateUndo("MyAction")
      Cmd("Delete Layout 1000.1", undo)
      Cmd("Assign Macro 1000 At Layout 1000", undo)

    How to reproducing the crash

    (MA3 1.8.8, 1.8.1)

    1. Define a plugin with the above code

    2. Run these commands:

    Store Layout 1000
    Store Macro 1000
    Assign Macro 1000 At Layout 1000

    3. Run the plugin once

    4. Hit the "oops" button

    5. Run the plugin again


    Enjoy :)


    My plugin has internal state, which is stored in a PluginVariable.
    The "SetVar" Lua function has no "undo" argument. (AFIK)
    And when the user presses "Oops" , these variable value is not changed back.

    Suggested Solution:

    I think the there should be a way to listen for "Oops" events on specific undo handles.
    Something like this:

    function onUndo(undoName)
       Echo(undoName .. " was reverted"
    local undo = CreateUndo("MyAction 1")
    Cmd("Store something", undo)


    Since I don't believe this already exists, we need to submit a feature request for it.
    In the meantime, I can think of a workaround (didn't try it yet)

    I can create a dummy Sequence, and for each undo block that I create I can add a cue to that sequence, and I register a hook on this sequence.
    Then when the user Oops's, the cue would be deleted, and my hook would get called.

    Does that sound like a decent workaround?


    My plugin generates many appearances for it's UI layouts.
    These appearance are of no interest to the user.

    I am trying to avoid them from being seen in the "Select Appearance" dialog:

    I thought about putting them in a different DataPool, but it seems that Appearances are NOT part of the DataPool.
    They are also not part of the User Profile.
    So I guess they are global (right?)

    Any ideas on how to achieve this?


    I am trying to figure out if it is possible to modify system menus, and add features.
    For example, I want to add a custom selection value to the "Group Pool Setting" window.

    I was able to add the UI SwipeButton element, but modifying this file:
    /Users/[your user]/MALightingTechnology/gma3_1.8.1/shared/resource/lib_menus/ui/window_context/context_group_pool.uixml

    But I can't define the values for this SwipeButton,
    and I can find how to listen for changes in it's values.

    Does anyone have any idea about this subject.
    It's not really plugin development, I guess it's kind of a hack...


    I don't know when the "Execute" function is being run.
    I put a "Printf" in it but I never see it being printed. (Only the Main and Cleanup are called)

    How do you make the Execute function to be called?

    Now, I was digging into MA3 lua code which can be found, for example, here:
    /Users/[your user]/MALightingTechnology/gma3_1.8.1/shared/resource/lib_menus/ui/window_add/add_window.lua

    And I see the signalTable being used as an event listener.
    I was able to add a "Printf" in this function:
    (line 15 of add_window.lua)

    signalTable.AddWindowLoaded = function(caller, status, creator)

    I restarted MA3,
    and when I click on an empty screen space, and the "Add Window" dialog appeared, I saw my debug line begin printed.

    I am not sure this is relevant for Plugin development though.
    I hope there might be an event like, "OnPluginLoaded" or something that will replace the need for a StartupMacro.
    But there is no documentation about that.
    And dumping the signalTable, yields nothing.

    local pluginName = select(1,...);
    local componentName = select(2,...);
    local signalTable = select(3,...);
    local my_handle = select(4,...);


    - pluginName: is the plugin name which is the plugin's object name int the Plugins pool. Note that it can be change by the user, and your LUA code will NOT be aware of it !

    - componentName: is the plugin's component's name. A plan may have several component, each having an index and name. When you click a plugin object in the plugins pool, it always runs the first component. You can run other components directly using the "Plugin" command, e.g. "Plugin 3.1" runs component 3 of plugin with index 1.

    - signalTable: I don't know yet, but I guess it is some kind of object that you can put event listeners on, and listen to system events. I see it in use in the built in menus.

    - my_handle: This is the plugin's object handle (UserData). you need this when you register hooks.

    There is an execute_example.lua file under:

    This plugin returns:

    return Main,Cleanup,Execute

    I am curious about the Execute function.

    It is defined as such:

    -- ****************************************************************
    -- plugin execute entry point
    -- ****************************************************************

    local function Execute(Type,...)
    E("Execute-Example: Execute called")
    local func=signalTable[Type];
    if(func) then
    local debug_text=string.format("Execute %s not supported",Type);

    function signalTable:Key(Status,Source,Profile,Token)
    local debug_text=F("Execute Key (%s) %s UserProfile %d : %s",Status,Source,Profile,Token);

    function signalTable:Fader(Status,Source,Profile,Token,Value)
    local debug_text=F("Execute Fader (%s) %s UserProfile %d : %s %f",Status,Source,Profile,Token,Value);

    I don't really understand it yet.
    I don't understand what the signalTable is.
    But the interesting part is the "signalTable:Fader",
    could there be a way to listen to fader movement?

    Any information about this signalTable would be appreciated 🙏

    Oh this workaround turned out great.

    The Window object has an APPEARANCE property that actually does NOT affect the window appearance at all (-:
    The Window object has a child called "Pool Settings" in which there is another APPEARANCE prop, which is the actual one being used.

    So.. for now, I can freely use the Window's APPEARANCE, since it seems to be NOT-IN-USE.
    Not so future-proof, but it's work... until it doesn't...🥴
    Luckily this plugin is not a REAL-TIME crucial-task plugin.

    I don't see a Scribble for a Window,
    but there is the Appearance. I can use that.
    That's a good idea.

    Of course, would love to have a LUA way to do it that is hidden from the user.


    My use-case is this:

    My plugin is adding a few Windows to the screen, and I want to be able to identify them.

    These identifiers should persist when:

    • The user is making changes to the windows (removing them or adding new ones),
    • The user loas another view and comes back to my view.

    Solutions that did go well:

    - I tried using the window Index, but it can change if the user is deleting windows. So I need hooks to monitor every change in the screen's windows. sounds too complicated.

    - I tried using the Window object handles, but when view is loaded, the windows are always newly allocated objects.

    Any suggestions?

    I saw that every MA Object has these 2 properties:

    [Custom GUID]

    Maybe I could use those some how to put a custom identified on the Window's objects?


    Why won't the DMX remote workaround, work with an onPC ?

    BTW: the post you referenced, says it is not possible from LUA global code.
    So what did you mean when you wrote "you can also do it from commandline" ?

    I think that "Startup Macro" is still not implemented in MA3. (version 1.8.1)

    This means that I can't use Hooks in my plugin, since I don't have a way to initialize them when the system starts.

    (And I have to resort to adding them only after the first user interaction)

    What's up with that !?😤

    Anyone has a hunch about when MA will add a startup macro?

    But your solution is much better (not a hack like mine) , you strike again !
    How do you get these insights?
    I was looking at the children of the Display Object, and didn't dig deep enough.

    So the UiScreen is here:
    Root()["GraphicsRoot"]["PultCollect"]["Pult 1"]["DisplayCollect"]["Display 1"]["ScrollIndicatorBox"]["ScreenScroll"]["ScrollBox"]["UiScreen"]

    fI you would like to get a glimpse of the plugin I am working on,
    login to my web-site (under-construction):

    after you login, I will give you permissions to download the beta version

    Thanks again.

    Clintos You too

    And I'll make you a Beta-Tester (-:

    I solved it like this:
    (Code snippet written in TypeScript)
    It pretty robust.