I have a data issue

People in my game have been telling me their wins have been decreased by ten or them having no wins completely. Now, I did a fix, which was an auto save system that ran every 120 seconds and saved the player data to a backup data store. If the regular data isn’t loaded correctly, it’ll load the backup data. But I think sometimes the backup data wasn’t loading either. Here’s my data code: (note to ignore half of the stuff in this, since most of it is just game stuff, which has nothing to do with my problem)

game.Players.PlayerAdded:Connect(function(player)
player.CharacterAdded:Connect(function(char)
if char:FindFirstChild(“Right Arm”) then
local m = Instance.new(“Motor6D”,char[“Right Arm”])
m.Part0 = char[“Right Arm”]
end
char.Humanoid.Died:Connect(function()
if Values.Game.Value == true then
if Values.GameTimer.Value >= 345 then
local tag = Instance.new(“StringValue”,player)
tag.Name = “Creeper”
end
if player.Team == game.Teams.Humans then
Remotes.DiedChatMessage:FireAllClients(player.Name)
end
end
end)
if Values.Game.Value == true then
player.Team = game.Teams.Creepers
local chance = math.random(1,25)
if MS:UserOwnsGamePassAsync(player.UserId,passes.VIP) or player:FindFirstChild(“VIP”) then
chance = math.random(1,15)
end
if chance == 1 and debounce == false then
debounce = true

			local points = {}

			wait()

			local charged = game.ServerStorage.Characters["Charged Creeper"]:Clone()
			charged.Name = player.Name
			player.Character = charged

			charged.Parent = workspace

			wait()

			local random = Random.new()
			charged.HumanoidRootPart.CFrame = workspace.Map.Spawns:GetChildren()[random:NextInteger(1,#workspace.Map.Spawns:GetChildren())].CFrame + Vector3.new(0,3,0)

			local startPosition = charged.HumanoidRootPart.Position
			local endPosition = charged.HumanoidRootPart.Position + Vector3.new(0,200,0)

			local tries = 4

			repeat wait()
				tries -= 1
				for i = 0, 30 do
					local offset = Vector3.new(math.random(-5,5),0,math.random(-5,5))
					if i == 0 or i == 30 then
						offset = Vector3.new(0,0,0)
					end

					local lightning = Instance.new("Part",workspace.Items)
					lightning.Name = "Lightning"
					lightning.Anchored = true
					lightning.CanCollide = false
					lightning.Size = Vector3.new(0.5,0.5,0.5)
					lightning.Material = Enum.Material.Neon
					lightning.BrickColor = BrickColor.new("Medium blue")
					lightning.Position =  startPosition + (endPosition - startPosition).Unit * i * (endPosition - startPosition).Magnitude/30 + offset
					game.Debris:AddItem(lightning,1)
					points[#points+1] = lightning
				end

				for i = 1,#points do
					if points[i+1] ~= nil then
						draw(points[i],points[i+1])
					end
				end
			until tries == 0
			Sounds.Thunder:Play()
			Sounds.LightningBolt:Play()
			Remotes.FlashScreen:FireAllClients(false,true,false)
			debounce = false
		end
		if char:FindFirstChild("Health") then
			char.Health:Destroy()
		end
		wait()
		char.Humanoid.Changed:Connect(function()
			if char.Humanoid.Health == 0 and not player:FindFirstChild("Died") then
				local tag = Instance.new("StringValue",player)
				tag.Name = "Died"
				game.Debris:AddItem(tag,game.Players.RespawnTime)
				wait(game.Players.RespawnTime)
				if char and game.Players:FindFirstChild(player.Name) then
					player:LoadCharacter()
				end
			end
		end)
		MakeVisible:FireClient(player,"ExplodeButton",true)
		MakeVisible:FireClient(player,"ExplodeButtonUnder",true)
	else
		player.DevCameraOcclusionMode = Enum.DevCameraOcclusionMode.Invisicam
	end
end)

local leaderstats = Instance.new("Folder",player)
leaderstats.Name = "leaderstats"

local Settings = Instance.new("Folder",player)
Settings.Name = "Settings"

local Flashes = Instance.new("BoolValue",Settings)
Flashes.Name = "Flashes"
Flashes.Value = true

local Particles = Instance.new("BoolValue",Settings)
Particles.Name = "Particles"
Particles.Value = true

local Sounds = Instance.new("BoolValue",Settings)
Sounds.Name = "Sounds"
Sounds.Value = true

local Gunpowder = Instance.new("IntValue",leaderstats)
Gunpowder.Name = "Gunpowder"

local Wins = Instance.new("IntValue",leaderstats)
Wins.Name = "Wins"

local Banned = Instance.new("BoolValue",player)
Banned.Name = "Banned"

local BlockAmounts = Instance.new("Folder",player)
BlockAmounts.Name = "BlockAmounts"

local SelectedBlock = Instance.new("Folder",player)
SelectedBlock.Name = "SelectedBlock"

local SelectedArmor = Instance.new("Folder",player)
SelectedArmor.Name = "SelectedArmor"

local Armor = Instance.new("Folder",player)
Armor.Name = "Armor"

local Weapons = Instance.new("Folder",player)
Weapons.Name = "Weapons"

local Items = Instance.new("Folder",player)
Items.Name = "Items"

local SelectedItems = Instance.new("Folder",player)
SelectedItems.Name = "SelectedItems"

local SelectedWeapons = Instance.new("Folder",player)
SelectedWeapons.Name = "SelectedWeapons"

local BoughtBlockAmounts = Instance.new("Folder",player)
BoughtBlockAmounts.Name = "BoughtBlockAmounts"

local BlockAmountsTable = {}
local BoughtBlockAmountsTable = {}

BlockAmountsTable.Wood = 70
BlockAmountsTable.Cobblestone = 35
BlockAmountsTable.Iron = 6
BlockAmountsTable.Obsidian = 0
BlockAmountsTable["Wood Log"] = 20
BlockAmountsTable.Cobweb = 0
BlockAmountsTable.Door = 0
BlockAmountsTable.Glass = 0
BlockAmountsTable.Scaffolding = 0
BlockAmountsTable.Glowstone = 2

BoughtBlockAmountsTable.Wood = 70
BoughtBlockAmountsTable.Cobblestone = 35
BoughtBlockAmountsTable.Iron = 6
BoughtBlockAmountsTable.Obsidian = 0
BoughtBlockAmountsTable["Wood Log"] = 20
BoughtBlockAmountsTable.Cobweb = 0
BoughtBlockAmountsTable.Door = 0
BoughtBlockAmountsTable.Glass = 0
BoughtBlockAmountsTable.Scaffolding = 0
BoughtBlockAmountsTable.Glowstone = 2

local data
local errorMessage

local armorAmount

local success, errorMessage = pcall(function()
	data = MainDataStore:GetAsync(player.UserId)
end)

if success and data then
	local pass = true
	for i, v in pairs(game.ReplicatedStorage.Tickets:GetChildren()) do
		if v.Value == player.Name then
			player.Banned.Value = false
			v:Destroy()
			pass = false
		end
	end
	if pass then
		if data.Banned then
			if data.Banned == true then
				player:Kick("You've been inevitably banned. Reason: skill issue")
			end
		end
	end

	Wins.Value = data.leaderstats.Wins

	if data.Settings then
		for i, v in pairs(data.Settings) do
			Settings[i].Value = v
		end
	end

	local sameRound = false

	if (data.JobId == game.JobId) then
		Gunpowder.Value = data.Gunpowder
		if Values.Round.Value == data.Round then
			sameRound = true
			for i, v in pairs(data.Blocks) do
				BlockAmountsTable[i] = v
			end
			if data.BoughtBlockAmounts then
				for i, v in pairs(data.BoughtBlockAmounts) do
					BoughtBlockAmountsTable[i] = v
				end
			end
		end

		if not sameRound and (MS:UserOwnsGamePassAsync(player.UserId,passes.VIP) or player:FindFirstChild("VIP")) then
			local ba = player.BlockAmounts
			local bba = player.BoughtBlockAmounts
			ba.Wood.Value = VIPPerks.Wood
			bba.Wood.Value = VIPPerks.Wood

			ba.Cobblestone.Value = VIPPerks.Cobblestone
			bba.Cobblestone.Value = VIPPerks.Cobblestone

			ba.Door.Value = VIPPerks.Door
			bba.Door.Value = VIPPerks.Door

			ba["Trap Door"].Value = VIPPerks["Trap Door"]
			bba["Trap Door"].Value = VIPPerks["Trap Door"]

			ba.Cobweb.Value = VIPPerks.Cobweb
			bba.Cobweb.Value = VIPPerks.Cobweb

			ba.Gold.Value = VIPPerks.Gold
			bba.Gold.Value = VIPPerks.Gold
		end

		if data.Armor then
			for i, v in pairs(data.Armor) do
				local clone = RS.Armor[i]:Clone()
				clone.Parent = Armor
				clone.Amount.Value = v
				armorAmount = v
			end
		end
		if data.SelectedArmor ~= "" then
			local clone = RS.Armor[data.SelectedArmor]:Clone()
			clone.Parent = Armor
			clone.Amount.Value = armorAmount
		end
		if data.Weapons then
			for i, v in pairs(data.Weapons) do
				RS.Weapons[v]:Clone().Parent = Weapons
			end
		end
		if data.SelectedWeapon ~= "" then
			RS.Weapons[data.SelectedWeapon]:Clone().Parent = SelectedWeapons
		end
		if data.Items then
			for i, v in pairs(data.Items) do
				local clone = RS.ItemWeapons[i]:Clone()
				clone.Parent = Items
				clone.Amount.Value = v
			end
		end
		if data.SelectedItems then
			for i, v in pairs(data.SelectedItems) do
				local clone = RS.ItemWeapons[i]:Clone()
				clone.Amount.Value = v
				clone.Parent = player.SelectedItems
			end
		end
	end
else
	local data
	local errorMessage

	local armorAmount

	local success, errorMessage = pcall(function()
		data = BackupDataStore:GetAsync(player.UserId)
	end)

	if data and success then
		local pass = true
		for i, v in pairs(game.ReplicatedStorage.Tickets:GetChildren()) do
			if v.Value == player.Name then
				player.Banned.Value = false
				v:Destroy()
				pass = false
			end
		end
		if pass then
			if data.Banned then
				if data.Banned == true then
					player:Kick("You've been inevitably banned. Reason: skill issue")
				end
			end
		end

		Wins.Value = data.leaderstats.Wins

		if data.Settings then
			for i, v in pairs(data.Settings) do
				Settings[i].Value = v
			end
		end

		if (data.JobId == game.JobId) then
			Gunpowder.Value = data.Gunpowder
			if Values.Round.Value == data.Round then
				for i, v in pairs(data.Blocks) do
					BlockAmountsTable[i] = v
				end
				if data.BoughtBlockAmounts then
					for i, v in pairs(data.BoughtBlockAmounts) do
						BlockAmountsTable[i] = v
					end
				end
			else
				local ba = player.BlockAmounts
				local bba = player.BoughtBlockAmounts
				ba.Wood.Value = VIPPerks.Wood
				bba.Wood.Value = VIPPerks.Wood

				ba.Cobblestone.Value = VIPPerks.Cobblestone
				bba.Cobblestone.Value = VIPPerks.Cobblestone

				ba.Door.Value = VIPPerks.Door
				bba.Door.Value = VIPPerks.Door

				ba["Trap Door"].Value = VIPPerks["Trap Door"]
				bba["Trap Door"].Value = VIPPerks["Trap Door"]

				ba.Cobweb.Value = VIPPerks.Cobweb
				bba.Cobweb.Value = VIPPerks.Cobweb

				ba.Gold.Value = VIPPerks.Gold
				bba.Gold.Value = VIPPerks.Gold
			end

			if data.Armor then
				for i, v in pairs(data.Armor) do
					local clone = RS.Armor[i]:Clone()
					clone.Parent = Armor
					clone.Amount.Value = v
					armorAmount = v
				end
			end
			if data.SelectedArmor ~= "" then
				local clone = RS.Armor[data.SelectedArmor]:Clone()
				clone.Parent = Armor
				clone.Amount.Value = armorAmount
			end
			if data.Weapons then
				for i, v in pairs(data.Weapons) do
					RS.Weapons[v]:Clone().Parent = Weapons
				end
			end
			if data.SelectedWeapon ~= "" then
				RS.Weapons[data.SelectedWeapon]:Clone().Parent = SelectedWeapons
			end
			if data.Items then
				for i, v in pairs(data.Items) do
					local clone = RS.ItemWeapons[i]:Clone()
					clone.Parent = Items
					clone.Amount.Value = v
				end
			end
			if data.SelectedItems then
				for i, v in pairs(data.SelectedItems) do
					local clone = RS.ItemWeapons[i]:Clone()
					clone.Amount.Value = v
					clone.Parent = player.SelectedItems
				end
			end
		end
	end
end

for i, v in pairs(Blocks:GetChildren()) do
	local val = Instance.new("IntValue")
	val.Name = v.Name
	val.Value = BlockAmountsTable[v.Name]
	val.Parent = BlockAmounts

	local val2 = Instance.new("IntValue")
	val2.Name = v.Name
	val2.Value = BoughtBlockAmountsTable[v.Name]
	val2.Parent = BoughtBlockAmounts
end
for i, v in pairs(BanList) do
	if (v == player.UserId) then
		player:Kick("Banned. If this was a false ban, appeal in the discord, or message me anywhere")
	end
end
spawn(function()
	while wait(120) do
		local data = {}

		data.leaderstats = {}
		data.Blocks = {}
		data.BoughtBlockAmounts = {}
		data.Armor = {}
		data.SelectedArmor = ""
		data.Weapons = {}
		data.SelectedWeapon = ""
		data.GamepassWeapons = {}
		data.Items = {}
		data.SelectedItems = {}

		data.Round = Values.Round.Value
		data.JobId = game.JobId

		data.Gunpowder = player.leaderstats.Gunpowder.Value

		data.Banned = player.Banned.Value

		local Settings = player.Settings
		data.Settings = {}
		data.Settings.Flashes = Settings.Flashes.Value
		data.Settings.Particles = Settings.Particles.Value
		data.Settings.Sounds = Settings.Sounds.Value

		for i, v in pairs(player.leaderstats:GetChildren()) do
			data.leaderstats[v.Name] = v.Value
		end

		for i, v in pairs(player.BlockAmounts:GetChildren()) do
			data.Blocks[v.Name] = v.Value
		end

		for i, v in pairs(player.BoughtBlockAmounts:GetChildren()) do
			data.BoughtBlockAmounts[v.Name] = v.Value
		end

		for i, v in pairs(player.Armor:GetChildren()) do
			data.Armor[v.Name] = v.Amount.Value
		end

		for i, v in pairs(player.SelectedArmor:GetChildren()) do
			data.SelectedArmor = v.Name
		end

		for i, v in pairs(player.Weapons:GetChildren()) do
			if not Gamepasses:FindFirstChild(v.Name) then
				table.insert(data.Weapons,v.Name)
			else
				table.insert(data.GamepassWeapons,v.Name)
			end
		end

		for i, v in pairs(player.SelectedWeapons:GetChildren()) do
			data.SelectedWeapon = v.Name
		end

		for i, v in pairs(player.Items:GetChildren()) do
			data.Items[v.Name] = v.Amount.Value
		end

		for i, v in pairs(player.SelectedItems:GetChildren()) do
			if not Gamepasses:FindFirstChild(v.Name) then
				data.SelectedItems[v.Name] = v.Amount.Value
			end
		end

		local success, errorMessage = pcall(function()
			BackupDataStore:SetAsync(player.UserId,data)
		end)

		if not success then
			warn(errorMessage)
		end
	end
end)

end)

game.Players.PlayerRemoving:Connect(function(player)
local data = {}

data.leaderstats = {}
data.Blocks = {}
data.BoughtBlockAmounts = {}
data.Armor = {}
data.SelectedArmor = ""
data.Weapons = {}
data.SelectedWeapon = ""
data.GamepassWeapons = {}
data.Items = {}
data.SelectedItems = {}

data.Round = Values.Round.Value
data.JobId = game.JobId

data.Gunpowder = player.leaderstats.Gunpowder.Value

data.Banned = player.Banned.Value

local Settings = player.Settings
data.Settings = {}
data.Settings.Flashes = Settings.Flashes.Value
data.Settings.Particles = Settings.Particles.Value
data.Settings.Sounds = Settings.Sounds.Value

for i, v in pairs(player.leaderstats:GetChildren()) do
	data.leaderstats[v.Name] = v.Value
end

for i, v in pairs(player.BlockAmounts:GetChildren()) do
	data.Blocks[v.Name] = v.Value
end

for i, v in pairs(player.BoughtBlockAmounts:GetChildren()) do
	data.BoughtBlockAmounts[v.Name] = v.Value
end

for i, v in pairs(player.Armor:GetChildren()) do
	data.Armor[v.Name] = v.Amount.Value
end

for i, v in pairs(player.SelectedArmor:GetChildren()) do
	data.SelectedArmor = v.Name
end

for i, v in pairs(player.Weapons:GetChildren()) do
	if not Gamepasses:FindFirstChild(v.Name) then
		table.insert(data.Weapons,v.Name)
	else
		table.insert(data.GamepassWeapons,v.Name)
	end
end

for i, v in pairs(player.SelectedWeapons:GetChildren()) do
	data.SelectedWeapon = v.Name
end

for i, v in pairs(player.Items:GetChildren()) do
	data.Items[v.Name] = v.Amount.Value
end

for i, v in pairs(player.SelectedItems:GetChildren()) do
	if not Gamepasses:FindFirstChild(v.Name) then
		data.SelectedItems[v.Name] = v.Amount.Value
	end
end

local success, errorMessage = pcall(function()
	MainDataStore:SetAsync(player.UserId,data)
end)

if not success then
	warn(errorMessage)
end

end)

So, I made this game thing called “a simulator game” and it has the same problem, but way worse. The data will refuse to load at all sometimes.

Anyways, when you save the data, are you getting any messages saying the request was added to queue? Does this only happen with the last player to leave the server?

1 Like

I just joined a server in my game and it was flooded with those messages. But the backup data only runs every 120 seconds so idk

I don’t really know where it’s coming from, I just know that’s the first problem. You should fix that first.

1 Like

someone recommended to me that I make a backup data store and then said they had no problems after that ever again. But I did see a message that said to maybe try to load the player’s data multiple times instead of just one attempt

That will just flood the datastore. I want to know what exactly is being saved.

When the player leaves, if they’re the last player in the server, their data won’t save on PlayerRemoved, so I used game:BindToClose() instead. That worked, but I still have the same issue. In my case I’d use a backup datastore, but in your case, the data isn’t saving.

1 Like

yeah it’s been loading correctly for me, but I just joined once and it gave me zero wins. This happened in studio it’s weird

That’s been happening to me a lot recently with “a simulator game”. I have a save button and that seems to be somewhat more reliable. I would add a cooldown for datastore writes as that seems to corrupt it, I guess, if sending a table.

Although I haven’t tried this, I think not listening to the PlayerRemoving event if there’s only one player in the server should work, and you’d need to code in an autosave system.

1 Like

yeah idk it’s so weird. This has got to be roblox’s issue though