Skip to main content

Custom Commands

note

Kohl's Admin is currently in development. Everything in these docs is subject to change.

Custom commands are a powerful feature that lets you personalize Kohl's Admin, automate tasks, streamline your workflows, and create unique interactions within your experience.

Prerequisites

  • Make sure you have Kohl's Admin: Ensure that Kohl's Admin is present in your experience.
  • Addons Folder: Confirm that Kohl's Admin has a folder named Addons. This is where you'll place your custom command scripts.

Addon Setup

All custom commands are part of an Addon. For this section we will create addons that only create custom commands, but in later parts we will show the extent of what addons can do.

All addons are a ModuleScript that returns a function. To start, create a module script and inside of it write the following:

return function(_K)
-- Addon code goes here!
end

Inside of this function is where we will be adding our custom commands. The name of the addon can be anything, but for this example we encourage "customCommands".

danger

Adding Client or Server an Addon file's name will make it only run in that context. This will make the other context unaware of the command!

Creating a Custom Command

To create a custom command, you must register it with the Registry, using registerCommand().

Using this, our module becomes:

return function(_K)
_K.Registry.registerCommand(_K, commandDefinition)
end

commandDefinition is a placeholder for the real contents of our command! Commands require a lot of information, structured in a commandDefinition.

type commandDefinition {
name: string, -- Name of the command.
aliases: { string }?, -- Table of aliases.
description: string, -- Description of what the command does.
group: string, -- What group the command belongs to.
args: { ArgumentDefinition }, -- A table of argument definitions.
envClient: {} | () -> {}?, -- Sets up an environment for the command.
env: {} | () -> {}?, -- Sets up an environment for the command.
runClient: (...any) -> ()?, -- What runs on the client of the player that ran the command.
run: (...any) -> ()? -- What the command runs on the server.
}

To give an example, this is the code from the ExampleAddon:

-- addons not containing in "Client" or "Server" will run in both contexts (shared)
return function(_K)
_K.log(`Hello World from ExampleAddon!`, "INFO")

_K.Registry.registerCommand(_K, {
name = "customcommand",
aliases = { "customcommandalias", "customcommandalias2" },
description = "Custom command description.",

-- The command group to sort the command by, this is what roles use to easily assign groups of commands.
-- Default groups in order of abusability are "Utility", "Environment", "General", "Fun", "Moderation", "Administration", and "Creator"
group = "General", -- Command group to use.

-- Argument definitions
args = {
{
type = "stringGreedy",
name = "Message",
description = "The message to send.", -- Description shown in command listings.
-- If the command is optional, make sure to check if it's nil and not false!
optional = true,

lowerRank = false,
ignoreSelf = false,
shouldRequest = false,
},
},

-- Command environment

env = function(_K)
-- This will only run once on each server
_K.log(`Hello World from ExampleAddon customcommand env!`, "INFO")

-- This table is passed to the `run` function as `context.env`
return {
countServer = 0,
}
end,

envClient = function(_K)
-- This will only run once on each client
_K.log(`Hello World from ExampleAddon customcommand envClient!`, "INFO")

-- This table is passed to the `runClient` function as `context.env`
return {
countClient = 0,
}
end,

-- Command execution

-- Function that runs on the server
run = function(context, message: string?)
print("Custom command ran on server!", context, message)

-- Create a simple Roblox message object
local messageInstance = Instance.new("Message", workspace)

-- Since our message is optional we need to check for context.OPTIONAL
messageInstance.Text = if message == context.OPTIONAL then "Default message" else message

-- This will destroy the message after 5 seconds
task.delay(5, messageInstance.Destroy, messageInstance)

-- Number of times the command has been used on this server
context.env.countServer += 1
end,

-- Function that runs on the player's client
runClient = function(context, message)
print("Custom command ran on the client!", context, message)

-- Number of times the command has been used on this client
context.env.countClient += 1
end,
})
end

This command creates a Message instance and populates it with the player provided message. As you can see, the command is registered with a dictionary that lists all information about the command.

tip

You can put multiple custom commands in one addon! All you need to do is register multiple commands in the same module.

In later sections, we'll cover more advanced uses of custom commands, including environments and other advanced functionality.