Skip to main content

Argument types

Every entry in Arguments declares a Type. CommandRunner ships fifteen of them. Here's each, in order of how often you'll reach for them.

string

A single-line text field.

Path = {
Type = "string",
Default = "Workspace",
Description = "Dotted path to a service or instance",
PlaceholderText = "e.g. ReplicatedStorage.Modules",
ClearTextOnFocus = false, -- default true
LayoutOrder = 1,
}

A string argument card titled "Path" with the value "Workspace"

  • Storage: string attribute on the ModuleScript.
  • Commit point: FocusLost. The per-arg Run (if defined) fires on commit.
  • Notes: PlaceholderText shows when the value is empty. ClearTextOnFocus = true (the default) wipes the box when the user clicks in. Set false for fields users edit incrementally.

paragraph

Multi-line text, for prose, JSON, or longer commands.

Notes = {
Type = "paragraph",
Default = "",
Description = "Free-form notes",
PlaceholderText = "Write something...",
IsEditable = true, -- default true. false makes it an output-only display.
LayoutOrder = 1,
}

A paragraph argument titled "Notes" with the placeholder "Write something..."

  • Storage: same as string, single string attribute.
  • Layout: stacked label-on-top regardless of widget width (a wide single-line input doesn't fit a multi-line edit story).
  • Output mode: set IsEditable = false and the paragraph becomes a read-only display the command can write to via props:SetLabelText(name, text) from inside Run.

output

A read-only, scrollable multi-line panel meant for streaming output, logs, or progress messages. Same visual as a paragraph but driven through the props:Output(...) / props:AppendOutput(...) helpers, with optional timestamps and severity-colored lines.

Log = {
Type = "output",
Default = "",
Description = "Operation log",
Timestamp = true, -- optional, default true. false = no [HH:MM:SS] prefix on appended lines.
PlaceholderText = "Press Execute to start...",
LayoutOrder = 1,
}

An output argument titled "Log" showing a print line, a yellow [WARN] line, and a red [ERROR] line, all timestamped

  • Storage: string attribute. The plugin appends to the attribute one line at a time.
  • Read-only: the user can't type into it. Only your command can write.
  • Rich text on: lines emitted via :warn(...) and :error(...) are wrapped in <font> tags so they render colored (yellow / red) in the panel.
  • Timestamps: each appended line is prefixed with [HH:MM:SS] by default. Set Timestamp = false on the schema to suppress.

Three ways to write to it from Run:

Run = function(props)
-- 1) The handle API. `Output()` with no name finds the first output arg.
local out = props:Output()
out:print("Starting...")
:warn("Skipped 3 invalid items")
:error("Hard fail on item 12")

-- 2) Targeted writes by output name.
out = props:Output("Log")
out:print("Same as above, but explicit.")

-- 3) Bypass the handle and append directly.
props:AppendOutput("Log", "Another line")
props:ClearOutput("Log") -- wipe the panel
end,

The handle's :print / :warn / :error / :clear methods all return the handle, so calls chain. See the props table for the full Output / AppendOutput / ClearOutput signatures.

Right-click the panel and pick Clear Output to wipe it manually without re-running the command.

number

A numeric field with stepper arrows.

Spacing = {
Type = "number",
Default = 4,
Min = 0, -- optional, inclusive
Max = 100, -- optional, inclusive
Step = 0.5, -- optional, default 1
Description = "Studs between copies",
LayoutOrder = 1,
}

A number argument titled &quot;Spacing&quot; with the value 4 and stepper arrows on the right

  • Storage: number attribute on the ModuleScript. arguments.Spacing is already a number. No tonumber needed.
  • Commit point: FocusLost parses the input. Non-numeric input reverts to the last valid value.
  • Clamping: every commit (typed or arrow-clicked) clamps to [Min, Max] if either is set.
  • Step rounding: arrow clicks add/subtract Step then round to its decimal precision, so 0.1 + 0.2 commits as 0.3, not 0.30000000000000004.

boolean

A simple square toggle. Empty = false, X = true.

Anchor = {
Type = "boolean",
Default = true,
Description = "Anchor each part after the operation",
LayoutOrder = 1,
}

A boolean argument titled &quot;Anchor&quot; with an X in the toggle box (true)

  • Storage: boolean attribute.
  • Commit point: every click. The per-arg Run (if defined) fires immediately.

switch

Same data shape as boolean, different visual: an animated pill toggle with a sliding knob.

DryRun = {
Type = "switch",
Default = false,
Description = "Preview only, don't apply changes",
LayoutOrder = 1,
}

A switch argument titled &quot;DryRun&quot; in the off position — pill-shaped track with the knob on the left

  • Storage: identical to boolean (a boolean attribute). Switches and booleans interoperate; you can change Type from one to the other without losing the saved value.
  • Visual: knob tweens between off/on positions; the track fades between the Studio Button and CheckedFieldBackground theme colors.
  • Use a switch when the toggle is the dominant control on the card. It reads as "on/off setting." Use a boolean when it's a row in a denser checklist.

button

