Annoying datastore issue I can explain but can't fix

I’m totally lost to why it doesn’t save. Not sure where the error lies either, sadly…

local Scope = "Version1"

local DataStore = game:GetService("DataStoreService"):GetDataStore("Stats", Scope)
local Event = game:GetService("ReplicatedStorage"):FindFirstChild("Events"):FindFirstChild("DATASTORE_UPDATE")
local PlayerService = game:GetService("Players")
local Main_Folder = Instance.new("Folder")
Main_Folder.Name = "DataStore"
Main_Folder.Parent = game:GetService("ServerScriptService")

-- For datastore
local Queue = {}
local Cooldown = 6
local Debounce = false

local function Save()
	for e, v in pairs(Queue) do
		for k, x in pairs(v) do
			pcall(function()
				DataStore:SetAsync(e, {
					["Total Wins"] 			= x[1],
					["Total Deaths"]		= x[2],
					["Best Killstreak"]		= x[3]
				})
			end)
		end
	end
	Queue = {}
end

PlayerService.PlayerAdded:Connect(function(Player)
	local UserId = Player.UserId
	local PlayerName = Player.Name
	local Folder = Instance.new("Configuration")
	Folder.Name = PlayerName
	Folder.Parent = Main_Folder
	
	local Wins_Folder = Instance.new("IntValue")
	Wins_Folder.Name = "Total Wins"
	Wins_Folder.Parent = Folder
	
	local Deaths_Folder = Instance.new("IntValue")
	Deaths_Folder.Name = "Total Deaths"
	Deaths_Folder.Parent = Folder
	
	local Best_Killstreak_Folder = Instance.new("IntValue")
	Best_Killstreak_Folder.Name = "Best Killstreak"
	Best_Killstreak_Folder.Parent = Folder
	
	local SSS = game:GetService("ServerScriptService")
	local Folder = SSS:FindFirstChild("DataStore")
	
	wait(Cooldown)	
	
	--[[ > > > Loading stats < < < ]]--

	local succ1, err1 = pcall(function()
		local Score = DataStore:GetAsync(Player.UserId) or {
			0,
			0,
			0
		}
		Wins_Folder.Value = Score["Total Wins"]
		Deaths_Folder.Value = Score["Total Deaths"]
		Best_Killstreak_Folder.Value = Score["Best Killstreak"]
	end)
	
	if succ1 then
		print("Loaded data for", Player.Name)
	else
		print("Failed loading data for", Player.Name, ":", err1)
	end
	
	Event:FireClient(Player, Main_Folder:FindFirstChild(PlayerName):FindFirstChild("Total Wins").Value, "WINS")
	Event:FireClient(Player, Main_Folder:FindFirstChild(PlayerName):FindFirstChild("Total Deaths").Value, "DEATHS")
	Event:FireClient(Player, Main_Folder:FindFirstChild(PlayerName):FindFirstChild("Best Killstreak").Value, "KILLSTREAK")
	
	--[[ > > > Update KD when player joins < < < ]]--
	
	local Update_Wins = Main_Folder:FindFirstChild(Player.Name):FindFirstChild("Total Wins")
	local Update_Deaths = Main_Folder:FindFirstChild(PlayerName):FindFirstChild("Total Deaths")
	local updatekd = Update_Wins.Value / (Update_Deaths.Value == 0 and 1 or Update_Deaths.Value)
	Event:FireClient(Player, math.floor(updatekd * 100 + 0.5) / 100, "K/D RATIO")

	
	local Wins_Changed = Main_Folder:FindFirstChild(PlayerName):FindFirstChild("Total Wins")
	Wins_Changed:GetPropertyChangedSignal("Value"):Connect(function()
		Event:FireClient(Player, Wins_Changed.Value, "WINS")
		local Update = Main_Folder:FindFirstChild(PlayerName):FindFirstChild("Total Wins").Value
		local kd = Update / (Wins_Changed.Value == 0 and 1 or Wins_Changed.Value)
		Event:FireClient(Player, math.floor(kd * 100 + 0.5) / 100, "K/D RATIO")
	end)
	
	local Deaths_Changed = Main_Folder:FindFirstChild(PlayerName):FindFirstChild("Total Deaths")
	Deaths_Changed:GetPropertyChangedSignal("Value"):Connect(function()
		Event:FireClient(Player, Deaths_Changed.Value, "DEATHS")
		local Update = Main_Folder:FindFirstChild(PlayerName):FindFirstChild("Total Wins").Value
		local kd = Update / (Deaths_Changed.Value == 0 and 1 or Deaths_Changed.Value)
		Event:FireClient(Player, math.floor(kd * 100 + 0.5) / 100, "K/D RATIO")
	end)
	
	local Best_Killstreak_Changed = Main_Folder:FindFirstChild(PlayerName):FindFirstChild("Best Killstreak")
	Best_Killstreak_Changed:GetPropertyChangedSignal("Value"):Connect(function()
		Event:FireClient(Player, Best_Killstreak_Changed.Value, "KILLSTREAK")	
	end)
	
	--[[ > > > Saving stats < < < ]]--
	
	PlayerService.PlayerRemoving:Connect(function(Player)
		Queue[Player.UserId] = {
			Wins_Folder.Value,
			Deaths_Folder.Value,
			Best_Killstreak_Folder.Value
		}
		if Debounce then
			return
		end
		Debounce = true
		Save()
		wait(Cooldown)
		Debounce = false
	end)
	
	game:BindToClose(function()
		for _,v in pairs(PlayerService:GetPlayers()) do
			Queue[v.UserId] = {
				Wins_Folder.Value,
				Deaths_Folder.Value,
				Best_Killstreak_Folder.Value
			}
			if Debounce then
				return
			end
			Debounce = true
			Save()
			wait(Cooldown)
			Debounce = false
		end
	end)
end)

