What is filtering?
Filtering is the way of checking text that has been passed through from a client to ensure that it is clean, and it stays within the guidelines of Roblox’s filtering system.
Filtering is super important because it protects naive people from sharing personal information, and protects them from vulgar language.
An oversimplified way this can be displayed is like this:
On the Developer Hub, there is another more indepth model that displays this.
How do I filter text?
The filtering system relies on a service called TextService. Also, this all needs to happen on the server, so make sure not to do it on the client to avoid any nasty errors.
The service can be added simply by retrieving the service: game:GetService("TextService")
Filtering is done by using the function: FilterStringAsync(), which as you may have guessed, is a function of the service we just retrieved, TextService.
FilterStringAsync has three parameters:
- the string to filter
- the UserId that the text has come from
- the context of the message (e.g. global, private messages)
Example 1
Let’s say that when a player presses a TextButton, you want to filter that text that they inputted through the TextBox. This could be used for a custom chat, nickname, pet naming, etc. All valid reasons to filter text.
- To set the environment up, we’ll need an event to fire the event to the server and then back to the clients once it’s been filtered, a LocalScript and a Script.
- Design a simple UI, with a TextBox, TextButton and a TextLabel.
- In your LocalScript, you’ll need to define your variables at the top, including the event. Then, add an event to see when a player clicks the button that it sends the text in the TextBox to the server.
It can be as basic as this:
--// Variables
local Event = game:GetService("ReplicatedStorage"):WaitForChild("FilterMessage")
local Input = script.Parent:WaitForChild("Frame"):WaitForChild("InputBox")
local Submit = script.Parent:WaitForChild("Frame"):WaitForChild("Button")
local Display = script.Parent:WaitForChild("Frame"):WaitForChild("TextLabel")
--// When the button is clicked
local function buttonClicked()
if Input.Text ~= "" then
Event:FireServer(Input.Text)
end
end
--// Bind the event to the function
Submit.MouseButton1Down:Connect(buttonClicked)
- That’s the LocalScript done for now. Go to the Script that you created earlier.
This time, we’ll be using the TextService module that we talked about earlier.
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local TextService = game:GetService("TextService")
local Event = ReplicatedStorage:WaitForChild("FilterMessage")
local function filterMessage(msg, fromUser)
local result
local success, err = pcall(function()
result = TextService:FilterStringAsync(msg, fromUser)
end)
if success then
return result
end
return false
end
The function filterMessage() will be the function that we use to filter the message.
PLEASE REMEMBER: We always need to pcall() these as the filtering may fail on Roblox’s end. If you don’t know what pcall() is, it’s a way of “safely erroring” if something does go wrong. If it errors, the Script can still run.
The “result” variable will be what we store the filtered text in.
TextService:FilterStringAsync(msg, fromUser). Message is the text that you typed in the TextBox, and fromUser is the player it came from.
- This function will prepare the final text for the player, based on their age (safechat or not). For example, if you typed
234837471239
into the TextBox, you’d see it when it’s displayed at the end of this tutorial. However, if you had safechat, you wouldn’t see it when it’s displayed later. It’ll make sense later when you test it out.
local function getFilteredMessage(text, recipient)
local result
local success, err = pcall(function()
result = text:GetChatForUserAsync(recipient)
end)
if success then
return result
end
return false
end
Again, we’re using pcall() to make sure that we can safely run the script. And then if it runs correctly, we return the finally filtered text under the local scope variable “result”.
- This part sends the message to the player when the event has been fired. All the functions that we completed above will be used in this function.
local function onSendMessage(sender, message)
if message ~= "" then
local filteredMessage = filterMessage(message, sender.UserId)
if filteredMessage then
for _, player in pairs(game.Players:GetPlayers()) do
local filteredMessage = getFilteredMessage(filteredMessage, player.UserId)
Event:FireClient(player, filteredMessage)
end
end
end
end
Event.OnServerEvent:Connect(onSendMessage)
First, the function checks if the message actually exists (the textbox wasn’t left blank). The next line then uses the first function and the two parameters local function filterMessage(msg, fromUser)
and the returned value is set to the “filteredMessage” variable.
If there was no errors, it then loops through all players in the game, and uses the second function that we created earlier, with the two parameters: local function getFilteredMessage(text, recipient)
. This is then fired to the client. We have to do this individually, opposed to doing FireAllClients(), as not everyone has the same chat restrictions.
- Go back to your LocalScript to receive the FireClient() event fired from your Script.
local function onClientReceive(message)
Display.Text = message
end
And then add the bind that connects the event to that function.
Event.OnClientEvent:Connect(onClientReceive)
The end result should be something like this:
This text is filitered as people could reveal personal information (pretty obvious, but if you didn’t understand, hopefully you do now)
When do I know when to filter text?
It’ll be fairly obvious, don’t worry. If you lack control over something (e.g. someone can name their pet, custom nickname, etc). Any input from the player should be filtered, just to be on the safe side. Rarely, when generating random words, it may generate a word that Roblox’s filter does not like. However, if you don’t filter it, then you’ll be subject to moderation. Stored text and text from external third party sources outside of Roblox need to be filtered too.
Good things to know
- Always pcall() your text filtering as there is chance that it may fail.
- Filtering won’t work in Studio by default, so if you publish it and then test it in game, it will work.
- A game without proper filtering will be taken down by Roblox, and your account may be subject to moderation.
Important Links
TextFilteringTutorial.rbxl (26.3 KB)
https://developer.roblox.com/en-us/api-reference/class/TextService
https://developer.roblox.com/en-us/api-reference/function/TextFilterResult/GetChatForUserAsync
Ending
Thanks for reading this, I hope it helped you. This was my first tutorial, any feedback is appreciated.
fin