My game always freezes for Xbox players?

I recently did a fairly large update to my game. However, the game is now unplayable for my Xbox players; as a result, my game’s average playtime plummeted due to Xbox players freezing the minute they entered the game (to the point that the only way they could fix it was to force quit ROBLOX). The percentage of my game’s visits and revenue from Xbox wasn’t the biggest, but most of my competitors have Xbox support + every little bit of visits and revenue counts.
This is a video sent to me by a player of what happens when he joined on Xbox

I tested the game myself on my Xbox and it froze the second I joined. From what I have heard and seen, this issue has been going on for around a day or so. As a result, I have had to disable Xbox compatibility with my game.

Now, my game has changed a lot in this update but the team picking and welcome GUI have stayed the same, albeit with some minor performance changes to the scripts. A lot of those scripts are pretty old (and definitely inefficient) but have worked well for all platforms, until recently. I’m not sure if it’s those UI scripts or scripts from something else? All I know is the game music in my game continues to play during the freezing; it’s quite difficult to get output from Xbox players

--- team joining script
local mkt = game:GetService("MarketplaceService")
local RunService = game:GetService("RunService")
local teams;
---#game.Teams:FindFirstChild(v.Name):GetPlayers() < 

repeat wait(0.1) teams = game.Teams:GetChildren(); until #teams >= 13 --- make sure all the teams load before people can join them

for a,b in pairs (teams) do --- this gets all teams and makes ui for each one, besides the default join one
	if b ~= game.Teams["For Recruitment"] then
		local clone = script.Parent.Parent.start:Clone()
		clone.Parent = script.Parent
		clone.Image = b.flag.Texture
		clone.label.Text = b.Name
		clone.Name = b.Name
		clone.Visible = true
	end
end

function switch(v) --- when a player picks a team, this fires the remote that will switch their team and respawn them
	print("this works")
	game:GetService("ReplicatedStorage"):FindFirstChild("Remote"):FindFirstChild("TeamEvent"):FireServer(game.Teams:FindFirstChild(v.Name))	
	print("this ok")
	script.Parent.Parent.Parent.Parent.info.Visible = true
	script.Parent.Parent.Parent.Parent.Parent.buttons.Enabled = true
	script.Parent.Parent.Parent.Parent.team_Pick:Destroy()
	game.StarterGui:SetCore("ChatMakeSystemMessage", {
		Text = "[TIP]: You can lock your team to friends only by saying /lockteam!";
	})
end

function start()
	for i,v in ipairs(script.Parent:GetChildren()) do
		if v.ClassName == "ImageButton" then
			v.MouseButton1Click:Connect(function()
				print("click!")
				local locked = false
				if game.Teams[v.Name]:FindFirstChild("locked") ~= nil then -- checks to see if someone locked their team to friends only.
					if game.Teams[v.Name].locked.Value == true then
						local who = game.Teams[v.Name].locked:WaitForChild("creator")
						if not game.Players.LocalPlayer:IsFriendsWith(who.Value.UserId) then
							locked = true
						end
					end	
				end
				if locked == false then
					if game.Players.LocalPlayer.Team == game.Teams["For Recruitment"] and mkt:UserOwnsGamePassAsync(game.Players.LocalPlayer.userId,11322392) then
						if #game.Teams:FindFirstChild(v.Name):GetPlayers() < 4 then
							switch(v)
						else
							script.Parent.Parent.ClickErrorSound:Play()
						end
					elseif 	game.Players.LocalPlayer.Team == game.Teams["For Recruitment"] and not mkt:UserOwnsGamePassAsync(game.Players.LocalPlayer.userId,11322392) then
						if #game.Teams:FindFirstChild(v.Name):GetPlayers() < 2 then
							switch(v)	
						else
							script.Parent.Parent.ClickErrorSound:Play()
						end
					else
						script.Parent.Parent.ClickErrorSound:Play()
					end
				else
					script.Parent.Parent.ClickErrorSound:Play()
					game.StarterGui:SetCore("ChatMakeSystemMessage", {
						Text = "[ERROR]: You are not friends with the person(s) on this team!";
					})
				end	
			end)
		end
	end
end

game.Teams.ChildAdded:Connect(start)

start()

