How wait for players data to load in seperate script (problem in multiplayer studio tests)

-- Data
function DataManager:Load(player)
    print('Loading Data')
	local LoadData = PlayerDataStore:GetAsync(player.UserId) or CloneTable(DefaultData)
	
	PlayerData[player.UserId] = UpdateData(LoadData, CloneTable(DefaultData))

	DataReady = true
    print('Data Ready')
end

-- Inventory
function InventoryManager:Update(player)
    print('Checking inventory')
	local User = PlayerData[player.UserId]
	if not User then return end
		
	InventoryCheck:InvokeClient(player, User.Inventory)
end

My inventory manager :Update() function is being called before the players data is ready. Output order goes
Loading Data
Checking Inventory
Data Ready

InventoryManager:Update() gets called when the client loads. The DataManager:Load() fires as soon as the player joins, so since the server loads first, I’d imagine data should be ready well before the client loads, so why is it taking so long to load the data? And how can I get the seperate script to wait until the players data exists.

NOTE This works in play solo and online play. It does NOT work when I try multiplayer tests in studio

1 Like

I might be a little confused here on your question but why not have the Client ask for their data instead of have the Server give it to them when it thinks they’re ready?

-- In a Local Script in player:
local myData = nil -- creates myData variable

function SetupPlayer()
	PlayerStats:FireServer() -- tells the server that you are requesting your data
	while myData == nil do wait(1) end  -- waits for the data to arrive
end

function UpdateData(newData)
	myData = newData -- sets the myData table to the new data you have recieved
end

PlayerStats.OnClientEvent:Connect(UpdateData)

SetupPlayer() -- this will run as soon as this local script is loaded
-- In a Server Script, best to put it in ServerScriptStorage
function RetrieveData(player)
	local playerData = DataModule.ReturnData(player) -- the data module retrieves the player's data
	playerData.Ships[4].Configuration.Speed = 101
	PlayerStats:FireClient(player, playerData) -- When a player fires the remoteEvent asking for data we fire it back returning their data
end

PlayerStats.OnServerEvent:Connect(RetrieveData)

I got this from Quoteory on this post (Changing some stuff) that shows a nice simple method of storing player data.
DataStore2 is great for storing player data too but is pretty advanced

You could implement a BindableEvent and an internal property to mimic DataReady from Data Persistence, then create a new method that essentially integrates both of these. When calling the method, first you would check if the DataReady value is true. If not, then you’d wait for the corresponding BindableEvent to fire. Something akin to the following:

function DataManager:WaitForData(player)
    local playerData = PlayerData[player.UserId]

    if playerData then
        return playerData
    end

    return bindableSomewhere.Event:Wait()
end

And then from your Load function, instead of DataReady,

binadbleSomewhere:Fire(playerDataTableGoesHere)