This the script where I save and load each players data.
The thing is, it doesn’t always save the data correctly, sometimes it does sometimes it doesn’t.
I have debugged it and everything looks how it’s supposed to, it goes through all the necessary keys and it saves them under a task.spawn() so that it takes less time and all the data can be saved before the server closes. However after it does call :SetAync(), it does not save it.
local DataStore = game:GetService("DataStoreService")
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Global = DataStore:GetDataStore("Global20")
local dataToSave = {}
local defaultValues = {
Spins = 3,
Bloodline = 3,
XP = 0,
Moveset = {
},
Abilities = {}
}
local globalKeys = {
"BoughtSpins",
"Settings",
}
local slotKeys = {
"Stats",
"SkillPoints",
"RebirthPoints",
"Moveset",
"Coins",
"lastPlayed",
"XP",
"Updated",
"Species",
"SubSpecies",
"Bloodline",
"Inventory",
"Skills",
"Abilities",
"Level",
"Spins"
}
local function get(Player,Slot,Key)
if typeof(Key) == "table" then
local data = {}
for i,v in pairs(Key)do
data[i] = Slot and dataToSave[Player][Slot][v] or dataToSave[Player][v] or defaultValues[v]
end
return data
else
local Slot = tonumber(Slot)
return Slot and dataToSave[Player][Slot][Key] or dataToSave[Player][Key] or defaultValues[Key]
end
end
ReplicatedStorage.Remotes.Data.fromClient.Get.OnServerInvoke = (function(Player:Player,Slot,Key:string)
local ID = Player.UserId
if not Key then
local success,msg = nil,nil
local playerData = {{},{},{}}
local attempts = 0
repeat
success,msg = pcall(function()
for _,key in pairs(globalKeys)do
playerData[key] = Global:GetAsync(ID.."/"..key) or defaultValues[key]
end
for slot = 1,3 do
for _, key in pairs(slotKeys) do
local value,info:DataStoreKeyInfo = Global:GetAsync(ID.."/"..slot.."/"..key)
playerData[slot][key] = value or defaultValues[key]
end
end
end)
attempts += 1
if not success then warn(msg) task.wait(3) end
until success or attempts == 5
print(playerData)
if success then
dataToSave[Player] = playerData
else
Player:Kick("Unable to load your data. Please try again later.")
end
elseif Key == "LobbyData" then
local data = {}
data.BoughtSpins = dataToSave[Player].BoughtSpins or 0
for i = 1,3 do
data[i] = {
Updated = dataToSave[Player][i].LastPlayed,
Spins = dataToSave[Player][i].Spins,
Bloodline = dataToSave[Player][i].Bloodline,
Level = dataToSave[Player][i].Level,
SubSpecies = dataToSave[Player][i].SubSpecies,
Species = dataToSave[Player][i].Species,
}
end
return data
else
return get(Player,Slot,Key)
end
end)
ReplicatedStorage.Remotes.Data.fromClient.Delete.OnServerInvoke = function(Player,Slot)
if dataToSave[Player] and dataToSave[Player][Slot] then
dataToSave[Player][Slot] = {Bloodline = dataToSave[Player][Slot].Bloodline, Spins = dataToSave[Player][Slot].Spins}
end
end
ReplicatedStorage.Remotes.Data.fromServer.Set.Event:Connect(function(Player,Slot,Key,Value)
if typeof(Key) == "table" then
for Key,Value in pairs(Key)do
dataToSave[Player][Slot][Key] = Value
end
else
if Slot then
dataToSave[Player][Slot][Key] = Value
else
dataToSave[Player][Key] = Value
end
end
end)
ReplicatedStorage.Remotes.Data.fromServer.Increment.Event:Connect(function(Player,Slot,Key,Increment)
if Slot then
dataToSave[Player][Slot][Key] = get(Player,Slot,Key) + Increment
else
dataToSave[Player][Key] = get(Player,Slot,Key) + Increment
end
end)
ReplicatedStorage.Remotes.Data.fromServer.Get.OnInvoke = get
local function save(Player)
if dataToSave[Player] then
local ID = Player.UserId
print(dataToSave[Player])
for _,key in pairs(globalKeys)do
task.spawn(function()
local key,value = (ID.."/"..key),dataToSave[Player][key]
local success,attempts,msg = false,0,nil
repeat
attempts += 1
success,msg = pcall(function()
if value then
Global:SetAsync(key,value,{ID})
else
Global:RemoveAsync(key)
end
end)
if not success then warn(msg) task.wait(3) end
until success or attempts == 5
end)
end
for slot = 1,3 do
for _, key in pairs(slotKeys) do
task.spawn(function()
local key,value = (ID.."/"..slot.."/"..key),dataToSave[Player][slot][key]
local success,attempts,msg = false,0,nil
repeat
attempts += 1
success,msg = pcall(function()
if value then
Global:SetAsync(key,value,{ID})
else
Global:RemoveAsync(key)
end
end)
if not success then warn(msg) task.wait(3) end
until success or attempts == 5
-end)
end
end
dataToSave[Player] = nil
end
end
Players.PlayerRemoving:Connect(function(Player)
save(Player)
end)
game:BindToClose(function()
for i,Player in pairs(Players:GetPlayers())do
save(Player)
end
end)
```.