I was converting my game’s chat system to the new TextChatService and struggling to figure out how to customize system messages.
For some indiscernible reason the ChatMakeSystemMessage
SetCore isn’t supported by the new chat, meaning my existing flow for sending system messages was broken.
To keep the same functionality as before, I had to write a new wrapper function. The process was painful so I thought I would share here to save other people the suffering.
How to send system messages before:
game.StarterGui:SetCore("ChatMakeSystemMessage", {
Text = "Welcome to Vesteria! Say '/help' for a list of commands.";
Color = Color3.fromRGB(0, 255, 149)
})
How to send system messages now:
It’s not so simple anymore!
To make system messages under the new TextChatService, you have to use the TextChannel:DisplaySystemMessage
API, which only takes two parameters: a message
(String) and and an optional metadata
(also a String!).
First we create a new channel for our game’s system messages, so we don’t accidently overload the Roblox system message channel.
Then we need to convert our system message properties to Rich Text.
Finally, we need to pass the font tag part of the string as metadata, because the message string will get sanitized, and add it back in using the channel callback. The end result looks something like this:
local modules = game.ReplicatedStorage:WaitForChild("modules")
local network = require(modules:WaitForChild("network"))
local channels = game.TextChatService:WaitForChild("TextChannels")
local systemChannel : TextChannel = Instance.new("TextChannel")
systemChannel.Name = "VesteriaSystemChannel"
systemChannel.Parent = channels
network:create("chatMakeSystemMessage", "BindableFunction", "OnInvoke", function(messageInfo)
local fontString = "<font"
if messageInfo.Color then
local c = messageInfo.Color
local r = math.floor(c.R * 255)
local g = math.floor(c.G * 255)
local b = math.floor(c.B * 255)
fontString ..= " color=\"rgb(" .. r .. "," .. g .. "," .. b .. ")\""
end
if messageInfo.Font then
local fontNameString
if typeof(messageInfo.Font) == "EnumItem" then
fontNameString = messageInfo.Font.Name
else
fontNameString = tostring(messageInfo.Font)
end
fontString ..= " face=\"" .. fontNameString .. "\""
end
if messageInfo.TextSize then
fontString ..= " size=\"" .. messageInfo.TextSize .. "\""
end
fontString ..= ">"
systemChannel:DisplaySystemMessage(messageInfo.Text, fontString)
end)
function systemChannel.OnIncomingMessage(textChatMessage : TextChatMessage)
local properties = Instance.new("TextChatMessageProperties")
local textString = textChatMessage.Text
-- Inject Rich Text
local metadata = textChatMessage.Metadata
if metadata then
textString = metadata .. textString .. "</font>"
end
properties.Text = textString
return properties
end
network:invoke("chatMakeSystemMessage", {
Text = "Welcome to Vesteria! Say '/help' for a list of commands.";
Color = Color3.fromRGB(0, 255, 149)
})
And now, at last, our system messages are coming through squeaky clean:
Considering that Roblox is moving to set TextChatService as the default for new experiences, I suggest converting your experiences. If you use the ChatMakeSystemMessage
SetCore like I did, I hope you found this guide useful for keeping your pretty system messages.