Get Ready for Updated Experience Controls

If you disable the Chat.LoadDefaultChat value in the Chat service, the Legacy Chat System will not be injected into your game. In this case, the chat button will not be connected to anything, so you’re free to connect to it and configure it however you wish.

Here’s how the Legacy ChatScript does it:

local StarterGui = game:GetService("StarterGui")
local GuiService = game:GetService("GuiService")
local ChatService = game:GetService("Chat")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local MAX_COREGUI_CONNECTION_ATTEMPTS = 10

local ClientChatModules = ChatService:WaitForChild("ClientChatModules")
local ChatSettings = require(ClientChatModules:WaitForChild("ChatSettings"))

local function DoEverything()
	local Chat = require(script:WaitForChild("ChatMain"))

	local containerTable = {}
	containerTable.ChatWindow = {}
	containerTable.SetCore = {}
	containerTable.GetCore = {}

	containerTable.ChatWindow.ChatTypes = {}
	containerTable.ChatWindow.ChatTypes.BubbleChatEnabled = ChatSettings.BubbleChatEnabled
	containerTable.ChatWindow.ChatTypes.ClassicChatEnabled = ChatSettings.ClassicChatEnabled

	--// Connection functions
	local function ConnectEvent(name)
		local event = Instance.new("BindableEvent")
		event.Name = name
		containerTable.ChatWindow[name] = event

		event.Event:connect(function(...) Chat[name](Chat, ...) end)
	end

	local function ConnectFunction(name)
		local func = Instance.new("BindableFunction")
		func.Name = name
		containerTable.ChatWindow[name] = func

		func.OnInvoke = function(...) return Chat[name](Chat, ...) end
	end

	local function ReverseConnectEvent(name)
		local event = Instance.new("BindableEvent")
		event.Name = name
		containerTable.ChatWindow[name] = event

		Chat[name]:connect(function(...) event:Fire(...) end)
	end

	local function ConnectSignal(name)
		local event = Instance.new("BindableEvent")
		event.Name = name
		containerTable.ChatWindow[name] = event

		event.Event:connect(function(...) Chat[name]:fire(...) end)
	end

	local function ConnectSetCore(name)
		local event = Instance.new("BindableEvent")
		event.Name = name
		containerTable.SetCore[name] = event

		event.Event:connect(function(...) Chat[name.."Event"]:fire(...) end)
	end

	local function ConnectGetCore(name)
		local func = Instance.new("BindableFunction")
		func.Name = name
		containerTable.GetCore[name] = func

		func.OnInvoke = function(...) return Chat["f"..name](...) end
	end

	--// Do connections
	ConnectEvent("ToggleVisibility")
	ConnectEvent("SetVisible")
	ConnectEvent("FocusChatBar")
	ConnectEvent("EnterWhisperState")
	ConnectFunction("GetVisibility")
	ConnectFunction("GetMessageCount")
	ConnectEvent("TopbarEnabledChanged")
	ConnectFunction("IsFocused")

	ReverseConnectEvent("ChatBarFocusChanged")
	ReverseConnectEvent("VisibilityStateChanged")
	ReverseConnectEvent("MessagesChanged")
	ReverseConnectEvent("MessagePosted")

	ConnectSignal("CoreGuiEnabled")

	ConnectSetCore("ChatMakeSystemMessage")
	ConnectSetCore("ChatWindowPosition")
	ConnectSetCore("ChatWindowSize")
	ConnectGetCore("ChatWindowPosition")
	ConnectGetCore("ChatWindowSize")
	ConnectSetCore("ChatBarDisabled")
	ConnectGetCore("ChatBarDisabled")

    if not FFlagUserHandleChatHotKeyWithContextActionService then
        ConnectEvent("SpecialKeyPressed")
    end

	SetCoreGuiChatConnections(containerTable)
end

function SetCoreGuiChatConnections(containerTable)
	local tries = 0
	while tries < MAX_COREGUI_CONNECTION_ATTEMPTS do
		tries = tries + 1
		local success, ret = pcall(function() StarterGui:SetCore("CoreGuiChatConnections", containerTable) end)
		if success then
			break
		end
		if not success and tries == MAX_COREGUI_CONNECTION_ATTEMPTS then
			error("Error calling SetCore CoreGuiChatConnections: " .. ret)
		end
		wait()
	end
end

function checkBothChatTypesDisabled()
	if ChatSettings.BubbleChatEnabled ~= nil then
		if ChatSettings.ClassicChatEnabled ~= nil then
			return not (ChatSettings.BubbleChatEnabled or ChatSettings.ClassicChatEnabled)
		end
	end
	return false
end

if (not GuiService:IsTenFootInterface()) then
	if not checkBothChatTypesDisabled() then
		DoEverything()
	else
		local containerTable = {}
		containerTable.ChatWindow = {}

		containerTable.ChatWindow.ChatTypes = {}
		containerTable.ChatWindow.ChatTypes.BubbleChatEnabled = false
		containerTable.ChatWindow.ChatTypes.ClassicChatEnabled = false
		SetCoreGuiChatConnections(containerTable)
	end
