Hello,

I've got a strange problem with my DataStore. :)

I have two DataStore serverscripts, one for the Leaderstats, one for the Inventory. There are zero problems with the Leaderstats script. As for the Inventory one, it works just fine in Studio, and when testing it with my account on the site, it works fine, data is retained. However, when I tested the game with another account, the alt account's Inventory did not save, but the Leaderstats did.

I've marked the errors below for Line 53 and Line 108 for where the errors appear, which are:

ServerScriptStorage.ToolsDataStore:53: attempt to get length of a nil value Stack Begin Script 'ServerScriptStorage.ToolsDataStore, Line 53 - global loadData Script 'ServerScriptStorage.ToolsDataStore, Line 108 Stack End

The errors the above lines appear on are:

for x = 1, #data.tbl_1 do -- Where the error pops up for Line 53

and

loadData(Player) -- Where the other error appears for Line 108

I've never seen this error, and can't understand why it would appear for one account, but not the other? Why is one account able to load their Inventory, but the other is not?

I'm not asking anyone to re-write my script, as far as I can tell, the script should be working fine, as it does for at least one account. I've marked the two lines, 53 and 108, that the error lines reference. The full script is below:

local module = {}
local DataStoreService = game:GetService("DataStoreService")
local InventoryItems = DataStoreService:GetDataStore("XXXXXX")
local ToolGiverCheck = require(script.ToolGiverCheck)

datastore_success = {}

hasValues = require(script.HasValues)

AUTOSAVE_INTERVAL = 120
DATASTORE_RETRIES = 3

function createData()
	local data = {}
	data.tbl_1 = {}
	data.tbl_2 = {}
	
	for x = 1, #hasValues do
		table.insert(data.tbl_1, hasValues[x])
		data[hasValues[x]] = false
	end
	
	return data
end

function dataStoreAttempt(dataStoreFunction)
	local tries = 0
	local success = false
	local data = nil
	repeat
		tries = tries + 1
		success = pcall(function() data = dataStoreFunction() end)
		if not success then wait(1) end
	until tries == DATASTORE_RETRIES or success
	
	return success, data
end

function loadData(Player)
	local Key = "PlayerIdNum-"..Player.UserId.."_ToolItems"
	local InvData = Player:WaitForChild("Inventory")
	
	local success, data = dataStoreAttempt(function()
		 return InventoryItems:GetAsync(Key)
	end)
	
	if success then
		if not data then
			data = createData()
			
			print("Successfully created new inventory data for player '" .. Player.Name .. "'  (" .. Player.UserId .. ")")
		else
			for x = 1, #data.tbl_1 do  -- FIRST ERROR APPEARS
				local value = data.tbl_1[x]
				local inv_value = InvData:WaitForChild(value)
				
				inv_value.Value = data.tbl_2[value]
			end
			
			print("Successfully loaded inventory data for player '" .. Player.Name .. "'  (" .. Player.UserId .. ")")
		end
		
		datastore_success["id_"..Player.UserId] = true
	else
		print("Failed to load inventory data for player '" .. Player.Name .. "'  (" .. Player.UserId .. ")")
	end
end

function saveData(Player)
	if datastore_success["id_"..Player.UserId] then
		local Key = "PlayerIdNum-"..Player.UserId.."_ToolItems"
		local InvData = Player:WaitForChild("Inventory")
		local data = createData()
		
		for x = 1, #data.tbl_1 do
			local value = data.tbl_1[x]
			local inv_value = InvData:WaitForChild(value)
			
			data.tbl_2[value] = inv_value.Value
		end
		
		local success, data = dataStoreAttempt(function()
			InventoryItems:SetAsync(Key, data)
		end)
		
		if not success then
			print("Failed to save inventory data for player '" .. Player.Name .. "'  (" .. Player.UserId .. ")")
		else
			print("Successfully saved inventory data for player '" .. Player.Name .. "'  (" .. Player.UserId .. ")")
		end
	end
end

game.Players.PlayerAdded:Connect(function(Player) -- Inventory
	local tnew = Instance.new
	
	local ts = tnew("Folder")
	ts.Name = "Inventory"
	ts.Parent = Player
	
	for x = 1, #hasValues do
		local tool = tnew("BoolValue")
		tool.Name = hasValues[x]
		tool.Value = false
		tool.Parent = ts
	end

	loadData(Player) --SECOND ERROR
	
	repeat wait() until Player.Character
end)

game.Players.PlayerRemoving:Connect(function(Player)
	saveData(Player)
	
	datastore_success["id_"..Player.UserId] = nil
end)
 
spawn(function()
    while wait(AUTOSAVE_INTERVAL) do
        for i, Player in pairs (game:GetService("Players"):GetChildren()) do
            print("Auto-saving " .. Player.Name .. "'s inventory data")
			saveData(Player)
        end
    end
end)


return module

Here's a snippet of the "HasValues" sub-script it draws from, which has 900 total items inside:

return {
 "Song144",
 "Song145",
"VIPAccessPass",
 "FirstTimePlayer"
 }

I confess, I'm not too sure why one account's data is being saved, but the other is not.

I get that the nil value would imply there's nothing inside the table, but that doesn't make sense, as it should still save, even if none of the values from inside the table are true or not.

I'd appreciate any advice on how to correct whatever may be the issue. :) Many thanks!

2 comments

1

Might be something to do with the naming conventions of the DataStoreService, I try and keep my Keys for DataStore entries as simple as possible.... But honestly I don't know why this wouldn't be working and I only really took a look at the first error.

0

@Pejorem - it appears you're correct! I had a key in my Inventory DataStore named the same as my Leaderstats DataStore. That seems to have been the cause of the issues.