String:match() not working

Hello, dev forum. Today I was trying to create an AI bot, which replies when a correct class has been found. At the current state, I’ve not come far as I’m not able to get it to return a number (in the last line of the server script)

Server Script:

game:GetService("ReplicatedStorage"):WaitForChild("AIADDON"):WaitForChild("Main").OnServerEvent:Connect(function(plr, event, value1)
	if game:GetService("Players"):FindFirstChild(plr.Name) then
		
		if event == "disablePrompt" then
			value1.Enabled = false
		elseif event == "enablePrompt" then
			value1.Enabled = true
		elseif event == "message" then
			--value1.CurrentUser = plr.Name
			plr.Chatted:Connect(function(msg)
					
				local msgLower = string.lower(msg)
				
				local classes = config.ClassTable
				local sClass = ""

				local function hasClass(s)
					for _, class in ipairs(classes) do
						if (s:match(class, 1, true)) then
							sClass = class
						end
					end
					return false
				end
				hasClass(msgLower)
				
				local moduleName = 0
				for k = 1,config.Classes do
					if sClass:find(config["Class"..k.."Name"], 1, true) then
						moduleName = k
					end
				end
				
				print(moduleName)
					
				
			end)
		end
		
	end
end)

Local Script:

ProximityPromptService.PromptTriggered:Connect(function(object, player)
	if object.Name == "AIPrompt" then
		for i,v in pairs(game.Workspace:GetDescendants()) do
			if v.Name == "AIPrompt" then
				v.Enabled = false
			end
		end
		game:WaitForChild("ReplicatedStorage"):WaitForChild("AIADDON"):WaitForChild("Main"):FireServer("disablePrompt", object)
		game:WaitForChild("ReplicatedStorage"):WaitForChild("AIADDON"):WaitForChild("Main"):FireServer("message", object)
	end
end)

Config Script:

local mci = {}

mci.GroupId = 0
mci.StaffRank = 0 -- Lowest Rank in the (GroupId) allowed to use the system, anything above will be able to use it aswell.

mci.NameTag = true
mci.NameTagMaxDistance = 100

mci.Classes = 4 -- How many classes you use. Max: 10

mci.Class1Name = "Economy Class" -- Name must match with what the tool located in Server Storage folder is called.
mci.Class1Rank = 0 -- The lowest rank allowed to check-in with the class without owning the class, if you don't want this keep it at 0.
mci.Class1Id = 0 -- Shirt people buy to be able to check-in with the class. If it's free keep it at 0
-- Rank does not work if you don't have a shirt to sell.

mci.Class2Name = "Business Class" -- Name must match with what the tool located in Server Storage folder is called.
mci.Class2Rank = 0 -- The lowest rank allowed to check-in with the class without owning the class, if you don't want this keep it at 0.
mci.Class2Id = 0 -- Shirt people buy to be able to check-in with the class.
-- Rank does not work if you don't have a shirt to sell.

mci.Class3Name = "First Class" -- Name must match with what the tool located in Server Storage folder is called.
mci.Class3Rank = 0 -- The lowest rank allowed to check-in with the class without owning the class, if you don't want this keep it at 0.
mci.Class3Id = 0 -- Shirt people buy to be able to check-in with the class.
-- Rank does not work if you don't have a shirt to sell.

mci.Class4Name = "Investor" -- Name must match with what the tool located in Server Storage folder is called.
mci.Class4Rank = 0 -- The lowest rank allowed to check-in with the class without owning the class, if you don't want this keep it at 0.
mci.Class4Id = 0 -- Shirt people buy to be able to check-in with the class.
-- Rank does not work if you don't have a shirt to sell.


-- THE SETTINGS BELLOW IS ONLY USED BY THE MANUAL CHECK IN AI ADD-ON

mci.FirstMessage = "Hello! Welcome to AeroSys Airlines! What class shall I check you in with today?" -- After activating the prompt // Second message will be where the player selects class
mci.UserDoesntOwnClassMessage = "Oops! Sorry you do not own this class. What other class would you like?"
mci.SecondMessage = "Excellent Choice!"
mci.AiFont = Enum.Font.FredokaOne -- Font


mci.ProximityPromptKeycode = Enum.KeyCode.E -- Change the E to an available keycode if you wish to change it.
mci.ProximityPromptGamepadKeycode = Enum.KeyCode.ButtonX -- This is exclusively for consoles, if your game allows consoles to play it.
mci.ProximityPromptRequiresLineOfSight = false -- Set to true if the player needs to see it, this may be buggy if set to true because of physics.

mci.ClassTable = { -- This one is a bit tricky. So for every class you have, add it like the current ones are added. With a comma to separate.
	-- If your class is named for example "Economy Class" and you know people in your game will make typo's. Just duplicate the same thing
	-- And add it as "Economy" aswell, you can do this for all the classes with multiple words. 
	-- The reward for doing this is making it easier for the AI to understand the message the player is sending.
	string.lower("Economy Class"), string.lower("Economy"),
	string.lower("Business Class"), string.lower("Business"),
	string.lower("First Class"), string.lower("First"),
	string.lower("Investor")
}

return mci

The last line in Server Script is returning 0 so it’s not changing the value. I’m not having any errors. But this probably means the second function is not passing the match. Any help is appreciated! Thank you!

1 Like

probably means the second function is not passing the match.

You should confirm this on your end by printing the results.

if (s:match(class, 1, true)) then

string.match doesn’t require a fourth argument.
https://developer.roblox.com/en-us/api-reference/lua-docs/string

Passing extra arguments doesn’t make any difference.

You are using match with a string (I think) and a number.

Passing extra arguments doesn’t make any difference.

It harms readability and may cause confusion down the line. It also upsets Roblox’s IDE’s linter.

You are using match with a string (I think) and a number.

They’ve called ‘match’ with a colon operator (as a method) meaning that the string value (object) ‘match’ is called through/on is being passed as the first argument to the method. ‘1’ is being passed as the method’s third argument (start position argument), this is unnecessary however as string.match's third parameter already defaults to 1.

Well you see, having extra arguments isn’t harmful in a way or another, if the function takes 3 arguments and you gave 4, it will have absolutely no difference on the way it runs / behaves

You shouldn’t pass a function more arguments than it expects for the sake of readability, irrespective of if or not the function operates identically.

1 Like