else
	-- Make init data request to register as a speaker
	local EventFolder = ReplicatedStorage:WaitForChild("DefaultChatSystemChatEvents")
	EventFolder.GetInitDataRequest:InvokeServer()
end

Will a screen inset similar to the “Core UI Safe Area” be created so we can take advantage of the right side of the topbar space that’s free? Or should we assume the topbar can and will expand all the way across the screen? Seems like we can’t even take advantage of the space created in the top right if the latter is the case.

Reference: On-Screen UI Containers | Documentation - Roblox Creator Hub

Thanks for the response - additionally, SocialService:ShowSelfView() and SocialService:HideSelfView() don’t work with the new experience controls, will this be fixed as well?

1 Like

I’m fine with all of this, with the one exception of the hamburger menu still being visible even if all CoreGui features are disabled.

I think that the report menu being in the hamburger is unnecessary, as I don’t believe this is useful for the majority of players, and it is unnecessary, valuable screen space being used for what’s rarely used.

2 Likes

It is the real new UI, but with extra frames beneath it. It’s made in a way where the circle under the buttons combined with the black transparency makes the same color as the frame beneath them (or at least, very very close to it).

5 Likes

id say it decreases accessibility on a computer

you have to use more energy to move your mouse farther

also thats for WEB DESIGN

not GAME DESIGN

3 Likes

Didn’t know you could do this. Just to show, here’s what the topbar looks like with some new accommodations in an attempt to make the topbar fit with my game’s retro style. Still looks wrong and offputting, but atleast it’s a tad bit something, eh?

RobloxStudioBeta_CUcDs862St

Also, look at this peculiar trick:


5 Likes

I’ve been waiting for this for a long while. Thank you.

I had the new experience controls once on mobile, and they were way too big.
I highly suggest making it a bit smaller on phones.

1 Like

If it weren’t for the fact that the hamburger menu is still persistent, I would have no complaints (apart from the size on desktop). The top bar should be adaptable to all games and their style/UI and that second button just interferes with that logic because it stays there no matter if the developer actually needs anything it does or not. The first button is allowed to stay persistent because it’s a centralized hub of everything the player needs, but if the second one can’t be removed at all even when the developer disables everything it could hold, it just becomes annoying, even to the player, because it’s just a near useless and completely redundant dropdown that reveals a report button - something that is already revealed in the first button.

3 Likes

I don’t get why Roblox is so insistent on keeping Report in the new experience controls. Is there some legal reason behind this or something?

That’s all I can really think of at this point; they want to make reporting more obvious instead of having it be tucked away in the esc menu like it has been for the past 13 years.

image

But it’s just such a waste of space here. I wish I could remove the hamburger menu entirely, as it breaks immersion in experiences that want to disable as much of Roblox’s UI as possible. Report is the only thing preventing that.

Back when Report was part of the unibar itself it wasn’t as immersion-breaking:

image

4 Likes

If Roblox really wants to keep the report icon in the experience controls, even if everything is disabled, to make it easier for people to press the report button, is it possible for roblox to make the current hamburger icon change to become the report button when everything else is disabled? That way, reporting, especially on mobile, would be just 1 click or tap instead of 2 clicks, and it would not take up as much space as the dropdown menu or expandable unibar.

EDIT: Also, for games that want to fully hide the report button, is it possible to add a tooltip like this, so that new players would know where the report button is every time they join a game?
image_2024-09-21_221725156

^ Image showing Report Icon replacing the hamburger menu if everything else is hidden except for the report button. If roblox does not wish for the report menu to be totally disabled from the unibar menu, this is probably the least they can do to reduce clutter from the bulky menu (although the best option is to hide the unibar entirely)
image_2024-09-25_002834128

6 Likes

i said it again, that button was useless because:
Roblox Menu > Report

why they would need this? i prefer when all CoreGuis are disabled, i would only have the Roblox button and nothing else.

1 Like

I know this button is here to make it easy to close the leaderboard but, why is it low quality an gets cut off??? :huh:
image

2 Likes


They finally did it…

The new HP bar gets quite noticeably ‘squashed’ when it’s low and clips into the border frame:
image
I know it’s because it’s more than likely just 3 frames using UiCorner but it feels really unpolished for the actual default interface.

4 Likes

Worse. It’s actually just two images stacked on eachother.

image
image

So, in addition to it being larger, it doesn’t even properly scale right. Also experiencing this mysterious warnings in console. Nice.

4 Likes

Would love to see options in the future that allow developers or players to reduce the inset height, especially since positioning UI elements beneath the inset becomes much more difficult with the increased size. However, I’ve been very happy with the new APIs that allow for custom UI within the topbar!

Is there any way to get more info than just the inset your GUIs should be placed at? The main use I have for having the inset is to make more buttons that blend in with the other buttons up there. But right now, as far as I can tell, I’d have to manually set button colours, transparency, and padding between buttons. It would be nice if our scripts had access to this info as well as a way to keep up with it potentially changing so that our UI can be truly reactive to whatever changes come.

why does voice chat on solo playtests dont work anymore after this update came out?
it was fixed like a month ago around august 9?
even i fixed this by turning on the team create feature, its still not work.

1 Like