I made this script to load and save data. How can I make it save if a player joins and quits very quickly? It will discard the data if I leave quickly? I tried several things, but none of them seem to work. It would suck if someone quickly joined, received a lot of loot, and quit and it all got trashed. Is there any way to tell the server to save it all before shutting down? It seems that SetAsync() is doing nothing!
local Database = game:GetService("DataStoreService"):GetDataStore("MAIN")
local RStorage = game:GetService("ReplicatedStorage")
local PlayerIndex = {}
local CanSaveData = true
local BFunctionF = Instance.new("Folder", RStorage)
function SaveData(Player)
local SCS, Result = pcall(function()
Database:SetAsync("USER"..Player.UserId, PlayerIndex[Player])
while Database:GetAsync("USER"..Player.UserId) ~= PlayerIndex[Player] do
Database:SetAsync("USER"..Player.UserId, PlayerIndex[Player])
warn("Stupid")
end
CanSaveData = true
end)
if not SCS then
warn(Result)
end
end
BFunctionF.Name = "DataManagerBindableFunctions"
game.Players.PlayerAdded:Connect(function(Player)
local ChangeData = Instance.new("BindableFunction", BFunctionF)
ChangeData.Name = Player.UserId
local Stats = Instance.new("BoolValue", Player)
Stats.Name = "leaderstats"
local LevelStat = Instance.new("IntValue", Stats)
LevelStat.Name = "Level"
local CrystalStat = Instance.new("IntValue", Stats)
CrystalStat.Name = "Crystals"
local MoneyStat = Instance.new("IntValue", Stats)
MoneyStat.Name = "Money"
local SCS, Data = pcall(function()
local RawData = Database:GetAsync("USER"..Player.UserId) or {}
local NewData = {
['Level'] = RawData['Level'] or 0,
['LvlXP'] = RawData['LvlXP'] or 0,
['Money'] = RawData['Money'] or 0,
['Crystal'] = RawData['Crystal'] or 0,
['Bonker'] = RawData['Bonker'] or 0,
['Sword'] = RawData['Sword'] or 0,
['Hammer'] = RawData['Hammer'] or 0,
['Knife'] = RawData['Knife'] or 0,
['Brick'] = RawData['Brick'] or 0}
return NewData
end)
if SCS and Data then
PlayerIndex[Player] = Data
end
MoneyStat.Value = Data.Money
LevelStat.Value = Data.Level
CrystalStat.Value = Data.Crystal
ChangeData.OnInvoke = function(Type, Amount)
print(Player, Type, Data[Type])
if Data[Type] == nil then
warn("Fake Playerdata Type")
else
local NV = Data[Type]+Amount
if Type == "Crystal" then
CrystalStat.Value = NV
elseif Type == "Money" then
MoneyStat.Value = NV
elseif Type == "Level" then
LevelStat.Value = NV
end
Data[Type] = NV
end
print(Data[Type])
return Data[Type]
end
end)
game.Players.PlayerRemoving:Connect(function(Player)
if CanSaveData then
CanSaveData = false
SaveData(Player)
end
end)
game:BindToClose(function()
for O, Player in pairs(game.Players:GetPlayers()) do
if CanSaveData then
CanSaveData = false
SaveData(Player)
end
end
end)
How can I fix this?

8 comments
Why do you set CanSaveData bool to false before saving a client's data? If two players leave at the same time, or even more, one of them could lose their data.
Agreed ^
Did you test this on a real server? Sometimes in studio the saving doesn't work.
In the past, it sometimes saved if I wait
https://scriptinghelpers.org/questions/71290/why-does-this-data-saving-script-not-work-at-all maybe this could help
no
It just seems that SetAsync() is doing NOTHING
do print checks