Disabling classic chat for specific players?

Is there currently a way to temporarily disable the classic chat for a select group of players? I don’t want to disable the entire chat system (because I want the bubble chat to remain active), and I’m trying to avoid creating my own custom chat if possible.

I’ve tried forking the existing client chat modules and then editing them while a game is in session, but nothing happens. After reading through a number of pages on the forums, they only seem to discuss how to disable the chat overall, or how to disable classic chat permanently. I’ve also looked at RegisterChatCallback and other similar API pages. It seems like most of these only disable chat upon the window being created. The BubbleChatEnabled property under the Chat service is close to what I want, but I’m trying to toggle classic chat, not bubble chat.

Any help would be appreciated. In short, I want to be able to remove a player’s classic chat mid-game, not right when a player joins, and I want them to keep their bubble chat when their classic chat is removed.

2 Likes

You’ll need to create a remote event in a location shared between the server and clients like ReplicatedStorage. Then when you want the chat to be disabled, fire the event at the players you want the chat to be disabled with by using :FireClient(). Then you’ll need a LocalScript for the client to receive the event action and turn off the chat when fired.

--Server Script
local DisableChatEvent = game:GetService("ReplicatedStorage"):WaitForChild("DisableChatEvent")
local TargetPlayers = {Player1, Player2, etc.} --Add the players to this array using their Player object.
for _,FocusedPlayer in ipairs(TargetPlayers) do --Does the following for every target player:
	if FocusedPlayer then --Checks to make sure the player exists before firing the event. (In case they left the game.)
		Event:FireClient(FocusedPlayer) --Sends a signal to each target player.
	end
end
--Client LocalScript (A good location would be PlayerStarterScripts)
local DisableChatEvent = game:GetService("ReplicatedStorage"):WaitForChild("DisableChatEvent")
DisableChatEvent.OnClientEvent:connect(function()
	game:GetService("StarterGui"):SetCoreGuiEnabled(Enum.CoreGuiType.Chat, false)
end)

You can make another event that would do the same thing but for turning the chat on instead of off. Then fire that event after however long of a period of time or until you want those players to have chat enabled again.

5 Likes

Make a custom chat system that relies on server-side for both types of chats, (a bubble chat and a list type chat) Then manipulate the custom GUIs! The only reason I’m suggesting this, is because it’s an alternative to relying on a LocalScript to enable/disable CoreGui. This method probably won’t fix exploitation of events firing, but, you’re controlling the chat being enabled/disabled on the server exclusively, per player, instead of remoting their CoreGuis on and off. For one instance, if they copied the custom chat GUI and typed a message, it wouldn’t send because you disabled them server-side!

1 Like

Thanks for your input.

Unfortunately, this doesn’t solve my problem. I’m trying to disable classic chat only, not the entire chat system. In other words, I still want bubble chat to be available for players. Disabling the Chat CoreGui would disable all methods of chatting. But thank you regardless.

Thank you for your response.

I am fully aware that creating a custom chat system would enable me to achieve what I want, but the problem is that I want to work with Roblox’s default chat system.

I’m still looking for API documentation that enables me to achieve this with their current system and I can’t seem to find anything which is surprising considering the amount of features they’ve been adding to chat over the years (e.g. channels, modifying bubble chat).

1 Like

You could set the classic chat enabled property using a localscript, but it wont unanimize (my word for “make unanimous”) the chat when an exploiter just enables the property

Disabling the Chat using CoreGui does not disable bubble chat. Users with CoreGui Chat disabled will still see bubble chat.

Enabling and disabling Chat.BubbleChatEnabled is what determines whether or not players will see player’s bubble chats. Bubble chat is not a CoreGui, it’s a LocalScript that displays chat messages above parts in the form of BillboardGuis. If Chat.BubbleChatEnabled is false, it won’t display bubbles for players. Objects and NPCs can still use bubble chat, even with bubble chat disabled. If Chat.BubbleChatEnabled is true, it will display bubbles for all players, regardless of your CoreGui Chat setting.

I’m confused as to what you’re trying to achieve here.

Do you still want them to have the capability to chat even without a chat window? Without a text display, it can be extremely difficult for the player to keep track of what they’re typing and for the player to tell if they’re making any typos.

If so, you really only have two options.

You can remove the visibility of everything other than the input field UI (highlighted below).

Screenshot_3732

For example:

--Server Script
local ChatEvent = game:GetService("ReplicatedStorage"):WaitForChild("DisplayChatEvent") --A remote event.
local TargetPlayers = {Player1, Player2, Player3, etc.} --Add the players to this array using their Player object.
for _,FocusedPlayer in ipairs(TargetPlayers) do --Does the following for every target player:
	if FocusedPlayer then --Checks to make sure the player exists before firing the event. (In case they left the game.)
		ChatEvent:FireClient(FocusedPlayer, false) --Sends a signal to each target player.
	end
end

