TextChatService: New Chat Window Customization and Delivery APIs

Hi everyone,

As part of our continued investment into TextChatService, we’re excited to announce new developer capabilities!

Chat Window Customization

To allow you to best customize the default chat window to fit your experience’s aesthetic and UI layout, we’ve introduced several new properties to the ChatWindowConfiguration instance, parented under TextChatService.

With these, you can now change the position and size of the chat window!

You can also change the appearance of the chat window!

Message Delivery APIs

We’ve introduced a new API, TextChannel:ShouldDeliverCallback, which allows you to specify if a given message should be delivered to certain players. Here are some of the potential use cases that this supports:

  1. Proximity-based chat where players can only communicate with those close to them.

  2. Game where dead players’ messages will not be sent to living players.

  3. Guessing game where correct guesses in chat will not be seen by other players.

Here’s an example of proximity-based chat!

To specify this behavior, you can supply the callback with a function that takes in the textChatMessage and a target textSource (the player it will be sent to). If this function returns false, the message will not be delivered. Here is a code sample for the demo above:

local TextChatService = game:GetService("TextChatService")
local Players = game:GetService("Players")
local generalChannel : TextChannel = TextChatService:WaitForChild("TextChannels").RBXGeneral

local function getPositionFromUserId(userId)
	local targetPlayer = Players:GetPlayerByUserId(userId)
    if targetPlayer then
        local targetCharacter = targetPlayer.Character
        if targetCharacter then
            return targetCharacter:GetPivot().Position

    -- return default position for example
    return Vector3.new(0, 0, 0)

generalChannel.ShouldDeliverCallback = function(textChatMessage: TextChatMessage, targetTextSource: TextSource)
    local sourcePos = getPositionFromUserId(textChatMessage.TextSource.UserId)
    local targetPos = getPositionFromUserId(targetTextSource.UserId)

    -- If the distance between players is less than 50, deliver the message.
    return (targetPos - sourcePos).magnitude < 50

Note: This callback should be defined on the server. Additionally, this callback will not work properly if the function yields.

What’s next?

  • We will continue investing in developer customization needs for TextChatService, such as ChatInputBar configurations and more.

  • We will also soon be making TextChatService the default for new experiences.

What is TextChatService?

TextChatService is a safe, modern, and easily extendable chat that is a successor to the existing Chat service. This system is more sustainable for engineers at Roblox to iterate on, which means that we will be delivering regular fixes and new features to TextChatService that won’t conflict with any code you may have written that uses it.

How to switch to TextChatService

Please read this guide on how to enable TextChatService.

If you have any difficulties migrating your experience to TextChatService, please reach out to us! We have a support channel where the engineers on our team are willing to directly assist you. If you would like to be added, please send me a direct message!

Special thanks to @be_nj, @daweezy99, and @SubtleShuttle for their work on these capabilities!


This topic was automatically opened after 10 minutes.

Love this update! Something I would love to see for chat windows in the future is the ability to populate the chat bar with more buttons, such as an emoji picker or chat tag customizer.

Excited to see what’s next for chat service!


I really like that these options are now open to editing. I wonder if all of the bubble chat options will be added in the future as some missing ones are mentioned in the bubble chat documentation like CornerEnabled, CornerRadius, TailVisible, Padding, and much more including player/object-specific chat bubbles. (Bubble Chat | Roblox Creator Documentation for reference) I’d like to be able to change those without having to revert to the legacy chat system. That is holding me back from swapping over to some of my games.

I am excited to see everything coming together in an easy and compact way to make customization of the chat easier for newcomers to scripting as well as experts to be able to make everything easier.


o m g, this is maazing, thank you roblox team!


I will once again say the one feature I’ve been wanting since TextChatService had been announced:

Channel Bar. Please. The channel bar is the only reason I’m not switching over.


Great update, looking forward to utilizing TextChatService in my experiences.

As someone previously mentioned, is there any plans to implement Player/Object Specific bubble chat customization to this new TextChatService as the legacy system currently supports?

