If you try to display a chat message to the user as soon as they join the experience, the message does not display because the chat window has not appeared soon enough.
Consider this clientside code, which is supposed to display “Testing 123” to the chat window:
local textChatService = game:GetService("TextChatService")
local textChannels = textChatService:WaitForChild("TextChannels")
local defaultChannel = textChannels:WaitForChild("RBXGeneral")
defaultChannel:DisplaySystemMessage("Testing 123")
The chat works, but the above code had no effect because the window wasn’t loaded in time:
Doing this trick doesn’t fix it either:
There doesn’t seem to be a “window loaded” event on any of the relevant Creator pages:
Using WaitForChild
on the ChatWindowConfiguration
instance doesn’t work, and neither does disabling it in Studio followed by re-enabling it through the script like so:
local Config = textChatService:WaitForChild("ChatWindowConfiguration")
Config.Enabled = true
defaultChannel:DisplaySystemMessage("Testing 123")
It was worth a shot
The only option I know of that remains is artificial yielding:
task.wait(1)
defaultChannel:DisplaySystemMessage("Testing 123")
Finally, it works!
But task.wait
is icky. Without a clear signal that lets the program know when the chat window has loaded, developers are stuck with a race condition where the safest thing to do is wait a few seconds before running any chat window-related code.
It would be nice if a “Chat Window Loaded” event existed to yield for, since there are many cases where the developer may want to display system messages in the chat as soon as a user joins the experience.
Some method to check the loaded condition, like a “Chat Window Has Loaded()” would be a good precondition as well.
This condition/yield duality has its place in the aforementioned “game:IsLoaded()? no? then game.Loaded:Wait()” check as well, which I’ve seen used commonly.
Edit 2024-02-16T22:39:00Z:
The Legacy Chat System does not have this same problem.
With TextChatService.ChatVersion
set to LegacyChatService
, the following clientside code displays a system chat message without needing a task.wait
at the top:
local msgText = "This is a system message"
game:GetService("StarterGui"):SetCore("ChatMakeSystemMessage", {Text = msgText})
Related:
Repro: send chat on join.rbxm (1.6 KB)
-
Place the folder in
game.ReplicatedStorage
. -
Ensure
game.TextChatService.ChatVersion
is set toTextChatService
. -
When testing any of the scripts, ensure only one is enabled at a time.
-
Ensure
game.Players.CharacterAutoLoads
is disabled for this test just in case it slows down the loading time. -
If the Artificial Yield script doesn’t work, just increase the yielding time. Try
task.wait(5)
, for example.