Problem with Chat tag

Hi developers,

My game has chat tag system. And I want to make VIP chat tag game-pass. If they own game-pass, they will get VIP chat tag. Problem is, I want to give an additional VIP chat tag without deleting the existing chat tag, but I don’t know how to do that.

Thank you in advance!

My chat system:

local players = game:GetService("Players")
local serverScriptService = game:GetService("ServerScriptService")
local chatService = require(serverScriptService:WaitForChild("ChatServiceRunner"):WaitForChild("ChatService"))
local GlobalLeaderboard = game.Workspace:WaitForChild("RebirthGlobalLeaderboard")
local Rebirth_itemsFolder = GlobalLeaderboard:WaitForChild("SurfaceGui"):WaitForChild("Frame"):WaitForChild("Contents"):WaitForChild("Items")


chatService.SpeakerAdded:Connect(function(player)
	while task.wait(5) do
		
		local speaker = chatService:GetSpeaker(player)
		
		if players[player]:IsInGroup(6589440) and players[player]:GetRoleInGroup(6589440) ~= "Fan" then
			if players[player]:GetRoleInGroup(6589440) == "Main Developer" then
			speaker:SetExtraData("Tags", {{TagText = "DEV", TagColor = Color3.fromRGB(255,238,0)}})
			else
				if players[player]:GetRoleInGroup(6589440) == "Influencer" then
					speaker:SetExtraData("Tags", {{TagText = "⭐ YouTuber",  TagColor = Color3.fromRGB(255, 51, 51)}})
				else
					speaker:SetExtraData("Tags", {{TagText = "🛠️" ..  players[player]:GetRoleInGroup(6589440),  TagColor = Color3.fromRGB(255, 149, 232)}})
					end
				end
			else
		
		if Rebirth_itemsFolder:FindFirstChild(players[player].Name) then
			local SpeakerItemFolder = Rebirth_itemsFolder:FindFirstChild(players[player].Name)
			if SpeakerItemFolder.Values.Number.Text == "1" then
					speaker:SetExtraData("Tags", {{TagText = "🏆#1", TagColor = Color3.fromRGB(255, 213, 0)}})
					task.wait()
			else
				if Rebirth_itemsFolder:FindFirstChild(players[player].Name) then
					local SpeakerItemFolder = Rebirth_itemsFolder:FindFirstChild(players[player].Name)
					if SpeakerItemFolder.Values.Number.Text == "2" then
							speaker:SetExtraData("Tags", {{TagText = "🏆#2", TagColor = Color3.fromRGB(212, 212, 212)}})
							task.wait()
					else
						if Rebirth_itemsFolder:FindFirstChild(players[player].Name) then
							local SpeakerItemFolder = Rebirth_itemsFolder:FindFirstChild(players[player].Name)
							if SpeakerItemFolder.Values.Number.Text == "3" then
									speaker:SetExtraData("Tags", {{TagText = "🏆#3", TagColor = Color3.fromRGB(255, 89, 0)}})
									task.wait()
								else
									if Rebirth_itemsFolder:FindFirstChild(players[player].Name) then
										local SpeakerItemFolder = Rebirth_itemsFolder:FindFirstChild(players[player].Name)
										if SpeakerItemFolder.Values.Number.Text ~= "1" or SpeakerItemFolder.Values.Number.Text ~= "2" or SpeakerItemFolder.Values.Number.Text ~= "3" then
											speaker:SetExtraData("Tags", {{TagText = "🌏#" .. SpeakerItemFolder.Values.Number.Text, TagColor = Color3.fromRGB(0, 255, 238)}})
											task.wait()
										else
												speaker:SetExtraData("Tags")
												print("-- rankchat: Player Removed on leaderboard.")
										end
									end
								end		
							end
						end
					end
				end
			end
		end
	end
	task.wait(10)
end)
1 Like

