Script stuck on waiting

Hey there! I was recently making a game but I accidentally made the UI work on the server and I was using global variables. Then, I made a player state module script. I turned the UI work into client side but then, when the loading was complete, it was stuck at waiting for the LoadingComplete state to be true while I set it to be true.

Line it gets stuck:

repeat task.wait() until Modules.PlayerState.Players[player.UserId]["LoadingComplete"] == true

Server Script:

local Services = {
	Players = game:GetService("Players");
	ServerStorage = game:GetService("ServerStorage");
	DataStoreService = game:GetService("DataStoreService");
	ReplicatedStorage = game:GetService("ReplicatedStorage");
}

local Modules = {
	LoadingScreenModule = require(Services.ReplicatedStorage.Libs.LoadingScreen);
	HUDMod = require(Services.ReplicatedStorage.Libs.HUD);
	PlayerState = require(Services.ReplicatedStorage.PlayerState);
}

local DataStores = {
	Credits = Services.DataStoreService:GetDataStore("CreditsDataStore");
}

local Remotes = {
	-- Events
	DisableOrEnableCoreGui = Services.ReplicatedStorage.Remotes.Events.DisableOrEnableCoreGui;
}

local Template = {
	Credits = 0;
}

local CommandPrefix = ";"
local Commands = {
	["kick"] = {
		CommandName = "Kick";
		CommandRequirement = "Player Name and Reason";
		Execute = function(player, targetPlayerName, ...)
			local matchingPlayers = {}
			for _, player in ipairs(Services.Players:GetPlayers()) do
				if string.sub(player.Name, 1, #targetPlayerName):lower() == targetPlayerName:lower() then
					table.insert(matchingPlayers, player)
				end
			end
			if #matchingPlayers == 0 then
				Modules.HUDMod.sendNotification(player, "NO MATCHING PLAYERS FOUND", "error")
			elseif #matchingPlayers == 1 then
				local targetPlayer = matchingPlayers[1]
				local reason = table.concat({...}, " ")
				targetPlayer:Kick("You were kicked by an admin. | "..reason)
			else
				Modules.HUDMod.sendNotification(player, "MULTIPLE PLAYERS FOUND", "error")
			end
		end
	};
	
	["changecurrency"] = {
		CommandName = "ChangeCurrency";
		CommandRequirement = "Player Name Name and Amount";
		Execute = function(player, targetPlayerName, amount)
			local matchingPlayers = {}
			for _, player in ipairs(Services.Players:GetPlayers()) do
				if string.sub(player.Name, 1, #targetPlayerName):lower() == targetPlayerName:lower() then
					table.insert(matchingPlayers, player)
				end
			end
			if #matchingPlayers == 0 then
				Modules.HUDMod.sendNotification(player, "NO MATCHING PLAYERS FOUND", "error")
			elseif #matchingPlayers == 1 then
				local targetPlayer = matchingPlayers[1]
				local DataFolder = Services.ServerStorage.Data[targetPlayer.UserId]
				DataFolder.Credits.Value = tonumber(amount)
			else
				Modules.HUDMod.sendNotification(player, "MULTIPLE PLAYERS FOUND", "error")
			end
		end
	};
	
	["addaccessory"] = {
		CommandName = "AddAccessory";
		CommandRequirement = "Player Name and Accessory ID";
		Execute = function(player, targetPlayerName, accessoryId)
			local matchingPlayers = {}
			for _, player in ipairs(Services.Players:GetPlayers()) do
				if string.sub(player.Name, 1, #targetPlayerName):lower() == targetPlayerName:lower() then
					table.insert(matchingPlayers, player)
				end
			end
			if #matchingPlayers == 0 then
				Modules.HUDMod.sendNotification(player, "NO MATCHING PLAYERS FOUND", "error")
			elseif #matchingPlayers == 1 then
				local targetPlayer = matchingPlayers[1]
				local accessory = game:GetService("InsertService"):LoadAsset(accessoryId):GetChildren()[1]
				accessory.Parent = targetPlayer.Character or targetPlayer.CharacterAdded:Wait()
			else
				Modules.HUDMod.sendNotification(player, "MULTIPLE PLAYERS FOUND", "error")
			end
		end
	};
}

Services.Players.PlayerAdded:Connect(function(player: Player)
	Modules.LoadingScreenModule.start(player)
	Remotes.DisableOrEnableCoreGui:FireClient(player, "All", false)
	
	Modules.PlayerState.update(player)
	
	local DataFolder = Instance.new("Folder", Services.ServerStorage.Data)
	DataFolder.Name = player.UserId
	
	local LeaderstatsFolder = Instance.new("Folder", player)
	LeaderstatsFolder.Name = "leaderstats"

	for index, value in pairs(Template) do
		if type(value) == "number" then
			local NumberValue = Instance.new("NumberValue", DataFolder)
			NumberValue.Name = index
			NumberValue:Clone().Parent = LeaderstatsFolder
			NumberValue:GetPropertyChangedSignal("Value"):Connect(function()
				LeaderstatsFolder[index].Value = NumberValue.Value
			end)
		end
	end
	
	local Data = {}
	for index, value in pairs(Template) do
		Data[index] = DataStores[index]:GetAsync(player.UserId) or value
	end

	for index, value in pairs(Data) do
		DataFolder[index].Value = value
	end

	Modules.PlayerState.update(player, {IsDataLoaded = true})
	
	repeat task.wait() until Modules.PlayerState.Players[player.UserId]["LoadingComplete"] == true
	
	Remotes.DisableOrEnableCoreGui:FireClient(player, "All", true)
	
	task.wait(1)

	Modules.HUDMod.welcomePlayer(player)
	
	repeat task.wait() until Modules.PlayerState.Players[player.UserId]["IsWelcomed"] == true
	
	Modules.HUDMod.startFunctioningButtons(player)

	player.Chatted:Connect(function(message)
		if player.UserId == 3581900099 then
			if string.sub(message, 1, 1) == CommandPrefix then
				local commandArgs = string.split(string.sub(message, 2), " ")
				local commandName = table.remove(commandArgs, 1):lower()
				if Commands[commandName] then
					Commands[commandName].Execute(player, unpack(commandArgs))
				end
			end
		end
	end)
end)

Services.Players.PlayerRemoving:Connect(function(player: Player)
	local DataFolder = Services.ServerStorage.Data[player.UserId]

	local success, errormessage = pcall(function()
		for index, value in pairs(Template) do
			DataStores[index]:SetAsync(player.UserId, DataFolder[index].Value)
		end
	end)

	if success then
		print("Successfuly saved data - "..player.Name.."(#"..player.UserId..")")
	else
		warn("Couldn't save data - "..player.Name.."(#"..player.UserId..")")
	end

	task.wait(1)
	DataFolder:Destroy()
end)

PlayerState Module:

local PlayerState = {}

PlayerState.Players = {}

PlayerState.update = function(player: Player, ...)
	local args = {...}
	if not PlayerState.Players[player.UserId] then
		PlayerState.Players[player.UserId] = {
			["LoadingComplete"] = false;
			["IsWelcomed"] = false;
			["IsDataLoaded"] = false;
		}
	else
		print(args)
		for key, value in pairs(args) do
			if PlayerState.Players[player.UserId][key] ~= nil then
				PlayerState.Players[player.UserId][key] = value
				print(PlayerState.Players[player.UserId])
			end
		end
	end
end

PlayerState.checkState = function(player: Player, ...)
	local args = {...}
	if not PlayerState.Players[player.UserId] then
		error("Called checkState but player "..player.UserId.." was not found.")
	else
		for key, value in pairs(args) do
			if PlayerState.Players[player.UserId][key] ~= nil then
				return PlayerState.Players[player.UserId][value]
			end
		end
	end
end

return PlayerState

LoadingModule:

local Services = {
	Players = game:GetService("Players");
	TweenService = game:GetService("TweenService");
	ReplicatedStorage = game:GetService("ReplicatedStorage");
}

local Facts = require(script.Facts)

local Modules = {
	PlayerState = require(Services.ReplicatedStorage.PlayerState);
}

local LoadingScreen = {}

startGeneratingFacts = function(textLabel: TextLabel)
	if textLabel.Name == "Facts" then
		while wait(4.5) do
			local randomIndex = math.random(#Facts)
			local randomFact = Facts[randomIndex]

			textLabel.Text = tostring(randomFact)
		end
	end
end

startTheLoadingBar = function(player: Player, bar: Frame, content, proggressTextLabel: TextLabel)
	local Progress = 0
	local barFiller = bar:FindFirstChild("BarFiller")
	if barFiller then
		while Progress < 100 do
			Progress += 5
			Services.TweenService:Create(barFiller, TweenInfo.new(0.6, Enum.EasingStyle.Linear, Enum.EasingDirection.Out, 0, false, 0), {["Size"] = UDim2.new(Progress / 100, 0, 1, 0)}):Play()
			proggressTextLabel.Text = tostring(math.floor(Progress) .. "%")
			task.wait(0.6)
		end

		for index, value in pairs(content) do
			if value:IsA("Frame") then
				if index == "Bar" then
					Services.TweenService:Create(bar, TweenInfo.new(1, Enum.EasingStyle.Linear, Enum.EasingDirection.InOut, 0, false, 0), {["BackgroundTransparency"] = 1}):Play()
					Services.TweenService:Create(value.BarFiller, TweenInfo.new(1, Enum.EasingStyle.Linear, Enum.EasingDirection.InOut, 0, false, 0), {["BackgroundTransparency"] = 1}):Play()
				else
					Services.TweenService:Create(value, TweenInfo.new(1, Enum.EasingStyle.Linear, Enum.EasingDirection.InOut, 0, false, 0), {["BackgroundTransparency"] = 1}):Play()
				end
			elseif value:IsA("TextLabel") or value:IsA("TextBox") or value:IsA("TextButton") then
				Services.TweenService:Create(value, TweenInfo.new(1, Enum.EasingStyle.Linear, Enum.EasingDirection.InOut, 0, false, 0), {["TextTransparency"] = 1}):Play()
			end
		end
		
		Modules.PlayerState.update(player, {LoadingComplete = true})
	end
end

LoadingScreen.start = function(player: Player)
	-- ScreenGui
	local LoadingScreen = player.PlayerGui:WaitForChild("LoadingScreen")
	LoadingScreen.Enabled = true

	-- Loading Screen content
	local Content = {
		Background = LoadingScreen:WaitForChild("Background");
		Bar = LoadingScreen:WaitForChild("Background"):WaitForChild("Bar");
		Facts = LoadingScreen:WaitForChild("Background"):WaitForChild("Facts");
		Title = LoadingScreen:WaitForChild("Background"):WaitForChild("Title");
		SubTitle = LoadingScreen:WaitForChild("Background"):WaitForChild("SubTitle");
		LoadingText = LoadingScreen:WaitForChild("Background"):WaitForChild("LoadingText");
		ProggressPercentage = LoadingScreen:WaitForChild("Background"):WaitForChild("ProggressPercentage");
	}

	task.spawn(startGeneratingFacts, Content.Facts)
	task.spawn(startTheLoadingBar, player, Content.Bar, Content, Content.ProggressPercentage)
end

return LoadingScreen

Any help on how to fix this is greatly appreciated!

4 Likes

I’m not sure to be honest, but maybe check if the UI is being loaded into the player?

local LoadingScreen = player.PlayerGui:WaitForChild(“LoadingScreen”)

If it cannot find the LoadingScreen, it will forever wait on the player.

3 Likes

But the loading screen is already showing up. After the loading is complete, it won’t continue but wait. Also I have added a print in the update function of the state machine and it said that it was true.

2 Likes

I dont see anything that is hanging “IsWelcomed” to true tho

3 Likes

This is in another module script. I am talking about how it stucks on waiting for the loading complete. What you are saying though is for another wait.

2 Likes

For anyone seeing this, I forgot to say that the two module scripts are on replicated storage.

2 Likes

so there should be a issue with HUD module script

2 Likes

How so? Any function within the HUD module will be called after the loading is complete.

2 Likes

Looks like HUD module is responsible for changing “IsWelcomed” to true but it dont do this

2 Likes

Yes it is. But again, the script will wait not only on the iswelcomed but on the loadingcomplete too.

1 Like

So with line is responsible for setting loading to true because I dont see one

There is nothing that is using loading module (or I dont see one)

1 Like

image

1 Like

That probably will be a issue

local success, response = pcall(function()
   task.spawn(startGeneratingFacts, Content.Facts)
end)
print(success)
print(response)
local success, response = pcall(function()
    task.spawn(startTheLoadingBar, player, Content.Bar, Content, Content.ProggressPercentage)
end)
print(success)
print(response)

try that maybe it will print a error

1 Like

The loading screen worked before this and after this. That’s not the problem. Output:
true
nil
true
nil

maybe barFiller is nil so it skips this part?

2 Likes

If the bar filler was nil then the loading screen wouldn’t work…

Is the loading module client or server sided?

2 Likes

It is in replicated storage so it is on the client

just

	Modules.PlayerState.update(player)

	Modules.LoadingScreenModule.start(player)
	Remotes.DisableOrEnableCoreGui:FireClient(player, "All", false)

(if still dont work then put wait between them)

or

PlayerState.update = function(player: Player, ...)
	local args = {...}
	if not PlayerState.Players[player.UserId] then
		PlayerState.Players[player.UserId] = {
			["LoadingComplete"] = false;
			["IsWelcomed"] = false;
			["IsDataLoaded"] = false;
		}
	end
	print(args)
	for key, value in pairs(args) do
		if PlayerState.Players[player.UserId][key] ~= nil then
			PlayerState.Players[player.UserId][key] = value
			print(PlayerState.Players[player.UserId])
		end
	end
end

so you dont will need to run Modules.PlayerState.update(player)

2 Likes

Still won’t work. Probably, there’s an other reason to this problem.