You wrap the entire code in

```

```

There could have been an issue whilst saving. You save data in protected mode, but you didnt make use of the return values of pcall. You do when loading, though.

1 Like

That’s not the problem though I believe…

Is the SetAsync yielding? Try printing something after the SetAsync.

[ServerScriptService.Leaderboard stats and DataStore handler.New datastore handler:21: attempt to index upvalue ‘x’ (a number value)] x3

Not sure that’s wrong though…

Could u tell me which line is line 21, so I can have a look at it…

Screenshot by Lightshot, here’s a screenshot of it

x isn’t a table, x is a number. That’s why it’s giving u that error.

2 Likes

But how do I get the values I store then?.. I’m lost lol

Don’t mind me please, here’s the fix btw:

local function Save()
	for e, v in pairs(Queue) do
		local succ, err = pcall(function()
			DataStore:SetAsync(e, {
				["Total Wins"] 			= v["Total Wins"],
				["Total Deaths"]		= v["Total Deaths"],
				["Best Killstreak"]		= v["Total Killstreak"]
			})
		end)
		if succ then
			print("Saved data for", e)
		else
			print(err)
		end
	end
	Queue = {}
end
for UserId, Stats in next, Queue do
	pcall(function()
		DataStore:SetAsync(e, {
			["Total Wins"] 			= Stats[1],
			["Total Deaths"]		= Stats[2],
			["Best Killstreak"]		= Stats[3]
		})
	end)
end

I’m aware, I would do it that way if I didn’t store it like this (easier to read):

Queue[v.UserId] = {
	["Total Wins"] 			= Wins_Folder.Value,
	["Total Deaths"]		= Deaths_Folder.Value,
	["Best Killstreak"]		= Best_Killstreak_Folder.Value
}

Oh, I saw this and thought u were storing it this way,

Queue[v.UserId] = {
	Wins_Folder.Value,
	Deaths_Folder.Value,
	Best_Killstreak_Folder.Value
}

My bad, did not update. But thanks for waking up my mind about the table. I was not aware as I’ve been awake for quite some time, haha. Finally found a solution