Some example use cases are a chat colors gamepass or differentiating different group ranks with differently-colored chat bubbles (both of which I actively use).


Can’t wait to implement this into my experiences!


This new chat window is great! But there is one minor issue that I can’t unsee…
Screenshot from 2022-11-14 13-49-12
The bottom stroke is cut off! (omg literally unplayable)
So, to figure out what was causing this, my curiousity led me on a journey of messing around in ROBLOX Studio… and I found the culprit!
Screenshot from 2022-11-14 13-49-45
There’s no padding on the bottom, so the chat bar’s outer stroke gets cut off as a result. Setting PaddingBottom to (0,1) seems to fix this issue!
Screenshot from 2022-11-14 13-51-03
Unfortunately, I can’t directly edit it in-game. So… I have to wait for this to be fixed :pensive:

edit: yeaaa letsgoo it was fixed!!!


While the proximity-based chat example in the announcement is cool, I think it would be even more powerful if we could determine if a chat should appear in bubbles and in the chat window independently. These should not be coupled together.

The Lua Chat System allows me to implement proximity-based chat such in a way that the chat window is used to hold a log of nearby messages but bubble chat will continue to show such that if a player comes into proximity before the bubble disappears, then it won’t show in the log but it will be seen.


The best update I ever seen while I’m a developer. It’s amazing! Can’t wait to add this in my experiences!

These updates are beatiful.
One thing that we need to be able to do is change a bubble chat’s text, specific per-user.
My use case is to ‘encrypt’ messages for certain players and some players can see that message, whereas some can’t.

Such an exciting new feature, thank you roblox dev team for your hard work!

Is there a way to remove already existing messages in the chat? So if you get out of range per example it would clear the message from the other player?

I’m so excited to customize the chat window in my game! Thank you!

We could now invent something as such called “proximity” chat, to go alongside the voice chat! This is a neat ass feature!

1 Like

Great update in terms of the chat, makes customisation significantly easier!

However, another great update would be the addition of a built-in system for whispering to multiple people are once, for example /w USERNAME1,USERNAME2, and then the people replying would also be able to reply in that group, so we could chat to multiple people at once.


In my opinion it would be nice for BubbleChats to have a special indicator for messages sent in TeamChat and Whispers, since it’s impossible to know in games which have the Chat Window Logs disabled. It could be signalled by a different color, a prefix like [T] and [W] or something along those lines.

Great update tho! It’s always nice to see getting some more customizability.


I made a test place as an example of this, so if anyone wants to try it, here you go:

If anyone is wondering how to do this, here's a little tutorial on how you would do it

First, make sure TextChatService is enabled of course.

Now, create 2 Teams, one named “Dead” and one named “Alive”. The Color of both teams doesn’t matter.

Then create a script in ServiceScriptService.

With this code inside:

local TextChatService = game:GetService("TextChatService")
local Players = game:GetService("Players")
local Teams = game:GetService("Teams")

local GeneralChannel : TextChannel = TextChatService:WaitForChild("TextChannels").RBXGeneral -- Variable for the General Channel

-- Defining Both Teams
local Dead = Teams.Dead
local Alive = Teams.Alive

GeneralChannel.ShouldDeliverCallback = function(message : TextChatMessage, targetTextSource : TextSource)
	local TextSource = message.TextSource -- The Speaker
	local player = Players:GetPlayerByUserId(TextSource.UserId) -- The Player of the Speaker
	local otherPlayer = Players:GetPlayerByUserId(targetTextSource.UserId) -- All the other players in the game

	-- Makes it so players on the Alive Team can't see the messages on the from the Players on the Dead Team, but the Players on the Dead Team can see the Messages from the Players on the Alive Team
	return (player.Team == otherPlayer.Team) and (player.Team == Teams.Alive and otherPlayer.Team == Teams.Dead)

Hey guys, great update. I’m not sure if this has been fixed yet, but with the new TextChatService enabled, using :Chat() on a part doesn’t actually produce a chat bubble. This is problematic since :Chat() only accepts parts and characters owned by actual players, and prevents us from making talking NPCs.