RunService.Heartbeat:Connect(function() --- checks constantly to see if any teams are open or closed now.
	for i,v in ipairs(script.Parent:GetChildren()) do
		if v.ClassName == "ImageButton" then
			if mkt:UserOwnsGamePassAsync(game.Players.LocalPlayer.userId,9579784) and #game.Teams:FindFirstChild(v.Name):GetPlayers() > 2 then
				v.Full.Visible = true
				if v.players:FindFirstChild("player") then
					for a,b in ipairs(v.players:GetChildren()) do
						if b:IsA("TextLabel") then
							b:Destroy()
						end	
					end
				end
			elseif not mkt:UserOwnsGamePassAsync(game.Players.LocalPlayer.userId,9579784) and #game.Teams:FindFirstChild(v.Name):GetPlayers() > 1 then
				v.Full.Visible = true
				if v.players:FindFirstChild("player") then
					for a,b in ipairs(v.players:GetChildren()) do
						if b:IsA("TextLabel") then
							b:Destroy()
						end	
					end
				end
			else	
				if not v.players:FindFirstChild("player") then
					for a,b in ipairs(game.Players:GetChildren()) do
						if b.Team == game.Teams:FindFirstChild(v.Name) then
							local x = script.Parent.Parent.player:Clone()
							x.Parent = v.players
							x.Text = b.Name
							x.Visible = true
						end
					end	
				end
				v.Full.Visible = false
			end
		end
	end
end)

Here’s the welcome GUI script:

---- this script is pretty old and inefficient, i will say. however it was not associated with any issues, until now.
local frame = script.Parent
local player = game.Players.LocalPlayer
local UserInputService = game:GetService("UserInputService")
local mkt = game:GetService("MarketplaceService")
local tele = { --- old versions of the game players can be teleported to
	tpmt2 = 981106912,
	original = 3188475792,
	old = 6380235528,
}

local gP = { ---- game passes
			season_Pass = 11322392,
			vip = 106923,
			double = 5951606,
}

if UserInputService.GamepadEnabled then
	frame.play.TextLabel.Visible = true	
end	
game.StarterGui:SetCoreGuiEnabled(Enum.CoreGuiType.Backpack, false)	

UserInputService.InputBegan:connect(function(input, processed) --- this was specifically made for xbox so if they just want the gui to go away and not read, they can just press B 
	if input.UserInputType == Enum.UserInputType.Gamepad1 then
		if input.KeyCode == Enum.KeyCode.ButtonB then
			frame.Parent:Destroy()
			game.StarterGui:SetCoreGuiEnabled(Enum.CoreGuiType.Backpack, true)	
		end
	end
end)

for i,v in ipairs(frame.games:GetChildren()) do --- teleporting service
	if v.ClassName == "ImageButton" then
		v.MouseButton1Click:Connect(function()
			game:GetService("ReplicatedStorage").Remote.SendPlayer:FireServer(tele[v.Name])
		end)
	end
end

for i,v in ipairs(frame.info:GetChildren()) do --- game passes
	for a,b in ipairs(v:GetChildren()) do
		if b.ClassName == "ImageButton" then
			b.MouseButton1Click:Connect(function()
				mkt:PromptGamePassPurchase(player, gP[b.Name])
			end)
		end
	end
end

frame.play.MouseButton1Click:Connect(function() --- clicking the play button
	frame.Parent:Destroy()
	game.StarterGui:SetCoreGuiEnabled(Enum.CoreGuiType.Backpack, true)	
end)
2 Likes

Does the Studio xbox emulation freeze as well? (I’m guessing not or it would be easy to troubleshoot)

1 Like

It does not freeze on studio.

Here’s what an Xbox player said about how they worked around it:
https://gyazo.com/f0b72e133711be7665ac20c9ee2993f5

I’ve been trying a lot of things to try and fix this - nothing seems to be working. Is it something with my game, or is it something with ROBLOX?
When I play on Xbox, and I force quit the game when it freezes, my character leaves a few seconds after I force quit the game instead of leaves automatically.

I’ve done a bit of testing and found that this is caused by the future lighting setting.
image
I believe this is a recent problem as I’ve been using the future lighting for a while and have only had a problem with it recently.

To fix this, I just changed the lighting setting to one of the other 3 and the game worked fine on Xbox.

What ended up being the problem was a day/night cycle system that was based on real-time, via UTC. Apparently using os.time, especially in a while loop, did not translate well to Xbox users (I’d imagine due to different compiling), and as a result, it would freeze their games.

Solution was I would just disable this feature for Console players.

Thanks for the help though!

1 Like