How to migrate your Legacy Chat to TextChatService

Hi, since Roblox now requires everyone to move to the newer TextChatService I’ve faced same issues just like everyone else who are using Legacy Chat system. I have managed to change my code to adapt to these new Roblox changes, and so I want to share my experiences with you and some advices for parts that were difficult for me to understand or implement. I’ll provide some code lines examples as well that you may want to use for your custom chat system.

The very first thing that I have struggled with is understanding the concept of TextChatService, understanding how it works and what are the obvious differences from Legacy Chat functionality.
First off, I was unsure how to implement Chat text filtering which was essential for Legacy Chat. I have ended up looking up wrong things such as TextService which is NOT what you or I need for a communication chat system.
The answer to my question was simple and straightforward: TextChatService does not require you to send client message to server for filtering and then send it back from server to client.
This answer can be found here: In-Experience Text Chat | Documentation - Roblox Creator Hub

The second part that I’ve struggled with was getting a working code, since this system works a bit different than Legacy Chat I had to imagine how the message sending and receiving workflow looks like. This was actually pretty simple, in fact even simpler than the Legacy Chat system, because all you need is a send message function and a receive message function and both of these functions run on client, no server side scripts involved.

Third part was actually writing code, mostly just changing some of my already existing chat system code lines. Now the first thing you want in your chat system script is to have this line:

local TextChatService = game:GetService('TextChatService')

This line is needed for both - the script that sends message and the script that retrieves messages. Now you can do your chat system your own way, perhaps use just one script or even more, just make sure that you’re using game:GetService('TextChatService') and not game:GetService('TextService') or game:GetService('Chat')

Moving on to the more important function lines, I needed to get rid of RemoteEvents and chatted:FireServer(TextMessage) stuff as well as Chat Controller script which was residing in ServerScriptService.
To send messages from client to all other clients in the server (text filters are included as well) all you need to do is use a code line like this:

TextChatService.TextChannels.RBXGeneral:SendAsync(TextMessage)

Now the important things to note: RBXGeneral stands for a Text Channel name (you need to replace it with your TextChannel name if you are using custom made channels), unlike Legacy Chat, TextChatService have multiple Text Channels and you must choose which one you want to use (or create your own) and you can also use multiple different Text Channels if you need a private chat between two players and a public chat for all server.
How these Text Channels work? This one question I had in mind at first when reading TextChatService Documentation. Text Channels can be created automatically if you choose in your game on Roblox Studio in Explorer window find TextChatService and after you click on it check the Properties window for CreateDefaultTextChannels property, make sure it is ticked to receive the default Text Channels in game such as RBXGeneral.
TextChatService
Properties

You can create your own Text Channels instead of using Roblox default channels, however this is something I have opted out of doing myself for now and I will not cover it in this thread, but you can find it in official Roblox Documentation website: TextChannel | Documentation - Roblox Creator Hub

Now we know that messages can be sent using:

TextChatService.TextChannels.RBXGeneral:SendAsync(TextMessage)

However, we need to retrieve these messages somehow. With TextChatService the client can receive signals of new incoming message without the need of RemoteEvents or server side script that would act as a medium between clients. After long time spent doing Google searches I’ve found this line which is essential to receive messages:

TextChatService.OnIncomingMessage = function(message:TextChatMessage)

This line fires pretty much every time someone in server sends a message, but it fires twice!
Now why does this function fire twice when we send only one message? I’ve done my research using print(message) and found that we receive 2 different message.Status results, the first one being Enum.TextChatMessageStatus.Sending and the second one Enum.TextChatMessageStatus.Success. I have resolved this issue by using the following code line:

if message.TextSource and message.Status == Enum.TextChatMessageStatus.Success then

Now perhaps message.TextSource is not needed (?) but I do want too check for it in case if message somehow doesn’t have its sender name.
You might be asking what is message.TextSource well it is the player name of who sent the message, in other words the player name that you have to use at the start of the message text to indicate who sent it.

