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,
}
- Storage: string attribute on the ModuleScript.
- Commit point:
FocusLost. The per-argRun(if defined) fires on commit. - Notes:
PlaceholderTextshows when the value is empty.ClearTextOnFocus = true(the default) wipes the box when the user clicks in. Setfalsefor 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,
}
- 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 = falseand the paragraph becomes a read-only display the command can write to viaprops:SetLabelText(name, text)from insideRun.
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,
}
- 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. SetTimestamp = falseon 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,
}
- Storage: number attribute on the ModuleScript.
arguments.Spacingis already anumber. Notonumberneeded. - Commit point:
FocusLostparses 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
Stepthen round to its decimal precision, so0.1 + 0.2commits as0.3, not0.30000000000000004.
boolean
A simple square toggle. Empty = false, X = true.
Anchor = {
Type = "boolean",
Default = true,
Description = "Anchor each part after the operation",
LayoutOrder = 1,
}
- 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,
}
- Storage: identical to
boolean(a boolean attribute). Switches and booleans interoperate; you can changeTypefrom one to the other without losing the saved value. - Visual: knob tweens between off/on positions; the track fades between the Studio
ButtonandCheckedFieldBackgroundtheme colors. - Use a switch when the toggle is the dominant control on the card. It reads as "on/off setting." Use a
booleanwhen 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,
}
- Storage: none. Buttons hold no state.
Run: required for buttons to do anything useful.clickCountis 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,
}
- Storage: string attribute (same as
string), but the user can't edit it directly. - Updates:
props:SetLabelText("Status", "Done, 12 parts updated")from insideRunor any per-arg callback. - Reads:
props:GetLabelText("Status").
dropdown
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,
}
- 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).
- Primitives:
- 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 howValues of any type round-trip across the attribute boundary. AllowCustom: defaultstrue. Lets the user type a value the dropdown didn't list.tonumberis 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,
}
- Storage: a child
ObjectValueof the command ModuleScript named__InstanceArg_<argId>(Roblox attributes can't holdInstance). - 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
DefaultInstance is written to the ObjectValue on first init. ShowFullPath: by default the textbox shows the captured Instance's.Name(e.g.Spawn1). SetShowFullPath = trueto 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 forpropertyPicker,attributePicker, andcolorPickercards.
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,
}
- Storage: a single native
Color3attribute on the ModuleScript.arguments.Tintarrives already typedColor3, 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 onFocusLostreverts 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
FocusLostto 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
Color3immediately and fires the per-argRuncallback.
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,
}
- Storage: number attribute on the ModuleScript (same shape as
number).arguments.Speedis already anumber. - 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:
Stepdefaults to1if not specified, so values snap to integers. SetStep = 0.1for one decimal,Step = 0.01for two, etc. Step rounding trims float-precision noise —0.1 + 0.2commits as0.3, not0.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,
}
- Schema:
Propertyis 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 childObjectValuenamed__InstanceArg_<argId>(the same side-channelinstanceuses).- Anything else (
CFrame,EnumItem, tables, etc.) → rejected with a toast.
- Attribute-supported types (
- Auto-gen Luau type:
any. The property value can be many types; if you want a tighter shape, overrideArgumentResultlike 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,
}
- Schema:
Attributeis 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:
GetAttributereturnsnilfor unknown attributes, which is fine — the stored value just becomesnil. - 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,
}
- Schema:
Propertyis required. - Click: reads
Selection:Get()[1][Property]. If the value is aBrickColor, its.Coloris used. Anything other thanColor3(orBrickColor) toasts"'<Property>' is not a color". - Storage:
Color3attribute on the ModuleScript. - Card: the same template as the
colorarg — a hex display textbox plus a swatch on the right. Unlikecolor, 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. colorvscolorPicker:coloris a standalone color value with a built-in HSV picker popup, you set the value yourself.colorPickercaptures 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.
| Type | arguments.<key> |
|---|---|
string | string |
paragraph | string |
output | string (the current accumulated panel contents) |
number | number |
boolean | boolean |
switch | boolean |
button | not exposed (button has no persisted value) |
label | string |
dropdown | the resolved Value from the chosen Option (any) |
instance | Instance? (whatever the ObjectValue points at) |
color | Color3 |
slider | number |
propertyPicker | any (the captured property's runtime type) |
attributePicker | any (the captured attribute's runtime type) |
colorPicker | Color3 |
For typed access, see auto-generated types.