Issue with Datastore being rolled back

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.

1 Like