Hello everyone! Recently, I’ve been attempting to implement chat tags into my game.
However, ChatService:GetSpeaker(player.Name) always returns nil and I don’t understand why that’s happening. I’m using the standard chat system. Nothing has been modified. And it has been ran on studio, in case that changes anything.
Here’s the script I’m using to give tags to the players:
local Players = game:GetService('Players')
local Chat = game:GetService('Chat')
local ChatService = require(Chat:WaitForChild('ChatServiceRunner'):WaitForChild('ChatService'))
Players.PlayerAdded:connect(function(player)
local PlayerPermissions = _G.PermissionsTable[player.UserId]
print(PlayerPermissions)
if PlayerPermissions == nil or PlayerPermissions > 6 or PlayerPermissions < 0 then
PlayerPermissions = 0
_G.PermissionsTable[player.UserId] = 0
end
local speaker
local MaxTries = 5
local Tries = 0
while not speaker do
if Tries < MaxTries then
print("Infinite loop here")
speaker = ChatService:GetSpeaker(player.Name)
wait()
Tries = Tries + 1
else
break
end
end
if speaker.PlayerPermissions > 0 then
speaker:JoinChannel("Staff")
end
if speaker.PlayerPermissions > 3 then
speaker:JoinChannel("Developer")
end
speaker:SetExtraData("Tags", {{ TagText = SpecialTagTable[PlayerPermissions][1], TagColor = SpecialTagTable[PlayerPermissions][2] }})
speaker:SetExtraData("NameColor", SpecialTagTable[PlayerPermissions][2])
end)
Yes, I do know that another post was made about the same behavior. However, it appeared to be caused by a different issue.
This is happening because you’re referencing the ChatService under the Chat service. This is only a holding container for the Chat scripts and is static (scripts don’t run). The proper way to get the ChatService is through ServerScriptService.
If you’re interested in doing this a better way as well, you should look into using the actual ChatService events. That means you should be using SpeakerAdded instead of PlayerAdded. Getting the associated player is a valid method of the ChatSpeaker class so work in terms of the speaker. This will also, in turn, get rid of the need to use weird guards in your code such as the retry fetch system.
local ChatService = require(game:GetService("ServerScriptService"):WaitForChild("ChatServiceRunner").ChatService)
local function speakerAdded(speakerName)
local speaker = ChatService:GetSpeaker(speakerName)
local player = speaker:GetPlayer()
if not player then return end
-- Ew, _G. Use a ModuleScript or ExtraData instead. Or attributes when they're here.
local playerPermissions = _G.PermissionsTable[player.UserId]
if not playerPermissions or playerPermissions > 6 or playerPermissions < 0 then
playerPermissions = 0
_G.PermissionsTable[player.UserId] = 0
end
-- Can't use speaker.PlayerPermissions without setting it
-- Might as well use the variable since you have it as well
if playerPermissions > 0 then
speaker:JoinChannel("Staff")
end
if playerPermissions > 3 then
speaker:JoinChannel("Developer")
end
-- Do your tag setting here; pretty sure you have some variable shadowing going on
end
ChatService.SpeakerAdded:Connect(speakerAdded)
for _, speaker in ipairs(ChatService:GetSpeakerList()) do
speakerAdded(speaker)
end