Skip to main content

MacroDefinition

This is how we define the behaviour of a Macro.

There are a few Required members for a MacroDefinition to be valid.

Many fields are Populated, where if it is not defined in your MacroDefinition, will be auto-filled by Socket with a default value.

There are some Read-Only fields, that you'll want to avoid defining in your MacroDefinition and let them be Populated by Socket.

Types

MacroState

interface MacroState {
FieldValuestable<MacroField.Name,any>--

Where we can read the values in our fields from

IsRunningboolean | nil--

Use this variable to toggle the state of a Macro (updates the UI)

IsKeybindDisabledboolean | nil--

An internal variable for declaring whether a keybind has been disabled or not

_ServerMacroState--

Socket-only (used for communcicating Server/Client in Accurate Play Solo)

_ClientMacroState--

Socket-only (used for communcicating Server/Client in Accurate Play Solo)

}

A table to store a macro's "State". Socket writes some stuff here, but feel free to use this for whatever you need. If you overwrite any keys that Socket uses (fields defined here), expect mayhem and tears!

Properties

Name

Required
MacroDefinition.Name: string

Declares the name that will appear on the Widget for the Macro.

caution

Longer names will be less readable on the Widget, depending on a user's resolution

NameColor

Populated
MacroDefinition.NameColor: Color3

Give your Macro a pretty color on the Widget!

Defaults to Color.fromRGB(255, 255, 255)

Icon

Populated
MacroDefinition.Icon: string

Defines an icon to put alongside the Name of the Macro.

This can either be Text (e.g., Emoji) or an ImageId. ImageIds are recognised by the string containing rbxasset

{
    Icon = "📂" -- Good
    Icon = "My Icon" -- Probably too long, but good
    Icon = "" -- Bit boring, but good
    Icon = "rbxassetid://9553550332" -- Good ImageId
    Icon = "https://www.roblox.com/library/9553550338/" -- Bad ImageId (Website)
    Icon = "http://www.roblox.com/asset/?id=9553550332" -- Bad ImageId (Decal)
}

Defaults to "❓"

IconColor

Populated
MacroDefinition.IconColor: Color3

Give your Macro icon a pretty color on the Widget! Applies to TextColor3 or ImageColor3, depending on Icon input

Defaults to Color.fromRGB(255, 255, 255)

Group

Populated
MacroDefinition.Group: string

The group that the Macro belongs to. Any macros with a matching Group value will be grouped together on the Widget

Defaults to "No Group"

GroupColor

Populated
MacroDefinition.GroupColor: Color3

Give the Group text a pretty color on the Widget! If you have multiple Macros under the same Group, GroupColor need only be defined on a singular MacroDefinition.

Defaults to Color.fromRGB(255, 255, 255)

GroupIcon

Populated
MacroDefinition.GroupIcon: string

Defines an icon to put alongside the name of the Group the Macro is under. If you have multiple Macros under the same Group, GroupIcon need only be defined on a singular MacroDefinition

This can either be Text (e.g., Emoji) or an ImageId. ImageIds are recognised by the string containing rbxasset

{
    Icon = "📂" -- Good
    Icon = "My Icon" -- Probably too long, but good
    Icon = "" -- Bit boring, but good
    Icon = "rbxassetid://9553550332" -- Good ImageId
    Icon = "https://www.roblox.com/library/9553550338/" -- Bad ImageId (Website)
    Icon = "http://www.roblox.com/asset/?id=9553550332" -- Bad ImageId (Decal)
}

Defaults to "❓"

GroupIconColor

Populated
MacroDefinition.GroupIconColor: Color3

Give your Macro icon a pretty color on the Widget! Applies to TextColor3 or ImageColor3, depending on Icon input. If you have multiple Macros under the same Group, GroupIconColor need only be defined on a singular MacroDefinition

Defaults to Color.fromRGB(255, 255, 255)

Description

Populated
MacroDefinition.Description: string

Any and all information pertaining to this specific Macro. This can be as long as you like as it appears in the output.

{
    Description = "Macro Description Line 1\nMacro Description Line 2"
}

Output:

================ Macro Name (Macro Group) | DESCRIPTION ================ 

Macro Description Line 1
Macro Description Line 2

================ Macro Name (Macro Group) | DESCRIPTION ================

Defaults to "No Description"

LayoutOrder

Populated
MacroDefinition.LayoutOrder: number