The last few important things you need to know is how to retrieve the message text and its sender name.
message.Text - - the chat message text context
message.TextSource.Name - - the name of player who sent the chat message
These two are required code parts you need to use for displaying the message text and player who sent it name on the screen.

local text = message.Text
local sender = message.TextSource.Name

With these you will be able to use text variable to define the chat message text content and sender variable to show who have sent this message.

This is how the beginning of your code should look like (for receiving messages to display them on screen)

This is pretty much all I needed to make it function properly, it looks short and simple but took me hours to understand and find needed information as some things such as how to receive an incoming message is not explained very well by Roblox Documentation.
I hope this little thread will help someone who also run into these troubles migrating custom chat system into TextChatService compliant chat.

Please take note that these are just merely tips for making a custom chat implementing TextChatService, this is not a full tutorial on how to make a working chat system.

9 Likes

Thank you so much, man! I was afraid my game was going to be in trouble due to all this new Roblox chat stuff but now I think I’m safe.

1 Like

I know that it isn’t your project but how would you change Better Chat v3 into this? It is a really great chat system and I do not want to get rid of it simply because of a Roblox update that no one really asked for. I personally am not inept enough on the coding side to know how to do it myself. Do you have any tips?

Hi, I do not know what is Better Chat V3, could you please elaborate it for me?

ask it’s developer to migrate it. U could also try contributing, but if u can’t just be patient.

if not wrong, there something that can’t be implemented at TextChatService, CMIIW~

BetterChat V3 | Discontinued Better Chat v3 is just a custom chat that this person made. I can not fully explain what it does nor how it does it but I do know a lot of games currently use it. The developer said that he would not be migrating it but it seems like he has came around and decided to work with someone to add a port.

Since it’s a chat system made by other person there’s no way to change the model or plugin unless you have full access to Better Chat V3 source code. I do not know how it functions and I can not guarantee it would be easy to migrate it, but the basic TextChatService functionality is very simple and straightforward, you could try to find code lines that execute function to send text message and replace it with one that is compliant with TextChatService.

There’s no perfect solution I could give you other than suggest you to follow the steps I’ve provided in the thread for migrating to TextChatService.

It’s there. How otherwise would you install and use it?

I would attempt to port it, but since the developer said a port is underway I won’t bother then.

I do not know since I never used it myself.

It would be best to wait for an official update from its developer.

message.Text is actually a string, while message.TextSource is link to instance TextSource which sent message. If message was seent by player, it will be also possible to retrieve player instance and get it’s name (if needed for whispers or other such functions) by game:GetService("Players"):GetPlayerByUserId(message.TextSource.UserId)

1 Like

That’s absolutely correct!

I’ve forgot to include that. While I was working on my own chat system code I’ve stumbled upon this slight issue that TextSource on the server side actually sends all data related to player instance, however on client side whether TextSource.UserId is specified or not it still returns player name only.

Snip1

I have updated my original post to include now better, correct usage of message.Text and message.TextSource.Name for displaying user name and their message.

alright this covers the migration for legacy chat but what about custom chats? how will one migrate those? Mainly this: Migrate to TextChatService: Removing Support for Legacy Chat and Custom Chat Systems - #507 by McDmnks

My post covered migration for both cases. I’ve had a custom Legacy Chat which I’ve easily migrated to TextChatService just by changing few code lines.

Also, if you have Legacy Chat and only the Legacy Chat without custom UI, then migration is as simple as changing TextChatService properties under Explorer window, you just need to change ChatVersion property to TextChatService and you’re done, no coding needed.
What I’ve covered in my post is a case when you have a customized chat system that requires coding.

But what if the custom chat isn’t a legacy chat? does this still work? or how would you solve the issues in the link above?

If it isn’t using Legacy Chat, nor TextChatService, then I believe according to a recent Roblox post you must integrate TextChatService into your code by April 30th, 2025: Integrate TextChatService:CanUsersDirectChatAsync or TextChannel:SetDirectChatRequester API to Comply with Settings

1 Like