--LocalScript in StarterPlayerScripts
local LocalPlayer = game:GetService("Players").LocalPlayer
local PlayerGui = LocalPlayer:WaitForChild("PlayerGui")
local PreviousSettings = {}
local CurrentlyHidden = false --debounce.
game:GetService("ReplicatedStorage"):WaitForChild("DisplayChatEvent").OnClientEvent:Connect(function(EnableOrDisable)
	local ChatGui = PlayerGui:FindFirstChild("Chat")
	if not ChatGui then return end
	local Frame = ChatGui:FindFirstChild("Frame")
	local TextEntryParentFrame = ChatGui:FindFirstChild("ChatBarParentFrame", true)
	if not TextEntryParentFrame or not Frame then return end
	for i,v in pairs(ChatGui:GetDescendants()) do
		if v:IsA("GuiObject") and v ~= Frame and v ~= TextEntryParentFrame and not v:IsDescendantOf(TextEntryParentFrame)  then
			if EnableOrDisable == false and CurrentlyHidden == false then
				PreviousSettings[v] = v.Visible
				v.Visible = false
			elseif EnableOrDisable == true then
				if type(PreviousSettings[v]) == "boolean" then
					v.Visible = PreviousSettings[v]
				end
			end
		end
	end
	if EnableOrDisable == true then
		PreviousSettings = {} --Reset settings.
		CurrentlyHidden = false
	elseif EnableOrDisable == false then
		CurrentlyHidden = true
	end
end)

OR

You’d have to make your own custom chat and/or input field. The easiest way is probably moving a TextBox off screen and focusing it when the player presses the / key and use Players:Chat() when the player presses the Enter key. (Though I am unsure if Enter is detected by InputBegan from a mobile keyboard.)

For example:

local LocalPlayer = game:GetService("Players").LocalPlayer
local PlayerScripts = LocalPlayer:WaitForChild("PlayerScripts")
local TextBox = nil --A textbox object.
TextBox.Position = UDim2.new(math.huge,0,math.huge,0)
local MobileButton = nil --A mobile button to toggle the chat entry. (optional)
TextBox.ClearTextOnFocus = true --Since the TextBox will be hidden off screen and the player can't see their own text, it's probably a good idea to clear the text on focus.
local UIS = game:GetService("UserInputService")

function OnChatButtonPressed()
	if UIS.OnScreenKeyboardVisible == true and TextBox.Focused then --Toggle on screen keyboard
		TextBox:ReleaseFocus()
		return
	end
	TextBox:CaptureFocus()
	local EnterPressed = false
	local EnterCon = UIS.InputBegan:Connect(function(SubInput)
		if SubInput.KeyCode == Enum.KeyCode.Return then
			EnterPressed = true
		end
	end)
	TextBox.FocusLost:Wait()
	task.wait(0.1) --Wait needed so FocusLost and Enter input don't overlap.
	if EnterPressed == true then
		local Character = LocalPlayer.Character
		if Character then
			local DesiredMessage = TextBox.Text
			if string.find(DesiredMessage,"/") == 1 then --Remove any / characters at the beginning of the message if :CaptureFocus responds too quickly.
				repeat DesiredMessage = DesiredMessage:gsub("/", "", 1)
				until string.find(DesiredMessage,"/") ~= 1
			end
			TextBox.Text = DesiredMessage
			local ChatModule = PlayerScripts:FindFirstChild("ChatMain", true)
			if ChatModule then
				if ChatModule:IsA("ModuleScript") then
					local ChatMain = require(ChatModule)
					local MessageEvent = ChatMain.MessagePosted
					if MessageEvent then
						--pcall(function() MessageEvent:Fire({TextBox.Text}) end) --MessagePosted bindable is currently broken as of 6/13/2022 (I also tried the SetCore method, same result) so you'll have to use Chat:Chat() instead. If they fix it, use this line instead of Chat:Chat().
						if game.Chat.BubbleChatEnabled == true then --Need to check if bubble chat is enabled before using :Chat() since it would make a bubblechat even if it were disabled.
							game:GetService("Chat"):Chat(Character, TextBox.Text)
						end
					end
				end
			end
		end
	end
	EnterCon:Disconnect()
end

UIS.InputBegan:Connect(function(Input)
	if UIS:GetFocusedTextBox() then --Checks to make sure they aren't currently chatting/inputting.
		return
	end
	if Input.KeyCode == Enum.KeyCode.Slash then 
		OnChatButtonPressed()
	end
end)


if MobileButton then
	if UIS.TouchEnabled then
		MobileButton.TouchTap:connect(OnChatButtonPressed)
	else
		MobileButton.Visible = false
	end
end
1 Like

Would you happen to know where the Classic Chat Enabled property is?

I’m not worried about exploiters tampering with the visibility, the intention is more for submersion than anything else.

This is what the chat looks like when I disable the Chat system:
image

As you can see, nothing is there, so bubble chat is essentially disabled in the sense that players cannot use it, only view it.

On the other hand, I can use RegisterChatCallback to change visibility upon a player joining:

game:GetService("Chat"):RegisterChatCallback(Enum.ChatCallbackType.OnCreatingChatWindow, function()
	return {ClassicChatEnabled = false, BubbleChatEnabled = true}
end)

And this is exactly what I want:
image

The classic chat is disabled, but the bubble chat is not. And as you can see, they have the capability to chat with a text display, so it’s easy to tell if typos are being made.

The issue I’m having is, as far as I can tell, I can only achieve this with Roblox’s Enum.ChatCallbackType.OnCreatingWindow. In other words, I can’t seem to disable and enable the chat whenever I want, but instead whenever the window is created.

I hope this further clarifies what I was looking for. Your sample code actually does what I want and I’ll embarrassingly admit that I never realized the chat was accessible via PlayerGui. Instead of disabling/enabling via RegisterChatCallback, I’ll just change the visibility and then adjust the chat bar’s offset so it isn’t sticking in the middle of the screen for no reason.

Thanks for your help!

1 Like