Can be used to define the position of where the Macro is rendered on the Widget. Higher numbers are rendered further down the widget. Works very much the same as LayoutOrder on Roblox Instances.

See Settings

Defaults to 0

EnableAutomaticUndo

Populated
MacroDefinition.EnableAutomaticUndo: boolean

If true, will automatically setup ChangeHistoryService waypoints before and after running the Macro's Function. AKA, any changes to studio that your Macro makes, you can undo with Ctrl+Z or equivalent.

You can obviously set this to false (or don't declare the field) if you want to write your own implementation.

tip

When you run "Undo" in Studio, it will undo the last change under the DataModel (game). If, for example, your Macro just prints to the output (and doesn't make any changes to the DataModel) it will undo the last change unrelated to your Macro

Defaults to false

IgnoreGameProcessedKeybinds

Populated
MacroDefinition.IgnoreGameProcessedKeybinds: boolean

Socket uses UserInputService#InputBegan for detecting keybinds.

game:GetService("UserInputService").InputBegan:Connect(function(inputObject, gameProcessedEvent)
    if gameProcessedEvent and not IgnoreGameProcessedKeybinds then
        return
    end

    ...
end)

Defaults to false

AutoRun

Populated
MacroDefinition.AutoRun: boolean

If true, macro.Function will be called when Socket starts. Useful if there is a macro you want to run on startup.

Defaults to false

IsLocalMacro

Populatedv1.1.0
MacroDefinition.IsLocalMacro: boolean

If a macro is a "Local Macro", this value will be populated as true.

Local Macros replicate across different roblox places by being stored under the Socket plugin. You can add a Local Macro by placing it under

game.ServerStorage.SocketPlugin.LocalMacros[userId] -- Where userId is your own userId
tip

Don't know what your userId is? It's the number in the URL of your profile, or you can find it by running the following in the command line:

print(game:GetService("StudioService"):GetUserId())

Keybind

Populated
MacroDefinition.Keybind: {Enum.KeyCode}

An array of Enum.KeyCode that can trigger the Macro to run.

{
    Keybind = { Enum.KeyCode.LeftControl, Enum.KeyCode.J }
}    
tip

Will not work if any of the inputs have gameProcessedEvent set to true. See: UserInputService

To disable this, see [TODO]

Defaults to {}

Fields

Populated
MacroDefinition.Fields: {MacroField}

An array of MacroField, which define the different fields the Macro has. The order they are defined is the order they will appear on the widget.

{
    Fields = { 
        {
            Name = "Amount";
            Type = "number";
            IsRequired = true;
        },
        {
            Name = "Title";
            Type = "string";
        }
    }
}    

Defaults to {}

FieldChanged

Read-Only
MacroDefinition.FieldChanged: BindableEvent

A BindableEvent to listen to field values being changed on the UI!

macro.FieldChanged.Event:Connect(function(fieldName, fieldValue)
    print(macro:GetFieldValue(fieldName) == fieldValue)
end)

-- Output: true

Most cases it will suffice to just read macro:GetFieldValue(fieldName) as and when you need a field value. But sometimes you may want to re-run routines after a field value change.

State

Populated
MacroDefinition.State: MacroState

A persistent State of the Macro while the Socket plugin is running. We can write to this inside the MacroDefinition, and read/write to it in our Function and BindToClose/BindToOpen functions.

We can declare default values for fields:

{
    Fields = {
        {
            Name = "Size";
            Type = "Vector3";
        }
    }
    State = {
        FieldValues = {
            Size = Vector3.new(2, 2, 2); -- Will automatically appear on the Widget
        }
    }
}

We can also access IsRunning:

local Heartbeat = game:GetService("RunService").Heartbeat

-- MacroDefinition that, when running, will print the time since the last frame
{
    Function = function(macro, plugin)
        -- Toggle running state
        macro:ToggleIsRunning()
    
        -- Running routine
        if macro:IsRunning() then
            -- Add to our RunJanitor
            -- Automatically gets cleaned up when we toggle IsRunning to false via ToggleIsRunning
            -- Also gets cleaned up when BindToClose is called
            macro.RunJanitor:Add(Heartbeat:Connect(function(dt)
                Logger:MacroInfo(macro, ("dt: %f"))
            end))
        end
    end
}

Defaults to

{
    FieldValues = {};
    IsRunning = false;
    _Server = {};
    _Client = {};
}

RunJanitor

Read-Only
MacroDefinition.RunJanitor: Janitor

A Janitor object, intended to be used to cleanup tasks after a macro stops running.

Is automatically cleaned up when using macro:ToggleIsRunning(), and on BindToClose

Disabled

Populated
MacroDefinition.Disabled: boolean

If true, this Macro will not be displayed on the Widget. It's Function will also not be required, nor registered. This renders AutoRun useless for this specific MacroDefinition

tip

This can be useful to create a MacroDefinition solely for defining the aesthetics of a Group for organisation purposes.

    {
        Group = "Fruity Macros",
        GroupIcon = "🍎",
        GroupColor = Color3.fromRGB(200, 20, 20),
        Disabled = true,
    }

Defaults to false

Functions

Function

Required
MacroDefinition.Function(
pluginPlugin
) → ()

The function that will be called when we Run the Macro.

caution

This function is not allowed to yield; wrap any yielding routines in a task.spawn or equivalent

BindToClose

MacroDefinition.BindToClose(
pluginPlugin
) → ()

This is a function that is called when:

  1. The Socket Plugin is exited
  2. The Macro is removed while the Socket Plugin is running

Use this to clean anything up instantiated by the Macro

caution

This function is not allowed to yield; wrap any yielding routines in a task.spawn or equivalent

Order of operations: 1) BindToClose is called 2) macro.State.IsRunning = false 3) macro.RunJanitor:Cleanup()

