How to make chat commands using the lua chat system

Introduction
Hello everyone! Today, i’ll be showing you how to make chat commands using the lua chat system! In this tutorial, I’ll be showing you an examples of what you could do using this method. One will be an example! From the research i’ve done, most of them would be using player.chatted. In this tutorial, I’ll show you a better, simpler and easier method! With more functionality than using player.chatted. These functionalities are but not limited to are removing chat messages(preventing people to know who said a command), changing a player’s message and way more!! So lets get right into it!

why you should use this instead of Player.Chatted

* This method is faster than Player.Chatted. Firing shortly after you press enter(little to no delay)

  • More customization, you can delete messages, hiding who said a command, filtering messages like making a player say something else then what they originally said, and much more!
  • cleaner, than having to do localplayer.chatted or playeradded:Connect to get information. All just in 1 script via the server and not client.
    If I missed something or I incorrectly said something then feel free to say below.

Set Up
First, click play. Once you load in, go the chat object in explorer
image
After you do that, click the arrow besides the chat object. Once you do that, you should see something like this:
image

If you do see something like this, select the ChatModules folder. Once you select it, copy it by doing ctrl + c(or cmd + c on mac).

Once you copied the chat modules folder, exit play mode.

After you’ve left play mode, select the chat object in explorer and do ctrl + shift + v. This will paste the chat modules folder into the chat object.

Finally, insert a Module Script into the chat modules folder. Dont insert a normal script/local script. Otherwise this wont work. Next, lets go onto scripting.

Scripting
First, open up the module script you just made. I’ll be writing comments on my code so you can understand

local Command = "/Print" -- our command 
local FunctionId = "PrintCommand"-- this is our function Id we'll be telling our script later on.
local function PrintCommand(Speaker, Message, Channel)-- the speaker is the player's NAME(string) NOT instance.  The message is the message the player typed. The channel is the channel the player typed the message in. Example would be in the team channel or whatever
	
	
end

Keep in mind, the Message argument is NOT filtered . Its the raw message.

Next, lets check if what the player said is our command. As the player could be saying something thats not our command.

local function PrintCommand(Speaker, Message, Channel)-- the speaker is the player's NAME(string) NOT instance.  The message is the message the player typed. The channel is the channel the player typed the message in. Example would be in the team channel or whatever
	if Message:lower() == Command:lower()  then -- the :lower function lowercases our message/command. This is because the player could've typed /pRiNt and it would've not fired. So we do this to make it so it fires no matter the capitals/lower cases.
		print(Speaker .. " said the command!") -- prints the speaker's name and that they said the command
		return true -- this will make the chat remove the message as the player said the command
	else
		 return false -- this will make the message stay in the chat as the player did not say the command
	end 
end

Now, the script doesn’t actually know when to do the command. So we’ll need to make another function to call the print command function.

local function RunChatService(ChatService) -- this function will run our print command every time the player chats.
	ChatService:RegisterProcessCommandsFunction(FunctionId, PrintCommand) -- this will  make our print command function fire any time a player chats.
end
return RunChatService -- returns our runchatservice function so it can be called.

As you can see, anytime you test it, it will run the function whilst removing the chat message. Which is perfect for chat commands!

Now, I want to add a bit more complexity to this function. How about, we allow the chat command to be /print “word here”. I think it’ll be a pretty nice addition. For this we’ll need to re-write our /print function, which shouldn’t be too hard to do.

This may look complex, but as long as you follow along and read my comments then you should be fine.

local function PrintCommand(Speaker, Message, Channel)-- the speaker is the player's NAME(string) NOT instance.  The message is the message the player typed. The channel is the channel the player typed the message in. Example would be in the team channel or whatever
	if string.match(Message:lower(), Command:lower())  then -- checks if the player has /print anywhere in their message.
		local Arguments = string.split(Message, " ") -- this will split strings that have spaces in them. This is perfect for setting up multiple arguments!
		if Arguments  then --checks if arguments is not nil
			local ArgumentCommand = Arguments[1] -- the /print
			local Message = Arguments[2] -- the message we want to print
			print(Speaker .. " printed: " .. Message) -- prints our message
			return true -- this will make the chat remove the message as the player said the command
		else
			return false -- this will make the message stay in the chat as the player did not say the command
		end

		
	else
		 return false -- this will make the message stay in the chat as the player did not say the command
	end 
end

Now, we may almost be done, but theres an issue. If the message includes a space it’ll count it as a separate argument. So we’ll need a way to combine all arguments after 2 to be combined. So lets do this. if you dont understand something then read the comment on that line

