How to make a basic admin command system

How to make a simple admin command system.

In this tutorial I will be showing you how to make a basic admin command system using TextChatService.

Getting the right services.

You will need two services for the core of this system, “Players” and “TextChatService”.

local TextChatService = game:GetService("TextChatService")
local Players = game:GetService("Players")

Creating the commands folder.

We will create a folder inside of “TextChatService” to store the commands.

local CommandFolder ="Folder")
CommandFolder.Name = "Commands"
CommandFolder.Parent = TextChatService

Setting the prefix.

You will now have to set the prefix to your commands.

local Prefix = "/" -- Whatever String You Want.

Making the admin list.

A table that includes peoples Usernames or UserIds

--> Admin List
local Admins = { --> UserIds Or Usernames

Finding players from a string.

You will need a function that will find a player from a given string, such as “RO” would find the player “ROBLOX” and “ROBERT”, “me” would find yourself, etc.

local function findPlayerByString(caller, str: string) 
	str = string.lower(str) -- Make Sure The String Is In All Lower Case
	local Targets = {} -- Table Of All The Found Players
	if str == "all" then -- Gets All Players
		Targets = Players:GetPlayers()
	elseif str == "others" then -- Gets All Players Except For The Command Caller.
		Targets = Players:GetPlayers()
		table.remove(Targets, table.find(Targets, caller))
	elseif str == "me" then -- Only Gets The Command Caller
		Targets[1] = caller
	else -- Searches For Players Who Match The Given String.
		for _, player in pairs(Players:GetPlayers()) do
			local Name = string.lower(player.Name)
			if string.sub(Name, 1, string.len(str)) == str then
				table.insert(Targets, player)
	return Targets -- Returns The Found Players

Setting up the command table.

You will need a table that has all your commands in it, including the function, and alias of the command.

local Commands = { 
	["kill"] = { -- Command Name
		Alias = nil, -- Alias Of The Command.
		Func = function(caller, arguments)
			local Targets = findPlayerByString(caller, arguments[1])

			for _, player in pairs(Targets) do
				local Character = player.Character
				Character:FindFirstChild("Humanoid").Health = 0

Creating The TextChatCommand, and detecting when it’s triggered.

You will now have to make a “TextChatCommand” for every command, which is easily done through a loop.

for CommandName, Data in pairs(Commands) do
	local TextChatCommand: TextChatCommand ="TextChatCommand")
	TextChatCommand.PrimaryAlias = tostring(Prefix .. CommandName) -- Sets The Primary Alias

	if Data.Alias ~= nil and type(Data.Alias) == "string" then -- Checks If The Command Has A Alias.
		TextChatCommand.SecondaryAlias = tostring(Prefix .. Data.Alias) -- Sets The SecondaryAlias.

	TextChatCommand.Parent = CommandFolder

	TextChatCommand.Triggered:Connect(function(textSource, UnfilteredText) -- Triggers Whenever The Command Is Ran.
		local Player = Players:GetPlayerByUserId(textSource.UserId) -- Gets The Player Who Called The Command
		--> Check If Player Is A Admin
		local FoundUserId = table.find(Admins, Player.UserId)
		local FoundName = table.find(Admins, Player.Name)
		if FoundUserId == nil and FoundName == nil then --> Dont Run The Command If Player Is Not Admin.
		local Arguments = string.split(UnfilteredText, " ")
		table.remove(Arguments, 1) -- Removes The Command From The Arguments

		Data.Func(Player, Arguments) -- Runs The Command

How to add commands to the system.

It is very simple to add your own commands to the system. Just add a command like this to the “Command” table.

["teleport"] = {
		Alias = "tp",
		Func = function(caller, arguments)
			local Target1 = findPlayerByString(caller, arguments[1])
			local Target2 = findPlayerByString(caller, arguments[2])
			if #Target1 >= 1 and #Target2 >= 1 then
				for _, player in pairs(Target1) do

Open Sourced Place.

Any feedback or comments are appreciated!


Can you provide a demo place or file of the final results?

Other than that is seems like a straightforward tutorial. :+1:

1 Like

I have updated the post with a open sourced place.

1 Like

Underrated tutorial. I’ve been trying to rewrite an admin command framework i made for the LegacyChatSystem to make it work for TextChatService, but kept on getting stuck. This got me in the right direction. Thanks!

1 Like

This is heavily underrated. But I do have a question:

Would anyone be able to help me solve this kick command?

["kick"] = {
		Alias = "remove",
		Func = function(arguments)
			local TargetKick = findPlayerByString(arguments[1])
			TargetKick:Kick("\nYou have been kicked from this server by a moderator.")
1 Like

what do you mean by “solve this kick command”? whats wrong with it?

EDIT: it looks like you forgot to pass in the caller parameter for the first parameter.
should be

		Func = function(caller, arguments)

Thanks for the help so far!

I do not understand what this error means

1 Like

TargetKick is a table so you can use a for loop or get the first element to kick it

@Artzified I’m not the best scripter, what do you mean?

EDIT: This is my kick code right now:

["kick"] = {
		Alias = nil,
		Func = function(caller, arguments)
			local TargetKick = findPlayerByString(caller, arguments[1])
			TargetKick:Kick("\nYou have been kicked from this server by a moderator.")

sorry i was busy, you need to do a for loop in the targetKick because its a list of players (not sure why its an array)

for _, player: Player in TargetKick do
player:Kick("kick message here")
1 Like

Thank you! It works now!!

I’m a bit of a pain some time :person_facepalming:t3:

1 Like