A clickable action. Has no persisted value; click count is passed to the callback.

ResetCounter = {
Type = "button",
Default = "Reset", -- the button's display text
Description = "Zero out the counter",
Run = function(props, clickCount)
props:SetLabelText("Counter", "0")
end,
LayoutOrder = 1,
}

A button argument titled &quot;ResetCounter&quot; rendered as a blue Reset button, with a label above showing 0

  • Storage: none. Buttons hold no state.
  • Run: required for buttons to do anything useful. clickCount is the number of times the button has been clicked since the widget opened.

label

Display-only text. Driven from inside Run via props:SetLabelText.

Status = {
Type = "label",
Default = "Idle",
Description = "Last operation result",
LayoutOrder = 1,
}

A label argument showing the text &quot;Idle&quot; centered with no input field around it

  • Storage: string attribute (same as string), but the user can't edit it directly.
  • Updates: props:SetLabelText("Status", "Done, 12 parts updated") from inside Run or any per-arg callback.
  • Reads: props:GetLabelText("Status").

A picker with a chevron. Options can be primitives, Instance refs, or {Name, Value} tables.

Material = {
Type = "dropdown",
Default = Enum.Material.Plastic, -- the actual VALUE, not an index
Options = {
{ Name = "Plastic", Value = Enum.Material.Plastic },
{ Name = "Wood", Value = Enum.Material.Wood },
{ Name = "Metal", Value = Enum.Material.Metal },
},
AllowCustom = false, -- default true
Description = "Material to apply to the selection",
LayoutOrder = 1,
}

A dropdown argument titled &quot;Material&quot; open, showing Plastic / Wood / Metal options with Wood highlighted

  • Options forms:
    • Primitives: Options = { "X", "Y", "Z" }. The string is both name and value.
    • Instance refs: Options = { workspace.Spawn1, workspace.Spawn2 }. Display uses .Name, value is the Instance.
    • Tables: Options = { { Name = "...", Value = ... } }. Value can be anything (Instance, table, primitive, EnumItem).
  • Storage: a tagged JSON record on the ModuleScript attribute ({i = optionIndex} for an indexed option, {v = primitive} for a typed-in custom value). This is how Values of any type round-trip across the attribute boundary.
  • AllowCustom: defaults true. Lets the user type a value the dropdown didn't list. tonumber is tried first, then string fallback.

instance

A read-only field plus a "use Studio selection" picker button.

Target = {
Type = "instance",
Default = workspace, -- optional Instance seed
Description = "Target instance for the operation",
ShowFullPath = false, -- optional, default false. true = show :GetFullName() instead of .Name
LayoutOrder = 1,
}

