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)
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
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.
– 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
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.
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.
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.