I’m currently having an issue with my datastore. Sometimes players in my game get rolled back and they lose lots of their data. What is a possible solution I could do to prevent this from happening and making sure that it saves 100% all of their data on their join/leave. ~ Thanks in advance!
Here’s my code:
local PlayerStatsDS = game:GetService("DataStoreService"):GetDataStore("PlayerStats0908")
game.Players.PlayerAdded:Connect(function(NP)
local Key = "PDS-".. NP.UserId
local GetSave = PlayerStatsDS:GetAsync(Key)
local PSF = Instance.new("Folder", NP)
PSF.Name = "leaderstats"
local StatsFolder = script.Stats
for _, S in pairs(StatsFolder:GetChildren()) do
local NS = Instance.new(S.ClassName, PSF)
NS.Name = S.Name
NS.Value = S.Value
end
if GetSave then
for n, Stat in pairs(PSF:GetChildren()) do
Stat.Value = GetSave[n]
end
else
local STS = {}
for _, Stat in pairs(StatsFolder:GetChildren()) do
table.insert(STS, Stat.Value)
end
PlayerStatsDS:SetAsync(Key, STS)
end
end)
game.Players.PlayerRemoving:connect(function(OP)
local Key = "PDS-".. OP.UserId
local StatsFolder = OP.leaderstats
local STS = {}
for _, Stat in pairs(StatsFolder:GetChildren()) do
table.insert(STS, Stat.Value)
end
PlayerStatsDS:SetAsync(Key, STS)
end)
in ur code the data is only saved when a player leaves the game. If a player’s data is lost due to a server shutdown or other reasons, it won’t be saved until they leave the game again. Additionally, it’s possible that the data is getting lost during gameplay due to network issues or other reasons. but i dont think this is the issue
what you could do is ensure that player data is saved consistently, you can consider implementing an auto-save feature that periodically saves the player’s data at a fixed interval, such as every 5 minutes or so. You can use a loop or a Timer object to accomplish this.
heres something i used wehn this was heppening to me:
local SAVE_INTERVAL = 300
local PlayerStatsDS = game:GetService("DataStoreService"):GetDataStore("PlayerStats0908")
local function savePlayerData(player)
local key = "PDS-".. player.UserId
local statsFolder = player.leaderstats
local stats = {}
for _, stat in pairs(statsFolder:GetChildren()) do
table.insert(stats, stat.Value)
end
PlayerStatsDS:SetAsync(key, stats)
end
game.Players.PlayerAdded:Connect(function(player)
local key = "PDS-".. player.UserId
local savedData = PlayerStatsDS:GetAsync(key)
local statsFolder = Instance.new("Folder", player)
statsFolder.Name = "leaderstats"
local statsTemplate = script.Stats
for _, statTemplate in pairs(statsTemplate:GetChildren()) do
local stat = Instance.new(statTemplate.ClassName, statsFolder)
stat.Name = statTemplate.Name
stat.Value = statTemplate.Value
end
if savedData then
for i, savedStatValue in ipairs(savedData) do
statsFolder:GetChildren()[i].Value = savedStatValue
end
else
savePlayerData(player)
end
player.CharacterAdded:Connect(function(character)
savePlayerData(player)
end)
end)
game.Players.PlayerRemoving:Connect(function(player)
savePlayerData(player)
end)
while true do
wait(SAVE_INTERVAL)
for _, player in pairs(game.Players:GetPlayers()) do
savePlayerData(player)
end
end
This code saves the player’s data when they join the game, when their character spawns, and when they leave the game. Additionally, it has a loop that saves all player data at a fixed interval.
Add to what @54pv said, some of implementations in your game may require an ‘instant’ save like obtain legendary pets, trophies gain stuff like that. You don’t want to wait until the next save interval cause it may ruins the user experience when their valuables are gone.