Help integrating this kick command into voice commands

I’ve made a fairly simple voice command system that can do basic tasks like turn on / off audio or change properties in game; I’m now looking to integrate a kick function that still follows the way all the other code is built, as listed below.

I’m not exactly sure where I’ve gone wrong with this but my hope is that my script will be able to filter the message, find the word kick, look at the name I’ve said after kick and then apply that name as the one to kick.

All the other commands run on this same msg:match system so I suspect the issue lies in me incorrectly trying to identify the string after the command.

players = game:GetService("Players")

function onChatted(msg, recipient, speaker)

	local source = string.lower(speaker.Name) 
	msg = string.lower(msg)

	if msg:match("kick") then
		local target = msg + 1
		local kicked = players:FindFirstChild(target)
		kicked:Kick("Bye")
	end
end

function onPlayerEntered(newPlayer) 
	newPlayer.Chatted:connect(function(msg, recipient) onChatted(msg, recipient, newPlayer) end) 
end 

game.Players.ChildAdded:connect(onPlayerEntered) 

Thanks in advance for any feedback!

2 Likes

There are a few issues I’d like to address while explaining this, but it’ll also be a bit of a string manipulation lesson for you as well.

You currently have an event that checks whenever someone talks. That parts mostly good, however within the

line, there are a few issues. Firstly, :Connect() Should be a capital (it’s case sensitive), and secondly you’re creating a function to the put your already made function inside of it. This can be avoided by just doing this:

newPlayer.Chatted:Connect(onChatted, player)

If that doesn’t work, you’ll have to re-arrange where the player argument is, I haven’t got the chance to test it in studio. In addition, I’ve removed the recipient since it’s a deprecated value.

Now, we’ve got the event working and set up, but at the moment we’ve just got 2 values, with them being:
1 - A raw string (the message)
2 - The player (object)

I’m going to assume that you don’t have a prefix, as you would have had it within the code if so. However, from what I see you doing, you’re making the msg lowerCase, and then checking if it says kick.

Making the message lowercase is good, however then you just check if the message has kick within it. There are a few things wrong with this approach, being that if the message was “I want to kick something” it would fire the if statement. So, instead of this, I’m going to show you a better way, and one which helps you get all the words from a message.

Now, a very useful and helpful method we can use on strings is called :Split(). The split function will get just the words from a string, and remember that the message is a string, and it will return all of the messages in a table. The way you’d use it is as follows:

local arguments = msg:Split(" ")

Now, notice that I put " " within the parenthesis. I did this because that’s setting the separator as a space. This is the default, however it means it’s easier to change. Lets say, for example, your messages looked-a-little-something-like-this. There was a dash between those words, not a space. To make it so the Split method would work, we’d simply replace " " to “-”.

Now, we have our arguments stored in a table. But how do we access them? Well, we’ll have to index them. Lets say for the rest of this response the message is Kick BillyB. When we use the split function on the message, it’ll respond a table that looks like this:

{“kick”, “billyb”}

Don’t forget that it’s all lower case, as we’ve used the string.lower() function previously. Now, to get the command, i.e. the “kick”, we’ll have to know about indexing. An index is the position of where something is within objects, tables, etc. This is a number, and shouldn’t be confused with dictionaries. Every index position starts at 1, so for the table, “kick” would have an index of 1, “billyb” would have an index of 2, and anything that we add to the table after it would continue this, so 3, 4, 5, etc.

Now, let’s store the command as a variable, so we can use it for the if statement in a minute. We’ll do the same for the subject, i.e. the person getting kicked.

local command = arguments[1] -- arguments is from earlier on
local subject = arguments[2]

Okay, now lets move on to the if statement. So far, we’ve got the command and subject, so now it should just be a matter of changing the if statement to see if the command variable is equal to kick. Now, let’s say it is, we can get rid of that target variable as we already have the subject, and can instead put that into the kicked variable.

Now, overall, the fixed version should look something like this:

players = game:GetService("Players")

function onChatted(msg, recipient, speaker)

	msg = string.lower(msg)
    local arguments = msg:Split(" ")
    local command = arguments[1]
    local subject = arguments[2]

	if command == "kick" then
		local kicked = players:FindFirstChild(subject)
		kicked:Kick("Bye")
	end
end

function onPlayerEntered(newPlayer) 
	newPlayer.Chatted:connect(onChatted) 
end 

game.Players.ChildAdded:connect(onPlayerEntered) 

Obviously, there are lots of areas to improve on, and things that may need to be changed as I haven’t tested this, but I believe this should work.

3 Likes

Thanks for helping out - testing this method, it doesn’t seem to be able to recognise any messages now as the arguments aren’t recognised.

A big part of why I was hoping to keep it written my initial way is because there’s already another thirty or so commands correctly operating on the same system of

if msg:match("example") then

or

if (msg == "example") then

I suspect I phrased my query wrong but what I’m truly looking to do is accomplish getting the word I say after “kick” and having the kicked value become that word, without changing my surrounding code.

The rewrite was incredibly helpful regardless as I was able to see a much more efficient way of doing things when I go back and rework everything.

2 Likes

Still looking to find a way to make this work - if it’s even possible with my method.

1 Like