How to make a custom chat system using TextChatService

Since ROBLOX hasn’t explicitly shown how to migrate old custom chat systems to the new TextChatService, and I haven’t seen any tutorials showing how to create a basic custom chat using it yet. I thought I would just do it myself.

Benefits of using TextChatService

  • ROBLOX will automatically filter chat messages for you.
  • ROBLOX will handle chat moderation for you.
  • ROBLOX will automatically handle age checks and chat permissions for you.

Steps on how to create a custom chat system using TextChatService
This tutorial does not show you how to make a good looking custom chat GUI, it only shows how to create a very basic chat GUI and how to make it work with TextChatService using some simple scripting logic.

Basic Barebones GUI Section
1. Start by creating a ScreenGui in StarterGui. Name it CustomChat.
2. Add a ScrollingFrame into the ScreenGui you just made. Change the Size, BackgroundTransparency, and other properties to whatever you want.
3. Add a TextLabel to the ScrollingFrame, make sure to name it DefaultChatMessage.
4. Add a UIGridLayout to the ScrollingFrame. Adjust CellPadding to something like {0.01, 0},{0.01, 0} and CellSize to something like {1, 0},{0.05, 0}, so new messages will be automatically sorted into position. Duplicate your DefaultChatMessage instance to make sure CellPadding and CellSize are what you want. Delete the duplicate “DefaultChatMessage” when you are done.
5. Set the visible property of your DefaultChatMessage to be false.

Scripting Section
1. Start by creating a script with a RunContext of client. Name it whatever you want. Parent it where most convenient.
2. Next, create local variables for TextChatService, TextChannels, and RBXDefault. Add them to the top of your empty script.

local TextChatService = game:GetService("TextChatService")
local TextChannels = TextChatService:WaitForChild("TextChannels") 
local RBXGeneral = TextChannels:WaitForChild("RBXGeneral")

3. Add a MessageReceived connection for RBXGeneral

RBXGeneral.MessageReceived:Connect(function(incomingMessage: TextChatMessage)
--scripting logic will go here
end)

4. Add basic scripting logic to your MessageReceived connection to get your finished script

local TextChatService = game:GetService("TextChatService")
local TextChannels = TextChatService:WaitForChild("TextChannels") 
local RBXGeneral = TextChannels:WaitForChild("RBXGeneral")

RBXGeneral.MessageReceived:Connect(function(incomingMessage: TextChatMessage)
	local PlayerWhoSentMessage=game.Players:FindFirstChild(incomingMessage.TextSource.Name)
	local ChatMessage=incomingMessage.Text --automatically filtered

	if PlayerWhoSentMessage~=nil then --only add a new message if the player is found
		local MessageBoxClone=game.Players.LocalPlayer.PlayerGui.CustomChat.ScrollingFrame.DefaultChatMessage:Clone() --Clone the empty DefaultChatMessage
		MessageBoxClone.Text=PlayerWhoSentMessage.Name..": "..ChatMessage --Add player name and text
		MessageBoxClone.Parent=game.Players.LocalPlayer.PlayerGui.CustomChat.ScrollingFrame --Parent it to your custom chat scrolling frame
		MessageBoxClone.Visible=true --Make it visible so you can actually see it
	end

end)

See? It’s actually quite simple to use TextChatService for a custom chat system! You can add additional logic, such as checking a player’s team, to create features like a police radio!

It will automatically capture chat input as long as RBXDefault is set as the default TextChannel (which it is by default), so no custom chat input is required.

But if you want to make a custom chat input you would use TextChannel:SendAsync in a LocalScript. You can use RBXDefault as the TextChannel for this.
You would then get the output from the MessageReceived connection to RBXDefault.

16 Likes

How is it a custom chat if its not i/o but just output reading?
Doesn’t makes sense really.

2 Likes

Thanks for this. Resources are very nice to have when updates when foggy updates like this are released. Wouldn’t want to publish anything that could get my games in bad standing.

2 Likes

Thank you for pointing that out! I forgot to explain that in the tutorial so I just edited it.

It will automatically capture chat input as long as RBXDefault is set as the default TextChannel (which it is by default), so no custom chat input is required.

But if you want to make a custom chat input you would use TextChannel:SendAsync in a LocalScript. You can use RBXDefault as the TextChannel for this.
You would then get the output from the MessageReceived connection to RBXDefault. Hope this helps!

3 Likes

THANK YOU SO MUCH. Roblox’s age estimation update is an absolute disaster.

1 Like

Will roblox automaticly apply filter and age check for all TextChannels in game OR just for TextChannels that are default created by TextChatService?

Yes all messages sent through a TextChannel will be automatically filtered and apply age check.

You can access the filtered text by reading the .Text property of a TextChatMessage.

If two users are unable to chat with each other due to ROBLOX’s age restrictions, their client will not receive the TextChatMessage through the MessageReceived connection.

RBXGeneral.MessageReceived:Connect(function(incomingMessage: TextChatMessage)