I am attempting to mess with the ChatService module so I can change the tag color of players in chat, however, while calling :GetSpeaker(), it returns nil and continues to do so forever as shown it being done in the repeat loop that will never end. How do I fix it?
local ChatService
game.Players.PlayerAdded:Connect(function(player)
if not ChatService then
ChatService = require(game:GetService("ServerScriptService"):WaitForChild("ChatServiceRunner").ChatService)
end
local speaker = ChatService:GetSpeaker(player.Name) -- site of error
repeat
wait() -- never ends
until speaker
wait(5)
speaker:SetExtraData("ChatColor", Color3.fromHSV(100, 1, 1))
end)
I don’t know much about the chat module itself, but here’s what I can tell you from the logic:
The repeat wait() until speaker
loop will never end because the variable speaker is only set once before it, thus the condition the loop is waiting for will not be met. If you want it to change, you’ll have to also be trying to find speaker in the loop itself. A simple change would look like this:
local speaker = ChatService:GetSpeaker(player.Name)
if not speaker then
repeat
wait()
speaker = ChatService:GetSpeaker(player.Name)
until speaker
end
3 Likes
Thank you, I never thought about it and now I’ll be able to solve a lot of more looping problems in the future now because of that logic I haven’t thought of.
1 Like
Do NOT use loops here. Loops where unnecessary are evil. Use the proper events here as well: do not use PlayerAdded when trying to work with new speakers, use SpeakerAdded of ChatService. The Lua Chat System is an independent system with its own API so it makes sense to check when a speaker is added by the ChatService rather than the Players service which doesn’t weigh in on the former.
If you’re worried about not having access to the player, ChatSpeaker objects have a method of retrieving the player associated with a ChatSpeaker, GetPlayer. You can use this if you need a reference to the player at any point. Judging by your code though, doesn’t seem that way.
local ServerScriptService = game:GetService("ServerScriptService")
local ChatService = require(ServerScriptService:WaitForChild("ChatServiceRunner").ChatService)
local function speakerAdded(speakerName)
local speaker = ChatService:GetSpeaker(speakerName)
-- local player = speaker:GetPlayer()
speaker:SetExtraData("ChatColor", Color3.fromHSV(100, 1, 1))
end
ChatService.SpeakerAdded:Connect(speakerAdded)
for _, speaker in ipairs(ChatService:GetSpeakerList()) do
speakerAdded(speaker)
end
6 Likes
Is there a :Wait()
and :Disconnect()
method for SpeakerAdded event?
SpeakerAdded is implemented as the .Event of a BindableEvent server-side which behaves like a standard signal. Wait is implemented for it, disconnect isn’t because disconnect is a method of RBXScriptConnections (different from an RBXScriptSignal). Any and all connections have disconnect methods, that’s a separate object class altogether.
1 Like
Forgot about that, thanks for the important information.