Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

My DataStore will not save?

I want it so Pebbles and Value both save and load, but when I join the game the output says 20:40:40.729 - ServerScriptService.leaderstats:21: attempt to index local 'SavedData' (a number value)

local DataStore = game:GetService("DataStoreService"):GetDataStore('RockData12')

game.Players.PlayerAdded:Connect(function(player)
	local key = player.UserId
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = 'leaderstats'
	leaderstats.Parent = player
	
	local Pebbles = Instance.new("IntValue")
	Pebbles.Name = 'Pebbles'
	Pebbles.Value = 0
	Pebbles.Parent = leaderstats
	
	local level = Instance.new("IntValue")
	level.Name = 'Level'
	level.Value = 0
	level.Parent = leaderstats
	
	local SavedData = DataStore:GetAsync(key)
	if SavedData then
		player.leaderstats.Pebbles.Value = SavedData[1]
		player.leaderstats.Level.Value = SavedData[2]
	else
		local StartValues = {Pebbles.Value, level.Value}
		DataStore:SetAsync(key, StartValues)
	end
end)

game.Players.PlayerRemoving:Connect(function(player)
	local key = player.UserId
	local CurrentValue = {player.leaderstats.Pebbles.Value}
	local LevelValue = {player.leaderstats.Level.Value}
	DataStore:SetAsync(key, CurrentValue[1], LevelValue[2])
end)

game:BindToClose(function()
	for i,v in pairs(game.Players:GetPlayers()) do
		if v then
		v:Kick()
	end
	end
	wait(3)
end)

1 comment

0

Do not forget to accept my answer if it helps out.

2 answers

✓ Accepted answer

The reason for your error is because SavedData is not a table, rather a number. You are attempting to index that number. Lua does not support indexing numbers. In your PlayerRemoving event listener you attempt to save more than one value. The third argument and so on will be discarded; only the second argument is saved. You should instead save a table. Instead of saving two individual tables, just store one table, specifically an array, like so:

DataStore:SetAsync(key, {
	player.leaderstats.Pebbles.Value,
	player.leaderstats.Level.Value
})

Think of arrays as mappings from 1...#array to arbitrary values. You can get the first element of the array with array[1], second element with array[2], and so on.

Example:

local arr = {"hello", "world"}
print(arr[1], arr[2]) --> hello    world

Index 1 in your case will be the pebbles value and index 2 is the level.

Now, your game:BindToClose() logic is not very great. You should read this tutorial on how to properly save your player's data.

I'm going to supplement incapaxx's answer with the following code:

local DataStore = game:GetService("DataStoreService"):GetDataStore('RockData12')

game.Players.PlayerAdded:Connect(function(player)
	local key = player.UserId
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = 'leaderstats'
	leaderstats.Parent = player
	
	local Pebbles = Instance.new("IntValue")
	Pebbles.Name = 'Pebbles'
	Pebbles.Value = 0
	Pebbles.Parent = leaderstats
	
	local level = Instance.new("IntValue")
	level.Name = 'Level'
	level.Value = 0
	level.Parent = leaderstats
	
	local SavedData = DataStore:GetAsync(key) or 0
	if SavedData then
		player.leaderstats.Pebbles.Value = SavedData[1]
		player.leaderstats.Level.Value = SavedData[2]
	else
		local StartValues = {Pebbles.Value, level.Value}
		DataStore:SetAsync(key, StartValues)
	end
end)

game.Players.PlayerRemoving:Connect(function(player)
	local key = player.UserId
	local CurrentValue = player.leaderstats.Pebbles.Value
	local LevelValue = player.leaderstats.Level.Value
	local SaveArray = {CurrentValue, LevelValue}
	DataStore:SetAsync(key, SaveArray)
end)
-- You can edit the BindToClose Function as needed from incapaxx's link
game:BindToClose(function()
	for i,v in pairs(game.Players:GetPlayers()) do
		if v then
			v:Kick()
		end
	end
	wait(3)
end)

I'm also just going to point out that when you wrote:

local LevelValue = {player.leaderstats.Level.Value}
DataStore:SetAsync(key, CurrentValue[1], LevelValue[2])

within the LevelValue Table, the placement of "player.leaderstats.Level.Value" is in the first position (thus it would be LevelValue[1] instead) However, since the arrays you provided are both only 1 variable long, they would cause an error when attempting to use setasync.

This discussion is preserved as it was. New answers, comments, and votes are closed.