I know this isn’t code review but are you open to switching up your methodology? 1 to 5 requests every 5 seconds per player is a lot of requests (actually it’s less than this because :GetRoleInGroup caches results which still has you creating many unnecessary function calls, you probably want to simulate live-updating chat tags, you can’t get those with Roblox limits unfortunately). Doing a single request when the player joins is much easier to keep track of, ensures you won’t reach any HTTP request limits (the gravity of which increases by the fact you aren’t properly handling any potential HTTP request errors (pcalls)), and finally it makes it much easier to set a player’s chat tags because you aren’t constantly obtaining, modifying and updating a table which you would have to do. You should also use tables to avoid if-elseif statements for each possible case (see spaghetti code). Finally, you have a memory leak because you’re creating a thread that will run until the server shuts down, every time a player joins the game or a speaker is created (which includes rejoining). Also you’re using while wait() do (which is a code smell in and of itself), wait() has been superseded by task.wait(), and you’re using an additional wait() at the end of your script which doesn’t do anything but delay the termination of the thread (which won’t happen anyway because, well, you’re using a while wait() do (essentially a while true do) loop).

-- ideally you would use a module in the case that you want the chat tag info to be used elsewhere and/or to organize the top of your script but it really isn't a big deal for now so we'll use a table.
-- also, you would probably want to use the rank in group instead of the role in group but it really doesn't matter
local groupTags = {
    ['Main Developer'] = {
        TagText = 'DEV';
        TagColor = Color3.fromRGB(255,238,0)
    };
    ['Influencer'] = {
        TagText = '⭐ YouTuber';
        TagColor = Color3.fromRGB(255, 51, 51);
    };
    -- continue for the rest of the group tags
}
-- idk what to call this table lmao
local speakerItemRank = {
    ['1'] = {
        TagText = '🏆#1';
        TagColor = Color3.fromRGB(255, 213, 0)
    } -- continue to 3 or whatever
}

chatService.SpeakerAdded:Connect(function(speakerName)
    local player = players:FindFirstChild(speakerName)
    if not player then -- player doesn't exist
        return
    end
    local speaker = chatService:GetSpeaker(speakerName)
    -- it's very important to wrap http requests in a pcall so in the case it fails, we handle it properly
    local success, role = pcall(player.GetRoleInGroup, player, 6589440)
    local tags = {}
    if success then -- you do not need to call player:IsInGroup to check if the user is actually in the group, you can just check that their role is not "Guest", "role" will be "Guest" when the player isn't in the group. 
        -- also since we're using a table to store group rank info, we don't even have to check that the role is Guest because the table doesn't have a Guest index
        local groupTag = groupTags[role]
        if groupTag then
            table.insert(tags, groupTag)
        end
    else
        warn(role) -- in the case that the pcall fails, 'role' will be equal to the error message
        -- we also do not return because we want to still grant the player the rebirth tag if they have it
    end
    -- note that above we did not set extra data yet. technically you could, but that would be an unnecessary function call so it doesn't matter.
    -- now, let's handle the rebirth items folder thing
    -- okay I have to use a bad practice here since I do not know how you're setting the number tag thing but you should change it to use values or something instead of relying on a string to be equal
    -- just use player.Name or speakerName, not players[player name].Name because that's like going workspace:FindFirstChild(workspace.Part.Name).Name which is another redundant function call, not to mention indexing the name to find another instance from which we index the name
    local speakerItemFolder = Rebirth_itemsFolder:FindFirstChild(speakerName)
    if speakerItemFolder then
        local number = speakerItemFolder.Values.Number.Text -- ideally you would use :FindFirstChild to not error but whatever
        -- we use the or operator in the case that speakerItemRank[number] is nil or false (typically it would be nil)
        table.insert(tags, speakerItemRank[number] or { TagText = "🌏#" .. number; TagColor = Color3.fromRGB(0, 255, 238) })
    end
    -- finally, we set the extra data
    speaker:SetExtraData(tags)
end)

But, if you don’t want to take my approach, which is fine as well, just use speaker:GetExtraData(‘Tags’) and use table.insert on the returned value, then use speaker:SetExtraData(‘Tags’) on that returned table.

1 Like