My Datastore script only loads the data once, I need help finding why

So I was testing making an inventory system and saving it, I made four boxes and when I click one of the boxes I get a tool (the box itself) then when I leave and join back the data is save and loads the tool I got when clicking the box, but when I leave and join back it looks like the inventory table is empty even tho when loading data I add the items name back to the table.

Server Script:

local Players = game:GetService("Players")
local DataStoreService = game:GetService("DataStoreService")
local InventoryManager = require(script.PlayerClasses.Inventory)
local DataManager = require(script.DataStore.DataStoreManager)

local PlayersDataStore = DataStoreService:GetDataStore("PlayersDataStore")

local saveInterval = 300

function saveData(Player)
	local PlayerInventory = InventoryManager.New(Player)

	local data = {}

	for i, item in pairs(PlayerInventory) do
		table.insert(data, item)
	end

	local DataEncode = DataManager.Encode(Player, data)

	if PlayerInventory then
		local success, errorMessage = pcall(function()
			PlayersDataStore:SetAsync(tostring(Player.UserId), DataEncode)
		end)

		if not success then
			warn("Error saving data for player " .. Player.Name .. ": " .. errorMessage)
		end
	end
end

function loadData(Player)
	local success, errorMessage = pcall(function()
		local data = PlayersDataStore:GetAsync(tostring(Player.UserId))

		if data then
			local dataDecode = DataManager.Decode(Player, data)
			local PlayerInventory = InventoryManager.New(Player)

			PlayerInventory:ClearInventory()

			for _, itemName in ipairs(dataDecode) do
				local itemClone = game.ReplicatedStorage.Items:FindFirstChild(itemName)
				if itemClone then
					itemClone = itemClone:Clone()
					itemClone.Parent = Player.Backpack
					PlayerInventory:AddItem(itemClone)
				else
					warn("Item not found: " .. itemName)
				end
			end
		end
	end)

	if not success then
		warn("Error loading data for player " .. Player.Name .. ": " .. errorMessage)
	end
end

Players.PlayerAdded:Connect(function(Player)
	if not InventoryManager.GetInventory(Player) then
		local PlayerInventory = InventoryManager.New(Player)
		print(PlayerInventory.GetInventory(Player))
		loadData(Player)
		print(PlayerInventory.GetInventory(Player))
	end
end)

Players.PlayerRemoving:Connect(function(Player)
	local PlayerInventory = InventoryManager.New(Player)
	print(PlayerInventory.GetInventory(Player))
	saveData(Player)
	print(PlayerInventory.GetInventory(Player))
end)

Inventory Module Script:

local Inventory = {}
Inventory.__index = Inventory

local PlayerInventories = {}

function Inventory.New(Player)
	local PlayerInventory = PlayerInventories[tostring(Player.UserId)]

	if not PlayerInventory then
		PlayerInventory = {}
		setmetatable(PlayerInventory, Inventory)
		PlayerInventories[tostring(Player.UserId)] = PlayerInventory
	end

	return PlayerInventory
end

function Inventory:AddItem(Item)
	table.insert(self, Item)
end

function Inventory:RemoveItem(Item)
	for i, item in ipairs(self) do
		if item == Item then
			table.remove(self, i)
			break
		end
	end
end

function Inventory.GetInventory(Player)
	if PlayerInventories[Player.UserId] then
		return PlayerInventories[Player.UserId]
	end
end

function Inventory:ClearInventory()
	for i, item in ipairs(self) do
		item:Destroy()
	end
	
	for k in pairs(self) do
		self[k] = nil
	end
end

return Inventory

DataStore Module Script:

local DataManager = {}
DataManager.__index = DataManager

local HTTPService = game:GetService("HttpService")

local PlayersDatabase = {}

function DataManager.New(Player)
	local PlayerData = PlayersDatabase[Player.UserId]

	if not PlayerData then
		PlayerData = {}
		PlayersDatabase[Player.UserId] = PlayerData
	end

	local self = setmetatable({}, DataManager)
	PlayerData.Data = self
	return self
end

function DataManager.Decode(Player, Table)
	if type(Table) == "string" then
		local DecodeTable = HTTPService:JSONDecode(Table)
		return DecodeTable
	else
		return {}
	end
end

function DataManager.Encode(Player, Table)
	if type(Table) == "table" then
		local EncodeTable = HTTPService:JSONEncode(Table)
		return EncodeTable
	end
end

return DataManager

Boxes Script:

local BoxesFolder = script.Parent
local RS = game:GetService("ReplicatedStorage")

local InventoryManager = require(game:GetService("ServerScriptService"):WaitForChild("Server"):WaitForChild("PlayerClasses"):WaitForChild("Inventory"))

for _, box in pairs(BoxesFolder:GetChildren()) do
	if box:IsA("Part") then
		local CD = Instance.new("ClickDetector")
		CD.Parent = box

		CD.MouseClick:Connect(function(Player)
			if not Player.Backpack:FindFirstChild(box.Name) then
				local Tool = RS:WaitForChild("Items"):WaitForChild(box.Name):Clone()
				Tool.Parent = Player.Backpack

				local PlayerInventory = InventoryManager.New(Player)
				PlayerInventory:AddItem(box.Name)
				
			else
				print("Already Have Item")
			end
		end)
	end
end


Screenshot 2023-09-24 134550
Screenshot 2023-09-24 134555

I found the issue, I just needed to make a table inside the Encode Function and turn the values of the Player’s Inventory into a string and insert it into the Encode Table to then encode it.

DataStore Module Script ^^^

function DataManager.Encode(Player, Table)
	if Table ~= nil then
		
		local TableToEncode = {}

		for _, item in pairs(Table) do
			table.insert(TableToEncode, tostring(item))
		end

		local EncodeTable = HTTPService:JSONEncode(TableToEncode)
		return EncodeTable
	else
		return {}
	end
end
1 Like

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