Need Help with DataStores!

I’m trying to make a simple Datastore that saves the data from a leaderstats value when the player leaves and loads it in when the player joins. The issue is every time I try to make one of these It never works and almost never leaves any errors. I’ve tried every tutorial I found, looked everywhere on the Developer Hub, but I just can’t seem to ever get it to work. I really want to learn how to do this and need someone to help me understand what I’m doing wrong. I know the general idea on how DataStores work, I just cant get them to work. This is my serverscript.

-- Leaderstats Script
game.Players.PlayerAdded:Connect(function(player)
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = player
	
	local Rebirths = Instance.new("IntValue")
	Rebirths.Name = "Rebirths"
	Rebirths.Value = 0
	Rebirths.Parent = leaderstats
	
	local Taps = Instance.new("IntValue")
	Taps.Name = "Taps"
	Taps.Value = 0
	Taps.Parent = leaderstats
end)

-- AddTaps Script
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local AddTaps = ReplicatedStorage:WaitForChild("AddTaps")

AddTaps.OnServerEvent:Connect(function(player)
	player.leaderstats.Taps.Value = player.leaderstats.Taps.Value+1
end)


-- GeneralPlayerData DataStore Script
local DSS = game:GetService("DataStoreService")
local playerStats = DSS:GetDataStore("playerStats")

game.Players.PlayerAdded:Connect(function(plr)
	local taps = plr:WaitForChild("leaderstats").Taps
	
	local data
	local succ, err = pcall(function()
		data = playerStats:GetAsync(plr.UserId.."_taps", plr.leaderstats.Taps.Value)
	end)
	
	if succ then
		taps.Value = data
		print("successfully got data")
	end
end)

game.Players.PlayerRemoving:Connect(function(plr)
	local data = plr.leaderstats.Taps.Value
	
	local succ, err = pcall(function()
		playerStats:SetAsync(plr.UserId.."_taps", plr.leaderstats.Taps.Value)
	end)
	
	if succ then
		print("Success!")
	else
		print("err")
		warn(err)
	end
end)

The second variable for a pcall contains the error message (if there is one). Your code should look like:

game.Players.PlayerAdded:Connect(function(plr)
	local taps = plr:WaitForChild("leaderstats").Taps
	
	local succ, err = pcall(function()
		return playerStats:GetAsync(plr.UserId.."_taps")
        -- just return the value, GetAsync doens't take a second parameter
	end)
	
	if succ then
        if err then
          -- check if the data isn't nil
		   taps.Value = data
        end

		print("successfully got data")
    else
      warn(err) -- tell you why the fetch was unsuccessful
	end
end)

Nothing new happened. This just keeps appearing in my Dev Console.

1 Like

replace data with err. I forgot to change that

if succ then
        if err then
          -- check if the data isn't nil
		   taps.Value = err
        end

Also, use WaitForChild for leaderstats on line 47

I made a post on this, you can use this script. Look in the comments I typed to learn about datastores, since I don’t want to just give you a script, and you use and and don’t learn anything.

local DSS = game:GetService("DataStoreService")
local Config = {KeyName = "GameStore101", Currencies = {Cash = "Int", Rebirths = "Int"}}
local Store = DSS:GetDataStore(Config.KeyName)
local CurrenciesToSave = {}
-- Create default currencies and put them in a table to be cloned
for i, v in pairs(Config.Currencies) do
	local new = Instance.new(v.."Value")
	new.Name = i
	table.insert(CurrenciesToSave, new)
end

-- PlayerAdded function
local function Added(plr)
	local PData = Instance.new("IntValue", plr)
	PData.Name = "Data" -- Object's children are saved
	for _, v in pairs(CurrenciesToSave) do
		v:Clone().Parent = PData -- inserts Values into data
	end
	local Key = "Player_"..plr.UserId -- defines key
	local Store = Store:GetAsync(Key) -- gets data
	if Store then -- if data exists then overwrite values with data
		for i, v2 in pairs(Store) do
			PData[i].Value = v2
		end
		print("Loaded data for "..plr.Name)
	else -- if not, then save the data
		local TBL = {}
		for _, v3 in pairs(PData:GetChildren()) do
			TBL[v3.Name] = v3.Value
		end
		local s, f = pcall(function() -- pcall
			Store:UpdateAsync(Key, function()
				return TBL
			end)
		end)
		if s then
			print("Data saved succesfully.")
		else -- retry if failed
			print("Data saving failed. Retrying.")
			local s2, f2 = pcall(function()
				Store:UpdateAsync(Key, function()
					return TBL
				end)
			end)
			if s2 then
				print("Retry succesfull.")
			else
				print("Retry failed.")
			end
		end
	end
end

local function Removing(plr) -- on player remove
	local PData = plr.Data -- Player's data
	local TBL = {} - table of data to save
	for _, v in pairs(PData:GetChildren()) do
		TBL[v.Name] = v.Value -- makes values with the Value's name and Value
	end
	local Key = "Player_"..plr.UserId -- key again
	local s, f = pcall(function() -- pcall again
		Store:UpdateAsync(Key, function()
			return TBL
		end)
	end)
	if s then
		print("Data Saving Succesfull!")
	else -- retry again
		print("Data saving failed. Retrying.")
		local s2, f2 = pcall(function()
			Store:UpdateAsync(Key, function()
				return TBL
			end)
		end)
		if s2 then
			print("Retry succesful")
		else
			print("Retry failed.")
		end
	end
end

