Loading Scripts and Remote Event Timing Question

You can write your topic however you want, but you need to answer these questions:
My Server Script is loading long before local scripts…

  1. What is the issue? Include screenshots / videos if possible!

Building a Test Shop System and the players Values populate sometimes and other times the data does not populate and leaves the default text in the placeholder.

  1. What solutions have you tried so far? Did you look for solutions on the Developer Hub?

I added a wait(10) in order to make sure it fully populates and it works fine, but this seems a bit crazy.

with a wait(1) the stone value would populate but not the iron value. Using many print statements I found it has something to do with the time it takes to load the local script for the iron value.

Thoughts? Also only been scripting for 2 months or so… so be nice :wink: Thank you for your help!

SERVER SCRIPT:

serverStorage = game:GetService("ServerStorage")
replicatedStorage = game:GetService("ReplicatedStorage")

Players = game:GetService("Players")

local Remotes = replicatedStorage:WaitForChild("Remotes")
local BuyEvent = Remotes:FindFirstChild("Buy")
local UpdateValue = Remotes:FindFirstChild("UpdateValue")


local stoneValue = 100
local stoneNum = 1

local ironValue = 200
local ironNum = 1



Players.PlayerAdded:Connect(function(player)
	
	local PlayerFolder = serverStorage:WaitForChild(player.Name)
	local goldCoins = PlayerFolder:FindFirstChild("GoldCoins")
	local stone = PlayerFolder:FindFirstChild("Stone")
	local iron = PlayerFolder:FindFirstChild("Iron")
	
	**wait(10)**
**	**
**	UpdateValue:FireClient(player, stone.Value, iron.Value)**
	
	

	BuyEvent.OnServerEvent:Connect(function(player, itemName, Quantity1, Quantity2, Quantity3)


		if itemName == "Stone" then
			if Quantity1 == 1 then
				if goldCoins.Value >= stoneValue * Quantity1 then
				goldCoins.Value = goldCoins.Value - stoneValue * Quantity1
				stone.Value = stone.Value + Quantity1
				UpdateValue:FireClient(player, stone.Value, iron.Value)
					print("BOUGHT 1 STONE")
				else
					print("NOT ENOUGH GOLD COINS")
				end
				
			elseif 
				Quantity2 == 10 then
				if goldCoins.Value >= stoneValue * Quantity2 then
				goldCoins.Value = goldCoins.Value - stoneValue * Quantity2
				stone.Value = stone.Value + Quantity2
				UpdateValue:FireClient(player, stone.Value, iron.Value)
					print("BOUGHT 10 STONE")
				else
					print("NOT ENOUGHT GOLD COINS")
				end
				
			elseif 
				Quantity3 == 100 then
				if goldCoins.Value >= stoneValue * Quantity3 then
				goldCoins.Value = goldCoins.Value - stoneValue * Quantity3
				stone.Value = stone.Value + Quantity3
				UpdateValue:FireClient(player, stone.Value, iron.Value)
					print("BOUGHT 100 STONE")
				else
					print("NOT ENOUGH GOLD COINS")
				end
			end
			
			
		elseif
			itemName == "Iron" then
			if Quantity1 == 1 then
				if goldCoins.Value >= ironValue * Quantity1 then
					goldCoins.Value = goldCoins.Value - ironValue * Quantity1
					iron.Value = iron.Value + Quantity1
					UpdateValue:FireClient(player, stone.Value, iron.Value)
					print("BOUGHT 1 IRON")
				else
					print("NOT ENOUGH GOLD COINS")
				end

			elseif 
				Quantity2 == 10 then
				if goldCoins.Value >= ironValue * Quantity2 then
					goldCoins.Value = goldCoins.Value - ironValue * Quantity2
					iron.Value = iron.Value + Quantity2
					UpdateValue:FireClient(player, stone.Value, iron.Value)
					print("BOUGHT 10 IRON")
				else
					print("NOT ENOUGHT GOLD COINS")
				end

			elseif 
				Quantity3 == 100 then
				if goldCoins.Value >= ironValue * Quantity3 then
					goldCoins.Value = goldCoins.Value - ironValue * Quantity3
					iron.Value = iron.Value + Quantity3
					UpdateValue:FireClient(player, stone.Value, iron.Value)
					print("BOUGHT 100 IRON")
				else
					print("NOT ENOUGH GOLD COINS")
				end
			end
		end
	end)
end)

LOCAL SCRIPT LISTENING FOR REMOTE:

replicatedStorage = game:GetService("ReplicatedStorage")
local Remotes = replicatedStorage:WaitForChild("Remotes")
local UpdateValue = Remotes:FindFirstChild("UpdateValue")

print(UpdateValue.Name.. "FOUND")



local function updateValues(stone, iron)
	local Quantity = script.Parent
	print("FIRED")
	Quantity.Text = ""..iron