BindToOpen

MacroDefinition.BindToOpen(
pluginPlugin
) → ()

This is a function that is called when the Socket plugin is started! This has some rare use cases.

For the most part, Socket is really good at calling BindToClose when it is needed, but there are some Roblox limitations. Imagine we have a macro that makes significant changes in game.Workspace (e.g., changes the Color3 of part(s)). If Roblox Studio is suddenly closed, or crashes, it's possible the changes the macro made will be saved, but the "stopping" logic is never run. BindToOpen can be used to run checks to cleanup any mess left from the previous session. This is more a failsafe than a requirement, but can save headaches!

For a good example use-case, see the Socket Core Macro .Locked

caution

This function is not allowed to yield; wrap any yielding routines in a task.spawn or equivalent

GetFieldValue

Read-Only
MacroDefinition:GetFieldValue(fieldNamestring) → any

Sugar for

macro.State.FieldValues[fieldName]

ToggleIsRunning

Read-Only
MacroDefinition:ToggleIsRunning() → ()

Sugar for

macro.State.IsRunning = not macro.State.IsRunning
if not macro.State.IsRunning then
    macro.RunJanitor:Cleanup()
end

IsRunning

Read-Only
MacroDefinition:IsRunning() → boolean

Returns true if the Macro is running (macro.State.IsRunning == true). False otherwise.

Sugar for

