Formatting a string but only with one table?

I have a command system in my game, which sends local outputs for whenever a player runs a command. (example being if the player runs /kick then they receive a local system message in chat that says “kicked ”)

However the way this does it is it has a dictionary of values for the respective commands in a table, which means it gets a nil value, and causes an error.

RS.Command.OnClientEvent:Connect(function(cRemote)
	local things = {
		["tpto"] = "Teleported to "..cRemote[3];
		["tp"] = "Teleported "..cRemote[3].." to "..cRemote[4];
		["kick"] = "Kicked "..cRemote[3].." for reason: "..cRemote[4];
		["KickNoArgs"] = "argument blank: Did you forget to type their username?\n/kick <username> <reason>";
		["TpNoArgs"] = "argument blank: Did you forget to type their username?\n/tp <username> <optional:username>";
	}
	local chatc = nil
	if cRemote == "c" then
		chatc = Color3.fromRGB(255,140,0)
	elseif cRemote == "d" then
		Color3.fromRGB(255,0,0)
	else
		Color3.fromRGB(255,255,255)
	end
	game.StarterGui:SetCore("ChatMakeSystemMessage", {Text = things[cRemote[1]], Color = chatc, Font = Enum.Font.Arial, FontSize = Enum.FontSize.Size24})
end)

Is there a way I can replace the string concatenation with %s for formatting without having to use individual variables like this?

local stringValue = "What is %s my %s"
local stuff = {"up", "Gs"}
string.format(stringValue, stuff[1], stuff[2])

and instead only having 2 arguments in string.format

Reason being the amount of indexes in the table changes a lot for different use scenarios, and I don’t want to have a bunch of elseif statements

string.format(stringValue, unpack(stuff))

3 Likes
Don't read, not a solution.

I would personally use string interpolation instead of string.format
Strings | Documentation - Roblox Creator Hub

local text1 = "up"
local text2 = "Gs"

local newString = `What is {text1} my {text2}`

Uhhh no. String interpolation is more oriented towards constants. You have to manually fill out all the variables to be interpolated, which is the opposite of what the OP wants to do. More importantly, it is not dynamic! You cannot reuse the interpolation format because the string is created at runtime

1 Like

I did not read OP’s post clearly because I’m kinda tired. I apologize to the OP if I caused any confusion. I now realize what OP was trying to achieve. My method wouldn’t be dynamic at all. So yeah uh, goodnight I guess.

uh oh, error!
image

what I think is going on is that since I’m trying to get the strings from indexes 3 and up if there’s only 1 index being unpacked it doesn’t really count as a table?

local finalString = string.format(things[cRemote[1]], unpack(cRemote, 3, #cRemote))

I want to have all indexes 3 and up because 1 is what command was used and 2 is whether the message is red or orange
I’m not sure how I’m supposed to go around this still

Try using this.

local stringValue = "What is %s my %s"
local stuff = {"up", "Gs"}
if type(stuff) == "table" then
    string.format(stringValue, unpack(stuff))
else
    print("Error: Invalid argument #1 to unpack (table expected, got "..type(stuff)..")")
end

This can fix the problem or help debug.

The error message literally tells you that the first parameter of unpack() is a string instead of a table. cRemote is not the correct type, I would double check the code.

The issue is, this is the line for the remoteEvent;

RS.Command:FireClient(plr, "KickNoArgs", "d")

It clearly is a table
Why when I print type() on cRemote it displays as a string?

edit: i realized it was because I forgot to make it a table i just kept putting commas

You can still use it like that! Use Ellipsis ... to represent a tuple of values. You won’t need to use a table anymore like this.

--this is an example
RS.Command.OnClientEvent:Connect(function(msg, ...)
	string.format(things[msg], ...)
end)
1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.