end



UpdateValue.OnClientEvent:Connect(updateValues)

Instead of waiting for a specific 10 seconds, you can make it more precise by doing this:

repeat wait() until LocalScript

-- run code afterward

i’m assuming I would have to point to the directory of that local script im waiting for rather than the LocalScript you stated? Just making sure that that isn’t a built in feature where it waits until all local scripts are loaded.

ServerScript - try this and see if it helps

serverStorage = game:GetService("ServerStorage")
replicatedStorage = game:GetService("ReplicatedStorage")

Players = game:GetService("Players")

local Remotes = replicatedStorage:WaitForChild("Remotes")
local BuyEvent = Remotes:FindFirstChild("Buy")
local UpdateValue = Remotes:FindFirstChild("UpdateValue")


local stoneValue = 100
local stoneNum = 1

local ironValue = 200
local ironNum = 1

Players.PlayerAdded:Connect(function(player)
	game:GetService("RunService").Heartbeat:Wait()
	local PlayerFolder = serverStorage:WaitForChild(player.Name)
	local goldCoins = PlayerFolder:FindFirstChild("GoldCoins")
	local stone = PlayerFolder:FindFirstChild("Stone")
	local iron = PlayerFolder:FindFirstChild("Iron")

	UpdateValue:FireClient(player, stone.Value, iron.Value)

	BuyEvent.OnServerEvent:Connect(function(player, itemName, Quantity1, Quantity2, Quantity3)
		if itemName == "Stone" then
			if Quantity1 == 1 then
				if goldCoins.Value >= stoneValue * Quantity1 then
				goldCoins.Value = goldCoins.Value - stoneValue * Quantity1
				stone.Value = stone.Value + Quantity1
				UpdateValue:FireClient(player, stone.Value, iron.Value)
					print("BOUGHT 1 STONE")
				else
					print("NOT ENOUGH GOLD COINS")
				end
				
			elseif 
				Quantity2 == 10 then
				if goldCoins.Value >= stoneValue * Quantity2 then
				goldCoins.Value = goldCoins.Value - stoneValue * Quantity2
				stone.Value = stone.Value + Quantity2
				UpdateValue:FireClient(player, stone.Value, iron.Value)
					print("BOUGHT 10 STONE")
				else
					print("NOT ENOUGHT GOLD COINS")
				end
				
			elseif 
				Quantity3 == 100 then
				if goldCoins.Value >= stoneValue * Quantity3 then
				goldCoins.Value = goldCoins.Value - stoneValue * Quantity3
				stone.Value = stone.Value + Quantity3
				UpdateValue:FireClient(player, stone.Value, iron.Value)
					print("BOUGHT 100 STONE")
				else
					print("NOT ENOUGH GOLD COINS")
				end
			end
			
			
		elseif
			itemName == "Iron" then
			if Quantity1 == 1 then
				if goldCoins.Value >= ironValue * Quantity1 then
					goldCoins.Value = goldCoins.Value - ironValue * Quantity1
					iron.Value = iron.Value + Quantity1
					UpdateValue:FireClient(player, stone.Value, iron.Value)
					print("BOUGHT 1 IRON")
				else
					print("NOT ENOUGH GOLD COINS")
				end

			elseif 
				Quantity2 == 10 then
				if goldCoins.Value >= ironValue * Quantity2 then
					goldCoins.Value = goldCoins.Value - ironValue * Quantity2
					iron.Value = iron.Value + Quantity2
					UpdateValue:FireClient(player, stone.Value, iron.Value)
					print("BOUGHT 10 IRON")
				else
					print("NOT ENOUGHT GOLD COINS")
				end

			elseif 
				Quantity3 == 100 then
				if goldCoins.Value >= ironValue * Quantity3 then
					goldCoins.Value = goldCoins.Value - ironValue * Quantity3
					iron.Value = iron.Value + Quantity3
					UpdateValue:FireClient(player, stone.Value, iron.Value)
					print("BOUGHT 100 IRON")
				else
					print("NOT ENOUGH GOLD COINS")
				end
			end
		end
	end)
end)

Generally speaking it’s bad practice to use wait() to make sure a resource has loaded on the client / server.

2 Likes

Its easy in your case since you already have the player referenced in your playeradded function.

You can just do

repeat wait() until player. --[[wherever the local script is]] 

Addressing the bad practice of using wait() for instancing, you can use waitforchild or findfirstchild(arg, true); to reference the script.

So instesd you could do,

Local localscript = player:WaitForChild('LocalScript');
-- or
Local localscript = player:FindfirstChild('LocalScript', true)
2 Likes

Instead of the server script sending the data when the player joins, have the client script request the data when the client script is ready. You can do this using a RemoteFunction (it’s fine if you just never call :InvokeClient()). You could also make the request through one RemoteEvent and send the response through another RemoteEvent.

2 Likes