An instance argument titled &quot;Target&quot; displaying &quot;Workspace&quot; with a + picker button on the right

  • Storage: a child ObjectValue of the command ModuleScript named __InstanceArg_<argId> (Roblox attributes can't hold Instance).
  • Picker: clicking the button copies Selection:Get()[1] into the field. Empty selection toasts "Select an object first" and leaves the value alone.
  • Default seeding: a Default Instance is written to the ObjectValue on first init.
  • ShowFullPath: by default the textbox shows the captured Instance's .Name (e.g. Spawn1). Set ShowFullPath = true to show the full :GetFullName() path (game.Workspace.Map.Spawn1) — useful when you regularly capture multiple Instances of the same name and need to disambiguate.
  • Clear: right-click the card and pick Clear to drop the captured Instance back to nil. Same item appears for propertyPicker, attributePicker, and colorPicker cards.

color

A Color3 value with a smart-input textbox plus a clickable swatch that opens an HSV color picker popup.

Tint = {
Type = "color",
Default = Color3.fromRGB(255, 122, 0),
Description = "Tint to apply",
LayoutOrder = 1,
}

A color argument titled &quot;Tint&quot; with the hex value #FF7A00 in the textbox and an orange swatch on the right

  • Storage: a single native Color3 attribute on the ModuleScript. arguments.Tint arrives already typed Color3, no conversion needed.
  • Smart textbox: accepts hex (#FF7A00, FF7A00, short #F70), RGB triples (255,122,0, rgb(255, 122, 0)), or BrickColor names (Bright red). Invalid input on FocusLost reverts to the previous value.
  • Picker popup: click the swatch to open a programmatically-built picker. It contains:
    • A saturation/value square — click+drag to set sat/val.
    • A hue slider — rainbow gradient, click+drag to set hue.
    • A hex input — type any hex value and FocusLost to commit.
    • A preset row — White, Black, Red, Orange, Yellow, Green, Cyan, Blue, Purple, Pink. Click to apply.
  • Live commit: every adjustment (textbox, picker drags, hex, preset) writes the new Color3 immediately and fires the per-arg Run callback.

slider

A draggable thumb on a horizontal track for picking a numeric value within a range.

Speed = {
Type = "slider",
Default = 50,
Min = 0,
Max = 100,
Step = 1, -- optional, default 1 (integer snapping)
Description = "Movement speed",
LayoutOrder = 1,
}

A slider argument titled &quot;Speed&quot; with the thumb at the midpoint and the value 50 displayed on the right

  • Storage: number attribute on the ModuleScript (same shape as number). arguments.Speed is already a number.
  • Click + drag: clicking anywhere on the track jumps to that position and starts a drag. Drag-anywhere is supported (cursor can leave the track during drag).
  • Defaults: Step defaults to 1 if not specified, so values snap to integers. Set Step = 0.1 for one decimal, Step = 0.01 for two, etc. Step rounding trims float-precision noise — 0.1 + 0.2 commits as 0.3, not 0.30000000000000004.
  • Clamping: the value is always clamped to [Min, Max]. The thumb position reflects (value - Min) / (Max - Min).
  • Per-arg Run: fires on every value change (clicks, drag updates).

propertyPicker

Like instance, but instead of capturing the selected Instance itself, it captures the value of one of its properties.

Pos = {
Type = "propertyPicker",
Property = "Position", -- the property name to read
Default = Vector3.zero, -- optional
Description = "Position copied from the picked part",
LayoutOrder = 1,
}

A propertyPicker argument titled &quot;Pos&quot; displaying &quot;0, 0, 0&quot; with a + picker button on the right

  • Schema: Property is required. It's a string naming any property on the selected Instance.
  • Click: reads Selection:Get()[1][Property] and stores it. Toasts on errors:
    • "Select an object first" if the Selection is empty.
    • "'<Property>' not found on <ClassName>" if the property doesn't exist on the picked Instance.
    • "Cannot capture <typeof(value)> values" if the property's type isn't storable (see below).
  • Storage:
    • Attribute-supported types (boolean, number, string, BrickColor, Color3, UDim, UDim2, Vector2, Vector3, NumberSequence, ColorSequence, NumberRange, Rect, Font) → stored as an attribute on the ModuleScript.
    • Instance-typed properties (e.g. Adornee, Parent) → stored on a child ObjectValue named __InstanceArg_<argId> (the same side-channel instance uses).
    • Anything else (CFrame, EnumItem, tables, etc.) → rejected with a toast.
  • Auto-gen Luau type: any. The property value can be many types; if you want a tighter shape, override ArgumentResult like the dropdown trick.

attributePicker

Like propertyPicker, but reads an attribute instead of a property.

HP = {
Type = "attributePicker",
Attribute = "Health", -- the attribute name to read
Default = 100, -- optional
Description = "Health captured from the picked instance",
LayoutOrder = 1,
}

An attributePicker argument titled &quot;HP&quot; displaying 100 with a + picker button on the right

  • Schema: Attribute is required.
  • Click: reads Selection:Get()[1]:GetAttribute(Attribute) and stores it.
  • Storage: always attribute-storable (Roblox attributes only allow a fixed set of types), so it always stores cleanly via script:SetAttribute(argId, value).
  • Missing attributes: GetAttribute returns nil for unknown attributes, which is fine — the stored value just becomes nil.
  • Auto-gen Luau type: any.

colorPicker

Same idea as propertyPicker, but specialized for color properties. The card shows a swatch reflecting the captured Color3 (rather than just text).

Tint = {
Type = "colorPicker",
Property = "BackgroundColor3", -- a Color3-typed property name
Default = Color3.new(1, 1, 1),
Description = "Color captured from the picked GuiObject",
LayoutOrder = 1,
}

A colorPicker argument titled &quot;Tint&quot; with the hex value #FFFFFF and a white capture swatch on the right

  • Schema: Property is required.
  • Click: reads Selection:Get()[1][Property]. If the value is a BrickColor, its .Color is used. Anything other than Color3 (or BrickColor) toasts "'<Property>' is not a color".
  • Storage: Color3 attribute on the ModuleScript.
  • Card: the same template as the color arg — a hex display textbox plus a swatch on the right. Unlike color, the textbox here is read-only (the card is purely a display + capture trigger; there's no built-in HSV picker popup). Click the swatch to capture.
  • Auto-gen Luau type: Color3.
  • color vs colorPicker: color is a standalone color value with a built-in HSV picker popup, you set the value yourself. colorPicker captures a color from the selected Instance's named property, no manual picker UI.

LayoutOrder

Every argument supports an optional LayoutOrder (number). Lower numbers render higher in the args panel. Without LayoutOrder, cards lay out in declaration order, but Lua tables don't guarantee that, so set it explicitly when order matters.

How values reach Run

Whatever the user typed/clicked/picked arrives as arguments.<key> (the second positional parameter to Run). The same data is also at props.Arguments.<key>, but loosely typed.

Typearguments.<key>
stringstring
paragraphstring
outputstring (the current accumulated panel contents)
numbernumber
booleanboolean
switchboolean
buttonnot exposed (button has no persisted value)
labelstring
dropdownthe resolved Value from the chosen Option (any)
instanceInstance? (whatever the ObjectValue points at)
colorColor3
slidernumber
propertyPickerany (the captured property's runtime type)
attributePickerany (the captured attribute's runtime type)
colorPickerColor3

For typed access, see auto-generated types.