Applying proper text filtering is one of the most important ways to keep your experiences safe and secure. Roblox has a text filtering feature that not only prevents users from seeing inappropriate languages, but also blocks personally identifiable information.
Because filtering is crucial for a safe environment, Roblox actively moderates the content of experiences to make sure they meet community standards. If Roblox receives reports or automatically detects that your experience doesn't apply filtering, then the system removes the experience until you add text filtering.
Types of Text to Filter
You must filter any displayed text that you don't have explicit control over to make sure your experiences are compliant. Examples include:
User Input - Users can display text to others by:
Text Input - TextBox input, custom GUI with character buttons, and interactive keyboard models in the 3D space.
Implicit Input - Spelling out words with 3D Parts and Models.
Random Words - If your experience generates words from random characters and displays them to users, there is a chance that it creates inappropriate words.
External Sources - Some experiences connect to external web servers that fetch content to display information in experience. Sometimes you don't have the full control of the content of the external site, and a third party can edit the information.
Stored Text - If your experience stores text such as a chat log or a user's pet name using data stores, and the stored text might include inappropriate words, you should filter the text strings when retrieving them. This ensures that you use the most up-to-date version of the text filter.
TextService:FilterStringAsync() filters in-experience text by taking a string of text and the UserId of the user who created the text as input. It returns a TextFilterResult object that can differ for each user since TextService determines different filtering levels based on age and other details.
local TextService = game:GetService("TextService")local filteredText = ""local success, errorMessage = pcall(function()filteredTextResult = TextService:FilterStringAsync(text, fromPlayerId)end)if not success thenwarn("Error filtering text:", text, ":", errorMessage)-- Put code here to handle filter failureend
The TextFilterResult object returned by TextService:FilterStringAsync() has two methods that you can call in different cases:
- TextFilterResult:GetNonChatStringForBroadcastAsync() for filtering text visible to all users in an experience.
- TextFilterResult:GetNonChatStringForUserAsync() to display filtered text for one specific user, such as the name of a pet.
The following example sets up a dialog that lets a user write a message on a sign. Since everyone in the server can read the sign, including users who join the experience after the author has left, it's filtered with TextFilterResult:GetNonChatStringForBroadcastAsync().
local Players = game:GetService("Players")local ReplicatedStorage = game:GetService("ReplicatedStorage")local player = Players.LocalPlayerlocal playerGui = player:WaitForChild("PlayerGui")local screen = playerGui:WaitForChild("MessageScreen")-- GUI elements for dialoglocal frame = screen:WaitForChild("Frame")local messageInput = frame:WaitForChild("Message")local sendButton = frame:WaitForChild("Send")-- RemoteEvent to send text to server for filtering and displaylocal setSignText = ReplicatedStorage:WaitForChild("SetSignText")-- Called when button is clickedlocal function onClick()local message = messageInput.Textif message ~= "" thensetSignText:FireServer(message)frame.Visible = falseendendsendButton.MouseButton1Click:Connect(onClick)
local TextService = game:GetService("TextService")local ReplicatedStorage = game:GetService("ReplicatedStorage")local sign = game.Workspace.Signlocal signTop = sign.Toplocal signSurfaceGui = signTop.SurfaceGuilocal signLabel = signSurfaceGui.SignLabellocal setSignText = ReplicatedStorage.SetSignTextlocal function getTextObject(message, fromPlayerId)local textObjectlocal success, errorMessage = pcall(function()textObject = TextService:FilterStringAsync(message, fromPlayerId)end)if success thenreturn textObjectelseif errorMessage thenprint("Error generating TextFilterResult:", errorMessage)endreturn falseendlocal function getFilteredMessage(textObject)local filteredMessagelocal success, errorMessage = pcall(function()filteredMessage = textObject:GetNonChatStringForBroadcastAsync()end)if success thenreturn filteredMessageelseif errorMessage thenprint("Error filtering message:", errorMessage)endreturn falseend-- Fired when client sends a request to write on the signlocal function onSetSignText(player, text)if text ~= "" then-- Filter the incoming message and send the filtered messagelocal messageObject = getTextObject(text, player.UserId)local filteredText = ""filteredText = getFilteredMessage(messageObject)signLabel.Text = filteredTextendendsetSignText.OnServerEvent:Connect(onSetSignText)