local function bindtoclose()
	for _, plr in pairs(game:GetService("Players"):GetPlayers()) do -- save all player's data
		local PData = plr.Data
		local TBL = {}
		for _, v in pairs(PData:GetChildren()) do
			TBL[v.Name] = v.Value
		end
		local Key = "Player_"..plr.UserId
		local s, f = pcall(function()
			Store:UpdateAsync(Key, function()
				return TBL
			end)
		end)
		if s then
			print("Data Saving Succesfull!")
		else
			print("Data saving failed. Retrying.")
			local s2, f2 = pcall(function()
				Store:UpdateAsync(Key, function()
					return TBL
				end)
			end)
			if s2 then
				print("Retry succesful")
			else
				print("Retry failed.")
			end
		end
	end
end
-- connections
game:GetService("Players").PlayerAdded:Connect(Added)
game:GetService("Players").PlayerRemoving:Connect(Removing)
game:BindToClose(bindtoclose)

There is no leaderboard, but you can set it up by listening for the changed events in all the values of the Data value in player

1 Like

Are you sure you published your game? Because you can’t access DataStores unless you publish it. After you publish your game, you can use it everywhere.

Does this script work? I modified a line of code

– Leaderstats Script
game.Players.PlayerAdded:Connect(function(player)
local leaderstats = Instance.new(“Folder”)
leaderstats.Name = “leaderstats”
leaderstats.Parent = player

local Rebirths = Instance.new("IntValue")
Rebirths.Name = "Rebirths"
Rebirths.Value = 0
Rebirths.Parent = leaderstats

local Taps = Instance.new("IntValue")
Taps.Name = "Taps"
Taps.Value = 0
Taps.Parent = leaderstats

end)

– AddTaps Script
local ReplicatedStorage = game:GetService(“ReplicatedStorage”)
local AddTaps = ReplicatedStorage:WaitForChild(“AddTaps”)

AddTaps.OnServerEvent:Connect(function(player)
player.leaderstats.Taps.Value = player.leaderstats.Taps.Value+1
end)

– GeneralPlayerData DataStore Script
local DSS = game:GetService(“DataStoreService”)
local playerStats = DSS:GetDataStore(“playerStats”)

game.Players.PlayerAdded:Connect(function(plr)
local taps = plr:WaitForChild(“leaderstats”).Taps

local data
local succ, err = pcall(function()
	data = playerStats:GetAsync(plr.UserId.."_taps") --Data is equal to what you set your key value equal to.
end)

if succ then
	taps.Value = data
	print("successfully got data")
end

end)

game.Players.PlayerRemoving:Connect(function(plr)
local data = plr.leaderstats.Taps.Value

local succ, err = pcall(function()
	playerStats:SetAsync(plr.UserId.."_taps", plr.leaderstats.Taps.Value) --Sets key equal to leaderstats value
end)

if succ then
	print("Success!")
else
	print("err")
	warn(err)
end

end)

I saved the changes to Roblox and tried again but the same text in the console pops up. I switched it to local data = plr:WaitForChild("leaderstats").Taps.Value like you said.

Did you read my comment above? It may be the issue you are experiencing. Your script looks correct. There are no errors.

I did publish my game to Roblox with the services for Datastores enabled.

Did you try my script? I learned datastores yesterday and it looks exactly the same.

I just tried it and it doesn’t work.

I found why it is not working.

First one,

Why do you use plr.leaderstats.Taps.Value ? It is already set to value, which you defined below;

Change it to data = playerStats:GetAsync(plr.UserId.."_taps")

Second one, It is actually not preventing your script working, but you can remove it.

Why do you use that data variable? It is not needed.

So here is your revised script;

game.Players.PlayerAdded:Connect(function(player)
    local leaderstats = Instance.new("Folder")
    leaderstats.Name = "leaderstats"
    leaderstats.Parent = player

    local Rebirths = Instance.new("IntValue")
	Rebirths.Name = "Rebirths"
    Rebirths.Value = 0
    Rebirths.Parent = leaderstats

    local Taps = Instance.new("IntValue")
    Taps.Name = "Taps"
    Taps.Value = 0
    Taps.Parent = leaderstats
end)

-- AddTaps Script
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local AddTaps = ReplicatedStorage:WaitForChild("AddTaps")

AddTaps.OnServerEvent:Connect(function(player)
    player.leaderstats.Taps.Value = player.leaderstats.Taps.Value + 1
end)


-- GeneralPlayerData DataStore Script
local DSS = game:GetService("DataStoreService")
local playerStats = DSS:GetDataStore("playerStats")

game.Players.PlayerAdded:Connect(function(plr)
    local taps = plr:WaitForChild("leaderstats").Taps

    local data
    local succ, err = pcall(function()
	    data = playerStats:GetAsync(plr.UserId.."_taps")
    end)

    if succ then
	    taps.Value = data
	    print("successfully got data")
    end
end)

game.Players.PlayerRemoving:Connect(function(plr)

    local succ, err = pcall(function()
   	    playerStats:SetAsync(plr.UserId.."_taps", plr.leaderstats.Taps.Value)
    end)

    if succ then
	    print("Success!")
    else
	    print("err")
	    warn(err)
    end
end)

Are you sure? I tested it on studio and it saves data perfectly

Are you able to share any new errors you’re getting in the console now, or is this one still happening?

That one just keeps repeating and I don’t know why, when I changed the plr.leaderstats to plr:WaitForChild("leaderstats") it still just prints this out. I’m trying all my code onto another game to see if it’s not a problem with the code and maybe with the game.

1 Like

Try the script which I typed above. I’m sure it will be working.

Ya, for some reason when I tried the original code on another game it worked perfectly. It was a problem with the file i was In I think. Thank you to everyone who stayed and helped, sorry the issue wasn’t actually a coding problem.

1 Like