DataStore saves 2x times when shutdowning game

Hello, I made DataStore but when I’m shutdowning game it’s saves 2x times and I get this warning:

Here is code:

local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local DataStore = game:GetService("DataStoreService")
local HttpService = game:GetService("HttpService")

local MainData = DataStore:GetDataStore("MainData")

local PlayerData = script.PlayerData

local sessionData = {}

local function loadData(player)
	local PDCopy = PlayerData:Clone()
	local leaderstats = PDCopy.leaderstats
	local key = "Plr_" .. player.UserId

	local dataToDecode

	local success, err = pcall(function()
		dataToDecode = MainData:GetAsync(key)
	end)

	if dataToDecode and success then
		local decodedData = HttpService:JSONDecode(dataToDecode)

		sessionData[player.UserId] = decodedData

		for i, folder in pairs(PDCopy:GetChildren()) do
			for i, val in pairs(folder:GetChildren()) do
				val.Value = sessionData[player.UserId][folder.Name][val.Name]
			end
		end

		warn("Successfuly loaded data for", player.UserId)
	else
		sessionData[player.UserId] = {}

		for i, folder in pairs(PDCopy:GetChildren()) do
			sessionData[player.UserId][folder.Name] = {}

			for tabName, v in pairs(sessionData[player.UserId]) do
				for i, val in pairs(PDCopy:GetDescendants()) do
					if val:IsA("ValueBase") then
						if val.Parent.Name == tabName then
							sessionData[player.UserId][tabName][tostring(val.Name)] = tonumber(val.Value)
						end
					end
				end
			end
		end

		warn(player.UserId, "got new Data")
	end

	leaderstats.Parent = player
	PDCopy.Parent = player
end

local function saveData(player)
	print("how many times")
	local PD = player.PlayerData
	local leaderstats = player.leaderstats
	leaderstats.Parent = PD
	
	local key = "Plr_" .. player.UserId

	table.clear(sessionData[player.UserId])

	for i, folder in pairs(PD:GetChildren()) do
		sessionData[player.UserId][folder.Name] = {}

		for tabName, v in pairs(sessionData[player.UserId]) do
			for i, val in pairs(PD:GetDescendants()) do
				if val:IsA("ValueBase") then
					if val.Parent.Name == tabName then
						sessionData[player.UserId][tabName][tostring(val.Name)] = tonumber(val.Value)
					end
				end
			end
		end
	end
	
	leaderstats.Parent = player

	local EncodedData = HttpService:JSONEncode(sessionData[player.UserId])

	local success, err = pcall(function()
		MainData:SetAsync(key, EncodedData)
	end)

	if success then
		warn("Successfuly saved Data for", player.UserId)
	end
end

Players.PlayerAdded:Connect(loadData)
Players.PlayerRemoving:Connect(saveData)

game:BindToClose(function()
	if not RunService:IsStudio() then
		for i, player in ipairs(Players:GetPlayers()) do
			task.spawn(function()
				saveData(player)
			end)
		end
	end
end)

Is it normal?

Yes, it is normal because you have the save function connected to both BindToClose and PlayerRemoving so it will save twice for the last player to leave (or for everyone if you shutdown the servers as BindToClose’s callback is called when the server is shut down and since when the last player leaves, the server has 0 players and it shuts down). To fix this once you have saved the data once add the userId to a table and in the save function check if the data for that player was already saved and if yes just return.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.