Datastore removes leaderstats bug

Hello Roblox,
i’m currently following monzter_dev’s simulator series and i just finished the datastore, however. when i finished, my leaderstats disappeared and left this error in my local script located inside the currency gui:

Players.ScxiptedShark.PlayerGui.CurrencyGui.CurrencyDisplayManager:18: attempt to index nil with 'leaderstats'

Here is my datastore code:

local players = game:GetService("Players")
local DataStoreService = game:GetService("DataStoreService")
local RunService = game:GetService("RunService")
local DataStore = DataStoreService:GetDataStore("Test") -- Set to official when publishing game

local function waitForRequestBudget(requestType)
	local currentBudget = DataStoreService:GetRequestBudgetForRequestType()
	while currentBudget < 1 do
		currentBudget = DataStoreService:GetRequestBudgetForRequestType()	
		task.wait(1)
	end
end

local function setupPlayerData(player)
	
	local UserId = player.UserId
	local key = "player_"..UserId
	
	local leaderstats = Instance.new("Folder", player)
	leaderstats.Name = "leaderstats"
	
	local Food = Instance.new("IntValue", leaderstats)
	Food.Value = 0
	
	local Coins = Instance.new("IntValue", leaderstats)
	Coins.Value = 0
	
	local sucsess, returnValue
	repeat 
		waitForRequestBudget(Enum.DataStoreRequestType.GetAsync)
		sucsess, returnValue = pcall(DataStore.GetAsync, DataStore, key)
	until sucsess or not players:FindFirstChild(player.Name)
	
	if sucsess then
		if returnValue == nil then
			returnValue = {
				
				Food = 0,
				Coins = 0,
				
			}
			
		end
		
		Food.Value = if returnValue.Food ~= nil then returnValue.Food else 0
		Coins.Value = if returnValue.Coins ~= nil then returnValue.Coins else 0
		
	else
		player:kick("An error has occured during loading your data, Roblox's Datastores might be down. Please try again later or contact us in our group!")
		print(player.Name.."'s Data has failed to load!")
	end
	
	local function save(player)
		local UserId = player.UserId
		local key = "player_"..UserId
		
		local food = player.leaderstats.Food.Value
		local coins = player.leaderstats.Coins.Value
		
		local dataTable = {
			
			Food = food,
			Coins = coins,
			
		}
		
		print(dataTable)
		
		local sucsess, returnValue
		repeat
			waitForRequestBudget(Enum.DataStoreRequestType.UpdateAsync)
			sucsess, returnValue = pcall(DataStore.UpdateAsync, DataStore, key, function()
				return dataTable	
			end)
		until sucsess
		
		if sucsess then
			print("Data Saved")
		else
			print("Data saving error")
		end
	end

local function onShutdown()
	if RunService:IsStudio() then
		task.wait(2)
	else
		local Finished = Instance.new("BindableEvent")
		local allPlayers = players:GetPlayers()
		local leftPlayers = #allPlayers
		
		for _, player in ipairs(allPlayers) do
			coroutine.wrap(function()
				save(player)
				leftPlayers -=1
				if leftPlayers == 0 then
					Finished:Fire()
				end
			end)
		end
		Finished.Event:Wait()
	end
	end
	
	for _, player in ipairs(players:GetPlayers()) do
		coroutine.wrap(setupPlayerData)(player)
	end

players.PlayerAdded:Connect(setupPlayerData)
players.PlayerRemoving:Connect(save)
	game:BindToClose(onShutdown)
	
	while true do
		task.wait(60)
		for _, player in ipairs(players:GetPlayers()) do
				coroutine.wrap(save)(player)
		end
	end
end

and here is the currency display script:

local Players = game:GetService("Players")
local player = Players.LocalPlayer

local CurrencyGui = script.Parent
local CurrencyHolderFrame = CurrencyGui:FindFirstChild("CurrencyHolder")
local Food = CurrencyHolderFrame:FindFirstChild("Food")
local Coins = CurrencyHolderFrame:FindFirstChild("Coins")

local function changeValue(name: string, StatsDisplay: number)
	if name == "Food" then
		Food.Frame.StatsDisplay.Text = StatsDisplay.."/30"
	elseif name == "Coins" then
		Coins.Frame.StatsDisplay.Text = StatsDisplay
	end
	
end

repeat wait(1) until player.leaderstats -- error is on this line apparently

changeValue("Food", player.leaderstats.Food.Value)
changeValue("Coins", player.leaderstats.Coins.Value)

player.leaderstats.Food.Changed:Connect(function()
	changeValue("Food", player.leaderstats.Food.Value)
end)
player.leaderstats.Coins.Changed:Connect(function()
changeValue("Coins", player.leaderstats.Food.Value)
end)

please reply with a fix!
-ScxiptedShark

Are they ServerScripts ?

I was wondering if there’s a LocalScript and there’s a ServerScript.

1 Like

The datastore script is located in serverscriptservice and is a regular script.
and the currency display script is located in a screen gui and is a local script

You should see what your output prints, as you said, it gives you the error “attempt to index nil with…” which means there’s something that doesn’t exist

1 Like

yea its the leaderstats, but at the top of the script i have created the leaderstats

repeat wait(1) until player.leaderstats

The reason it causes an error is because instances don’t work quite like tables

When you reference with dot or brackets operators, Lua checks if there’s a property named like that in the instance, if not it checks for a child, if not, it will error

If you are unsure if a child exists in an instance use FindFirstChild, because that instance may not exist and there may be a property named like the instance’s name

2 Likes

oh, good to know, i dont know how to fix that tho, think you can help me out?

I’ve edited my reply 30 caracters

1 Like

Alright, as @UltraYummyChocolate said, here’s the LocalScript:

local Players = game:GetService("Players")
local player = Players.LocalPlayer

local CurrencyGui = script.Parent
local CurrencyHolderFrame = CurrencyGui:FindFirstChild("CurrencyHolder")
local Food = CurrencyHolderFrame:FindFirstChild("Food")
local Coins = CurrencyHolderFrame:FindFirstChild("Coins")

local function changeValue(name: string, StatsDisplay: number)
	if name == "Food" then
		Food.Frame.StatsDisplay.Text = StatsDisplay.."/30"
	elseif name == "Coins" then
		Coins.Frame.StatsDisplay.Text = StatsDisplay
	end

end

repeat wait(1) until player:FindFirstChild('leaderstats')

changeValue("Food", player.leaderstats.Food.Value)
changeValue("Coins", player.leaderstats.Coins.Value)

player.leaderstats.Food.Changed:Connect(function()
	changeValue("Food", player.leaderstats.Food.Value)
end)
player.leaderstats.Coins.Changed:Connect(function()
	changeValue("Coins", player.leaderstats.Food.Value)
end)
1 Like
repeat wait(1) until player:FindFirstChild("leaderstatd")

would this work?

Yes, although it is far easier to just say

local leaderstats = player:WaitForChild(“leaderstats”)

2 things btw, wait is deprecated and why only waiting one second?

2 Likes

It’s this, instead.

This text will be blurred

2 Likes

Thanks dude, i think i’ve figured it out tho.

They are the same? What are you trying to say

1 Like

just so the leaderstats can load

Saying repeat until leaderstats is basically the same as waitforchild

1 Like

It’s not the same, he misspeled leaderstats.

1 Like

oh ok, good to for future projects!

1 Like

True, i thought you were talking about the " and ’

1 Like

oh yeah lol my bad!, whoopsies