local DataStoreService = game:GetService("DataStoreService")
local PlayerStore = DataStoreService:GetDataStore("PlayerStore")
local Tries = 3
local PlayerValues = {
Money = 0,
Level = 1,
EXP = 0
}
function generateData(Player)
for i, v in pairs(SessionData) do
if i == 1 then
Player.Data.Money.Value = v
elseif i == 2 then
Player.Data.Level.Value = v
else
Player.Data.EXP.Value = v
end
end
end
function loadData(Player)
local Count = 0
local Folder = Instance.new("Folder")
Folder.Parent = Player
Folder.Name = "Data"
for i, v in pairs(PlayerValues) do
local Value = Instance.new("IntValue")
Value.Parent = Folder
Value.Name = i
Value.Value = v
end
repeat
wait(0.2)
local Success, Err = pcall(function()
SessionData = PlayerStore:GetAsync(Player.UserId)
end)
if Success then
for i, v in pairs(SessionData) do
print(i, v)
end
print("Success")
generateData(Player)
return
else
print("Error")
Count = Count + 1
end
until Count >= Tries
end
function saveData(Player)
local Storage = {}
local Count = 0
for i, v in pairs(Player.Data:GetChildren()) do
Storage[i] = v.Value
end
repeat
wait(0.2)
local Success, Err = pcall(function()
PlayerStore:SetAsync(Player.UserId, Storage)
end)
if Success then
print("Success")
return
else
print("Error")
Count = Count + 1
end
until Count >= Tries
end
game.Players.PlayerAdded:Connect(function(Player)
loadData(Player)
while true do
wait(1)
Player.Data.Money.Value = Player.Data.Money.Value + 1
end
end)
game.Players.PlayerRemoving:Connect(function(Player)
saveData(Player)
end)
The loadData() works perfectly fine . But the saveData() seems to only work when the player has joined the game and stayed for like at least 6 seconds. Is this common with data stores?
Well one thing I wanted to point out is that you’re waiting .2 seconds ( or even more since it’s not accurate ) before actually saving the data and also I noticed some stuff in your scripts so I decided to go ahead and write it up again :
local DataStoreService = game:GetService("DataStoreService")
local PlayerStore = DataStoreService:GetDataStore("PlayerStore")
local Players = game:GetService("Players")
local Tries = 3
local PlayerValues = {
Money = 0,
Level = 1,
EXP = 0
}
function generateData(Player,Data)
Data = Data or PlayerValues -- Basically if Data doesn't exist meaning player first time joined then use the default values.
for i,v in pairs(Data) do -- using pairs because Data is supposed to be a dictionary.
local CurrentStat = Player.Data:FindFirstChild(i) -- since this is a dictionary i would be the index which is the key ( Money, Level or EXP ).
print(i) -- just so you can see lol
if not CurrentStat then warn(string.format("couldn't find stat inside player data : %s",i)) continue end
CurrentStat.Value = v -- v is the value of the stat
end
end
function loadData(Player)
local Count = 0
local Folder = Instance.new("Folder")
Folder.Parent = Player
Folder.Name = "Data"
for i, v in pairs(PlayerValues) do
local Value = Instance.new("IntValue")
Value.Parent = Folder
Value.Name = i
Value.Value = v
end
-- Now here you were doing repeat, there is actually no need to do that unless the data didn't load successfully so :
local success,data = pcall(PlayerStore.GetAsync,PlayerStore,Player.UserId)
if not success then -- datastore failed or whatever
-- If the data didn't load successfully THEN do a repeat and do the 3 attempts at getting data...
repeat wait(.2)
success,data = pcall(PlayerStore.GetAsync,PlayerStore,Player.UserId)
Count = Count + 1
until success or Count >= Tries
-- if it still didn't get after 3 tries then kick the player to prevent any data loss ( which shouldn't occur in the first place )
if not success then return (function() Player:Kick("To prevent data loss you've been kicked from the game.") end)() end
end
generateData(Player,data) -- Generate the data like in your function
end
function saveData(Player)
local Storage = {}
local Count = -2 -- I made the count -2 because It's VERY IMPORTANT to save the data... ( I wouldn't even have a count if I were you and just repeat until success )
for _,v in pairs(Player.Data:GetChildren()) do
Storage[v.Name] = v.Value -- yes
end
-- Now here you were also waiting .2 seconds or even more before actually saving data which I think was your main issue :
local success = pcall(PlayerStore.SetAsync,PlayerStore,Player.UserId,Storage)
if not success then
repeat wait(.2)
success = pcall(PlayerStore.GetAsync,PlayerStore,Player.UserId)
Count = Count + 1
until success or Count >= Tries
-- can't really kick a player for "data loss prevention" if his data didn't save successfully and they already closed their client (kinda)
end
end
Players.PlayerAdded:Connect(loadData)
Players.PlayerRemoving:Connect(saveData)
game:BindToClose(function() -- incase the game shutdown or something happened
for _,v in ipairs(Players:GetPlayers()) do
coroutine.wrap(saveData)(v)
end
wait(10)
end)
You have to do more fixing the to the script I’m providing, I suggest looking at articles made by other devforum members about datastores such as :