I made a tutorial on YouTube using this code. It seems to work for me (this version is untested).
local Players = game:GetService("Players")
local DataStoreService = game:GetService("DataStoreService")
local dataStore = DataStoreService:GetDataStore("name_here")
local dataLoaded = false
local tries = 3
local function Set(plr)
if dataLoaded then
local key = "key#-" .. plr.UserId
local data = {
["currency1"] = plr.leaderstats.name.Value,
["currency2"] = plr.leaderstats.name2.Value
}
local success, err
local count = 0
repeat
success, err = pcall(function()
dataStore:SetAsync(key, data)
end)
count = count + 1
wait(0.5)
until count >= tries or success
if not success then
warn("Failed to serialize data. Error code: " .. tostring(err))
return
end
end
end
local function Get(plr)
local key = "key#-" .. plr.UserId
local serialized
local success, err
local count = 0
repeat
success, err = pcall(function()
serialized = dataStore:GetAsync(key)
end)
count = count + 1
wait(0.5)
until count >= tries or success
if not success then
warn("Failed to read data. Error code: " .. tostring(err))
return
end
if serialized then
return serialized
else
local starterStats = {
["currency1"] = 10,
["currency2"] = 20
}
return starterStats
end
end
local function CreateStats(plr)
local stats = Instance.new("Folder")
stats.Name = "leaderstats"
stats.Parent = plr
local data = Get(plr)
local currency1 = Instance.new("IntValue")
currency1.Name = "name"
currency1.Parent = stats
local currency2 = Instance.new("IntValue")
currency2.Name = "name2"
currency2.Parent = stats
currency1.Value = data.currency1
currency2.Value = data.currency2
dataLoaded = true
Set(plr)
end
game:BindToClose(function()
for _, v in pairs(game.Players:GetChildren()) do
Set(v.Name) -- v.Name is the player name
end
end)
Players.PlayerAdded:Connect(CreateStats)
Players.PlayerRemoving:Connect(Set)
You forgot to add a BindToClose function. This needs to be added just incase of server shutdown data won’t be lost. It is better to use UpdateAsync than SetAsync.
game:BindToClose(function()
for _,v in pairs(game.Players:GetChildren()) do
Set(v.Name) -- v.Name is the player name
end
end)
It would make it easier if you provide a screenshot of the PlayerSave tell us if its Bool,Number,String values. The Player that reports data loss is it just certain data(if so which value) or is the whole safe getting wiped?
There is A lot of Data in that folder that needs to be saved. If you go over the Data store limit of 260,000 it wont save everything. To check the amount of Data you are saving you can use this script.
local j = game:GetService("HttpService"):JSONEncode(Saving) -- Saving is the Table with the Data
print("JSON Encode: " .. j) -- Prints out the encoded data
print("JSON length: " .. #j) -- tells you how much data is in the table
I wrote a quick DataStore script that will loop through the table when a player enters and load the data. It also loops through the folder saving each value to the table named “Saving”. I have tested it with your old script and everything loaded fine. Just be sure to do more testing with it. Also if your game has stuff you can buy with robux I recommend saving when someone buys something.
local DataStore = game:GetService("DataStoreService"):GetDataStore("Data")
function loadData(plr)
local Folder = game.ReplicatedStorage:WaitForChild(plr.Name)
local key = plr.UserId
local success, message = pcall(function()
local Data = DataStore:GetAsync(key)
if Data ~= nil then
for i, v in pairs(Data) do
for _,k in pairs(game.ReplicatedStorage[plr.Name]:GetChildren()) do
if i == k.Name then
k.Value = v
end
end
end
else
print("New Player " .. plr.Name)
end
end)
if success then
print("Player Data Loaded for " .. plr.Name)
end
if message then
print("Player Data NOT loaded for " .. plr.Name .. " Error: ".. message)
end
end
function saveData(plr)
local Folder = game.ReplicatedStorage:WaitForChild(plr.Name):GetChildren()
local key = plr.UserId
local Saving = {}
for _,v in pairs(game.ReplicatedStorage[plr.Name]:GetChildren()) do
Saving[v.Name] = v.Value
end
local j = game:GetService("HttpService"):JSONEncode(Saving)
print("JSON Encode: " .. j)
print("JSON length: " .. #j)
local success, message = pcall(function()
DataStore:SetAsync(key, Saving)
end)
if success then
print("Data Successfully saved for ".. plr.Name)
else
print(message)
end
end
game.Players.PlayerAdded:Connect(function(plr)
if game.ReplicatedStorage:FindFirstChild(plr.Name) ~= nil then
game.ReplicatedStorage:FindFirstChild(plr.Name):Destroy()
end
local Folder = game.ReplicatedStorage.PlayerSave:Clone()
Folder.Parent = game.ReplicatedStorage
Folder.Name = plr.Name
game.ReplicatedStorage:WaitForChild(plr.Name)
loadData(plr)
end)
game.Players.PlayerRemoving:Connect(function(plr)
saveData(plr)
end)
game:BindToClose(function()
if game:GetService("RunService"):IsStudio() then
return
end
for _, Name in pairs(game.Players:GetChildren()) do
saveData(Name)
end
end)
Here is the Script. Be sure to read through it before using and test it in studios before you publish. You can also use Crazyman32 DataStore Editor in studios.