local function PrintCommand(Speaker, Message, Channel)-- the speaker is the player's NAME(string) NOT instance.  The message is the message the player typed. The channel is the channel the player typed the message in. Example would be in the team channel or whatever
	if string.match(Message:lower(), Command:lower())  then -- checks if the player has /print anywhere in their message.
		local Arguments = string.split(Message, " ") -- this will split strings that have spaces in them. This is perfect for setting up multiple arguments!
		if Arguments  then --checks if arguments is not nil
			local ArgumentCommand = Arguments[1] -- the /print
			if #Arguments > 2 then -- checks if there are more than 2 arguments
				for ArgumentIndex, ArgumentValue in pairs(Arguments) do -- loops through all our arguments
					if ArgumentIndex > 2 then -- checks if it's current argument is above 2
						Arguments[2] = Arguments[2] .. " " ..  ArgumentValue -- combines the current argument the script is on and combines it with our message argument. Also adds a space between them, otherwise the message argument will be close together with no spaces. 
					end
				end			
			end
			
			local Message = Arguments[2] -- the message we want to print
			if Message then
				print(Speaker .. " printed: " .. Message) -- prints our message
			else
				return false -- this is to not remove the chat message as the player did not say and arguments.
			end
			
			return true -- this will make the chat remove the message as the player said the command
		else
			return false -- this will make the message stay in the chat as the player did not say what to print
		end

		
	else
		 return false -- this will make the message stay in the chat as the player did not say the command
	end 
end

As you can see, as simple as that, here’s an example of it happening:
what i said:
image

What it printed:
image

final code
local Command = "/Print" -- our command 
local FunctionId = "PrintCommand"-- this is our function Id we'll be telling our script later on.
local function PrintCommand(Speaker, Message, Channel)-- the speaker is the player's NAME(string) NOT instance.  The message is the message the player typed. The channel is the channel the player typed the message in. Example would be in the team channel or whatever
	if string.match(Message:lower(), Command:lower())  then -- checks if the player has /print anywhere in their message.
		local Arguments = string.split(Message, " ") -- this will split strings that have spaces in them. This is perfect for setting up multiple arguments!
		if Arguments  then --checks if arguments is not nil
			local ArgumentCommand = Arguments[1] -- the /print
			if #Arguments > 2 then -- checks if there are more than 2 arguments
				for ArgumentIndex, ArgumentValue in pairs(Arguments) do -- loops through all our arguments
					if ArgumentIndex > 2 then -- checks if it's current argument is above 2
						Arguments[2] = Arguments[2] .. " " ..  ArgumentValue -- combines the current argument the script is on and combines it with our message argument. Also adds a space between them, otherwise the message argument will be close together with no spaces. 
					end
				end			
			end
			
			local Message = Arguments[2] -- the message we want to print
			if Message then
				print(Speaker .. " printed: " .. Message) -- prints our message
			else
				return false -- this is to not remove the chat message as the player did not say and arguments.
			end
			
			return true -- this will make the chat remove the message as the player said the command
		else
			return false -- this will make the message stay in the chat as the player did not say what to print
		end

		
	else
		 return false -- this will make the message stay in the chat as the player did not say the command
	end 
end
local function RunChatService(ChatService) -- this function will run our print command every time the player chats.
	ChatService:RegisterProcessCommandsFunction(FunctionId, PrintCommand) -- this will  make our print command function fire any time a player chats.
end
return RunChatService -- returns our runchatservice function so it can be called. 

Well, thats it for the /print command!

Polls
hello! I’d like feedback on the tutorial via polls! So make sure to vote on them!

will you use this?

  • Yes
  • No
  • Maybe
  • THIS TUTORIAL IS TRASH OF COURSE NOT!!!

0 voters

How useful was this to you?

How useful was this?
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

0 voters

was this tutorial useful to you?
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

0 voters

Did you learn anything new?

  • NO
  • YES
  • I DIDNT BAD TUTORIAL

0 voters

Outro
alright, thank you for reading this(or you scrolled all the way down). I hope this helped you and that you learned something new! If you think I did anything wrong, have feedback, or have a question then feel free to say below!

4 Likes

Why is this the proper way? There are millions of admin systems uses .Chatted with no issues, maybe performance?

I don’t consider this proper as that’s what .Chatted was meant for, while this is just forking the chatmodule

Edit: nvm, you said it’s faster, customizable

I get what you mean. But I personally recommend using this system instead of .chatted. As you have more customization and more control. If you still want to use .chatted then go for it. Im just recommending an alternative

okay, ig cool then, would probably be useful

Actually, after doing a test, this method is slightly slower than .chatted. So mistake on my end. So the main point is that is more customizable
about 17 miliseconds, so not that big
image

1 Like

Chatted has existed for all needs of checking what a player sent to chat since before the chat system got ported over to Luau. Using ChatService is the canonical way of interfacing with other parts of the chat while Chatted is the old method of looking at what a player said.

ChatService provides you greater control over a user’s message especially if you’re using classic chat mode which displays the chat window. It’s not about other admin systems using Chatted without issue, most of them were created prior to the Lua Chat System port.

3 Likes

I didn’t actually know most of that! Thanks for the information!