macro.State.IsRunning
Show raw api
{
    "functions": [
        {
            "name": "GetFieldValue",
            "desc": "Sugar for\n```lua\nmacro.State.FieldValues[fieldName]\n```",
            "params": [
                {
                    "name": "fieldName",
                    "desc": "",
                    "lua_type": "string"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "any"
                }
            ],
            "function_type": "method",
            "tags": [
                "Read-Only"
            ],
            "source": {
                "line": 290,
                "path": "docs_api/macro_definition.lua"
            }
        },
        {
            "name": "ToggleIsRunning",
            "desc": "Sugar for\n```lua\nmacro.State.IsRunning = not macro.State.IsRunning\nif not macro.State.IsRunning then\n    macro.RunJanitor:Cleanup()\nend\n```",
            "params": [],
            "returns": [],
            "function_type": "method",
            "tags": [
                "Read-Only"
            ],
            "source": {
                "line": 391,
                "path": "docs_api/macro_definition.lua"
            }
        },
        {
            "name": "IsRunning",
            "desc": "Returns true if the Macro is running (`macro.State.IsRunning == true`). False otherwise.\n\nSugar for\n```lua\nmacro.State.IsRunning\n```",
            "params": [],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "boolean"
                }
            ],
            "function_type": "method",
            "tags": [
                "Read-Only"
            ],
            "source": {
                "line": 405,
                "path": "docs_api/macro_definition.lua"
            }
        },
        {
            "name": "Function",
            "desc": "The function that will be called when we Run the Macro.\n\n:::caution\nThis function is not allowed to yield; wrap any yielding routines in a `task.spawn` or equivalent\n:::",
            "params": [
                {
                    "name": "macro",
                    "desc": "",
                    "lua_type": "MacroDefinition"
                },
                {
                    "name": "plugin",
                    "desc": "",
                    "lua_type": "Plugin"
                }
            ],
            "returns": [],
            "function_type": "static",
            "tags": [
                "Required"
            ],
            "source": {
                "line": 419,
                "path": "docs_api/macro_definition.lua"
            }
        },
        {
            "name": "BindToClose",
            "desc": "This is a function that is called when:\n1. The Socket Plugin is exited\n2. The Macro is removed while the Socket Plugin is running\n\nUse this to clean anything up instantiated by the Macro\n\n:::caution\nThis function is not allowed to yield; wrap any yielding routines in a `task.spawn` or equivalent\n:::\n\nOrder of operations:\n1) `BindToClose` is called\n2) `macro.State.IsRunning = false`\n3) `macro.RunJanitor:Cleanup()`",
            "params": [
                {
                    "name": "macro",
                    "desc": "",
                    "lua_type": "MacroDefinition"
                },
                {
                    "name": "plugin",
                    "desc": "",
                    "lua_type": "Plugin"
                }
            ],
            "returns": [],
            "function_type": "static",
            "source": {
                "line": 441,
                "path": "docs_api/macro_definition.lua"
            }
        },
        {
            "name": "BindToOpen",
            "desc": "This is a function that is called when the Socket plugin is started! This has some rare use cases.\n\nFor the most part, Socket is really good at calling `BindToClose` when it is needed, but there are some Roblox limitations.\nImagine we have a macro that makes significant changes in `game.Workspace` (e.g., changes the `Color3` of part(s)). If Roblox Studio\nis suddenly closed, or crashes, it's possible the changes the macro made will be saved, but the \"stopping\" logic is never run. `BindToOpen` can\nbe used to run checks to cleanup any mess left from the previous session. This is more a failsafe than a requirement, but can save headaches!\n\nFor a good example use-case, see the Socket Core Macro `.Locked`\n\n:::caution\nThis function is not allowed to yield; wrap any yielding routines in a `task.spawn` or equivalent\n:::",
            "params": [
                {
                    "name": "macro",
                    "desc": "",
                    "lua_type": "MacroDefinition"
                },
                {
                    "name": "plugin",
                    "desc": "",
                    "lua_type": "Plugin"
                }
            ],
            "returns": [],
            "function_type": "static",
            "source": {
                "line": 461,
                "path": "docs_api/macro_definition.lua"
            }
        }
    ],
    "properties": [
        {
            "name": "Name",
            "desc": "Declares the name that will appear on the Widget for the Macro.\n\n:::caution\nLonger names will be less readable on the Widget, depending on a user's resolution\n:::",
            "lua_type": "string",
            "tags": [
                "Required"
            ],
            "source": {
                "line": 24,
                "path": "docs_api/macro_definition.lua"
            }
        },
        {
            "name": "NameColor",
            "desc": "Give your Macro a pretty color on the Widget!\n\nDefaults to `Color.fromRGB(255, 255, 255)`",
            "lua_type": "Color3",
            "tags": [
                "Populated"
            ],
            "source": {
                "line": 34,
                "path": "docs_api/macro_definition.lua"
            }
        },
        {
            "name": "Icon",
            "desc": "Defines an icon to put alongside the `Name` of the Macro.\n\nThis can either be `Text` (e.g., Emoji) or an `ImageId`. `ImageIds` are recognised by the string containing `rbxasset`\n\n```lua\n{\n    Icon = \"📂\" -- Good\n    Icon = \"My Icon\" -- Probably too long, but good\n    Icon = \"\" -- Bit boring, but good\n    Icon = \"rbxassetid://9553550332\" -- Good ImageId\n    Icon = \"https://www.roblox.com/library/9553550338/\" -- Bad ImageId (Website)\n    Icon = \"http://www.roblox.com/asset/?id=9553550332\" -- Bad ImageId (Decal)\n}\n```\n\nDefaults to `\"❓\"`",
            "lua_type": "string",
            "tags": [
                "Populated"
            ],
            "source": {
                "line": 57,
                "path": "docs_api/macro_definition.lua"
            }
        },
        {
            "name": "IconColor",
            "desc": "Give your Macro icon a pretty color on the Widget! Applies to `TextColor3` or `ImageColor3`, depending on `Icon` input\n\nDefaults to `Color.fromRGB(255, 255, 255)`",
            "lua_type": "Color3",
            "tags": [
                "Populated"
            ],
            "source": {
                "line": 67,
                "path": "docs_api/macro_definition.lua"
            }
        },
        {
            "name": "Group",
            "desc": "The group that the Macro belongs to. Any macros with a matching `Group` value will be grouped together on the Widget\n\nDefaults to `\"No Group\"`",
            "lua_type": "string",
            "tags": [
                "Populated"
            ],
            "source": {
                "line": 77,
                "path": "docs_api/macro_definition.lua"
            }
        },
        {
            "name": "GroupColor",
            "desc": "Give the `Group` text a pretty color on the Widget! If you have multiple Macros under the same `Group`, `GroupColor` need only be defined\non a singular `MacroDefinition`.\n\nDefaults to `Color.fromRGB(255, 255, 255)`",
            "lua_type": "Color3",
            "tags": [
                "Populated"
            ],
            "source": {
                "line": 88,
                "path": "docs_api/macro_definition.lua"
            }
        },
        {
            "name": "GroupIcon",
            "desc": "Defines an icon to put alongside the name of the `Group` the Macro is under. If you have multiple Macros under the same `Group`, `GroupIcon` need only be defined\non a singular `MacroDefinition`\n\nThis can either be `Text` (e.g., Emoji) or an `ImageId`. `ImageIds` are recognised by the string containing `rbxasset`\n\n```lua\n{\n    Icon = \"📂\" -- Good\n    Icon = \"My Icon\" -- Probably too long, but good\n    Icon = \"\" -- Bit boring, but good\n    Icon = \"rbxassetid://9553550332\" -- Good ImageId\n    Icon = \"https://www.roblox.com/library/9553550338/\" -- Bad ImageId (Website)\n    Icon = \"http://www.roblox.com/asset/?id=9553550332\" -- Bad ImageId (Decal)\n}\n```\n\nDefaults to `\"❓\"`",
            "lua_type": "string",
            "tags": [
                "Populated"
            ],
            "source": {
                "line": 112,
                "path": "docs_api/macro_definition.lua"
            }
        },
        {
            "name": "GroupIconColor",
            "desc": "Give your Macro icon a pretty color on the Widget! Applies to `TextColor3` or `ImageColor3`, depending on `Icon` input. If you have multiple Macros under the \nsame `Group`, `GroupIconColor` need only be defined on a singular `MacroDefinition`\n\nDefaults to `Color.fromRGB(255, 255, 255)`",
            "lua_type": "Color3",
            "tags": [
                "Populated"
            ],
            "source": {
                "line": 123,
                "path": "docs_api/macro_definition.lua"
            }
        },
        {
            "name": "Description",
            "desc": "Any and all information pertaining to this specific Macro. This can be as long as you like as it appears in the output.\n\n```lua\n{\n    Description = \"Macro Description Line 1\\nMacro Description Line 2\"\n}\n```\n\nOutput:\n```\n================ Macro Name (Macro Group) | DESCRIPTION ================ \n\nMacro Description Line 1\nMacro Description Line 2\n\n================ Macro Name (Macro Group) | DESCRIPTION ================\n```\n\nDefaults to `\"No Description\"`",
            "lua_type": "string",
            "tags": [
                "Populated"
            ],
            "source": {
                "line": 149,
                "path": "docs_api/macro_definition.lua"
            }
        },
        {
            "name": "LayoutOrder",
            "desc": "Can be used to define the position of where the Macro is rendered on the Widget. Higher numbers are rendered further down the widget. Works very much the same\nas `LayoutOrder` on Roblox Instances.\n\nSee [Settings](/api/SocketSettings#SortType)\n\nDefaults to `0`",
            "lua_type": "number",
            "tags": [
                "Populated"
            ],
            "source": {
                "line": 162,
                "path": "docs_api/macro_definition.lua"
            }
        },
        {
            "name": "EnableAutomaticUndo",
            "desc": "If `true`, will automatically setup `ChangeHistoryService` waypoints before and after running the **Macro's** `Function`. AKA, any changes\nto studio that your Macro makes, you can undo with `Ctrl+Z` or equivalent.\n\nYou can obviously set this to `false` (or don't declare the field) if you want to write your own implementation.\n\n:::tip\nWhen you run \"Undo\" in Studio, it will undo the last change under the `DataModel` (`game`). If, for example, your Macro just prints to the output (and doesn't\nmake any changes to the `DataModel`) it will undo the last change unrelated to your Macro\n:::\n\nDefaults to `false`",
            "lua_type": "boolean",
            "tags": [
                "Populated"
            ],
            "source": {
                "line": 180,
                "path": "docs_api/macro_definition.lua"
            }
        },
        {
            "name": "IgnoreGameProcessedKeybinds",
            "desc": "Socket uses [UserInputService#InputBegan] for detecting keybinds.\n```\ngame:GetService(\"UserInputService\").InputBegan:Connect(function(inputObject, gameProcessedEvent)\n    if gameProcessedEvent and not IgnoreGameProcessedKeybinds then\n        return\n    end\n\n    ...\nend)\n```\n\nDefaults to `false`",
            "lua_type": "boolean",
            "tags": [
                "Populated"
            ],
            "source": {
                "line": 199,
                "path": "docs_api/macro_definition.lua"
            }
        },
        {
            "name": "AutoRun",
            "desc": "If `true`, `macro.Function` will be called when Socket starts. Useful if there is a macro you want to run on startup.\n\nDefaults to `false`",
            "lua_type": "boolean",
            "tags": [
                "Populated"
            ],
            "source": {
                "line": 209,
                "path": "docs_api/macro_definition.lua"
            }
        },
        {
            "name": "IsLocalMacro",
            "desc": "If a macro is a \"Local Macro\", this value will be populated as true.\n\nLocal Macros replicate across different roblox places by being stored under the Socket `plugin`. You can add a Local Macro by placing it under\n```\ngame.ServerStorage.SocketPlugin.LocalMacros[userId] -- Where userId is your own userId\n```\n\n:::tip\nDon't know what your `userId` is? It's the number in the URL of your profile, or you can find it by running the following in the command line:\n```\nprint(game:GetService(\"StudioService\"):GetUserId())\n```\n:::",
            "lua_type": "boolean",
            "tags": [
                "Populated",
                "v1.1.0"
            ],
            "source": {
                "line": 230,
                "path": "docs_api/macro_definition.lua"
            }
        },
        {
            "name": "Keybind",
            "desc": "An array of `Enum.KeyCode` that can trigger the Macro to run.\n```lua\n{\n    Keybind = { Enum.KeyCode.LeftControl, Enum.KeyCode.J }\n}    \n```\n\n:::tip\nWill not work if any of the inputs have `gameProcessedEvent` set to true. See: [UserInputService]\n\nTo disable this, see [TODO]\n:::\n\nDefaults to `{}`",
            "lua_type": "{Enum.KeyCode}",
            "tags": [
                "Populated"
            ],
            "source": {
                "line": 251,
                "path": "docs_api/macro_definition.lua"
            }
        },
        {
            "name": "Fields",
            "desc": "An array of [MacroField], which define the different fields the Macro has. The order they are defined is the order they will appear\non the widget.\n```lua\n{\n    Fields = { \n        {\n            Name = \"Amount\";\n            Type = \"number\";\n            IsRequired = true;\n        },\n        {\n            Name = \"Title\";\n            Type = \"string\";\n        }\n    }\n}    \n```\n\nDefaults to `{}`",
            "lua_type": "{MacroField}",
            "tags": [
                "Populated"
            ],
            "source": {
                "line": 277,
                "path": "docs_api/macro_definition.lua"
            }
        },
        {
            "name": "FieldChanged",
            "desc": "A `BindableEvent` to listen to field values being changed on the UI!\n```\nmacro.FieldChanged.Event:Connect(function(fieldName, fieldValue)\n    print(macro:GetFieldValue(fieldName) == fieldValue)\nend)\n\n-- Output: true\n```\n\nMost cases it will suffice to just read `macro:GetFieldValue(fieldName)` as and when you need a field value. But sometimes you may want to re-run routines\nafter a field value change.",
            "lua_type": "BindableEvent",
            "tags": [
                "Read-Only"
            ],
            "source": {
                "line": 308,
                "path": "docs_api/macro_definition.lua"
            }
        },
        {
            "name": "State",
            "desc": "A persistent `State` of the Macro while the Socket plugin is running. We can write to this inside the `MacroDefinition`, and\nread/write to it in our `Function` and `BindToClose/BindToOpen` functions.\n\nWe can declare default values for fields:\n```lua\n{\n    Fields = {\n        {\n            Name = \"Size\";\n            Type = \"Vector3\";\n        }\n    }\n    State = {\n        FieldValues = {\n            Size = Vector3.new(2, 2, 2); -- Will automatically appear on the Widget\n        }\n    }\n}\n```\n\nWe can also access `IsRunning`:\n```lua\nlocal Heartbeat = game:GetService(\"RunService\").Heartbeat\n\n-- MacroDefinition that, when running, will print the time since the last frame\n{\n    Function = function(macro, plugin)\n        -- Toggle running state\n        macro:ToggleIsRunning()\n    \n        -- Running routine\n        if macro:IsRunning() then\n            -- Add to our RunJanitor\n            -- Automatically gets cleaned up when we toggle IsRunning to false via ToggleIsRunning\n            -- Also gets cleaned up when BindToClose is called\n            macro.RunJanitor:Add(Heartbeat:Connect(function(dt)\n                Logger:MacroInfo(macro, (\"dt: %f\"))\n            end))\n        end\n    end\n}\n```\n\nDefaults to\n```\n{\n    FieldValues = {};\n    IsRunning = false;\n    _Server = {};\n    _Client = {};\n}\n```",
            "lua_type": "MacroState",
            "tags": [
                "Populated"
            ],
            "source": {
                "line": 367,
                "path": "docs_api/macro_definition.lua"
            }
        },
        {
            "name": "RunJanitor",
            "desc": "A [Janitor](https://github.com/howmanysmall/Janitor) object, intended to be used to cleanup tasks after a macro stops running.\n\nIs automatically cleaned up when using `macro:ToggleIsRunning()`, and on `BindToClose`",
            "lua_type": "Janitor",
            "tags": [
                "Read-Only"
            ],
            "source": {
                "line": 377,
                "path": "docs_api/macro_definition.lua"
            }
        },
        {
            "name": "Disabled",
            "desc": "If `true`, this Macro will not be displayed on the Widget. It's `Function` will also not be required, nor registered. This renders `AutoRun` useless\nfor this specific [MacroDefinition](/api/MacroDefinition)\n\n:::tip\nThis can be useful to create a [MacroDefinition](/api/MacroDefinition) solely for defining the aesthetics of a `Group` for organisation purposes.\n\n```lua\n    {\n        Group = \"Fruity Macros\",\n        GroupIcon = \"🍎\",\n        GroupColor = Color3.fromRGB(200, 20, 20),\n        Disabled = true,\n    }\n```\n:::\n\nDefaults to `false`",
            "lua_type": "boolean",
            "tags": [
                "Populated"
            ],
            "source": {
                "line": 485,
                "path": "docs_api/macro_definition.lua"
            }
        }
    ],
    "types": [
        {
            "name": "MacroState",
            "desc": "A table to store a macro's \"State\". Socket writes some stuff here, but feel free to use this for whatever you need. If you overwrite any\nkeys that Socket uses (fields defined here), expect mayhem and tears!",
            "fields": [
                {
                    "name": "FieldValues",
                    "lua_type": "table<MacroField.Name,any>",
                    "desc": "Where we can read the values in our fields from"
                },
                {
                    "name": "IsRunning",
                    "lua_type": "boolean|nil",
                    "desc": "Use this variable to toggle the state of a Macro (updates the UI)"
                },
                {
                    "name": "IsKeybindDisabled",
                    "lua_type": "boolean|nil",
                    "desc": "An internal variable for declaring whether a keybind has been disabled or not"
                },
                {
                    "name": "_Server",
                    "lua_type": "MacroState",
                    "desc": "Socket-only (used for communcicating Server/Client in Accurate Play Solo)"
                },
                {
                    "name": "_Client",
                    "lua_type": "MacroState",
                    "desc": "Socket-only (used for communcicating Server/Client in Accurate Play Solo)"
                }
            ],
            "source": {
                "line": 114,
                "path": "docs_api/sub_definitions.lua"
            }
        }
    ],
    "name": "MacroDefinition",
    "desc": "This is how we define the behaviour of a Macro.\n\nThere are a few `Required` members for a [MacroDefinition] to be valid.\n\nMany fields are `Populated`, where if it is not defined in your [MacroDefinition], will be auto-filled by Socket with a default value.\n\nThere are some `Read-Only` fields, that you'll want to avoid defining in your [MacroDefinition] and let them be `Populated` by Socket.",
    "source": {
        "line": 12,
        "path": "docs_api/macro_definition.lua"
    }
}