How do i store my inventory system into a data store?

Oh and i need to leave, i need to take a break from my computer, cya later

1 Like

So first setup the profile service.

[Use a tutorial - Video before reading this tho]
Once you setup that using a video, somewhere you will make a module script along the lines of:
image

This as stated in one of the vids would be where the baseline data would be. Here is a sniplet of mine:

local Template = {}
Template.CurrencyData = {
	Money = 0,
}
Template.LevelingData = {
	Level = 1,
	XP = 0,
	RXP = 1000
}

Template.SettingsData = {
	
}

return Template

Now to access the ProfileStore, there is a script called:
image
This script holds the phyiscal “Profiles” or Player Data for the entire server. To access you must get in the table of profiles inside the Manager:
image
In here, you also add functions such as Client reading (NOT EDITTING) and Write:

	return Manager.Profiles[Player].Data
end

local function RecursiveSearchAndEdit(Table, Index, Value, Set)
	for i,v in pairs(Table) do
		if i == Index then
			print(Table[i])
			if type(Table[i]) == "number" then
				if Set == true then
					Table[i] = Value
				else
					Table[i] += Value
				end
			elseif type(Table[i]) == "boolean" or type(Table[i]) == "string" then
				Table[i] = Value
			end
		end

		if typeof(v) == "table" then
			RecursiveSearchAndEdit(v,Index,Value,Set)
		end
	end
end

function Manager.Write(Player,Index,Value,Set)
	--Profile
	local ClientData = Manager.Profiles[Player].Data
	RecursiveSearchAndEdit(ClientData,Index,Value,Set)
	
	--Physical Value
	for i, Descendant in pairs(ClientsDataFolder:WaitForChild(Player.Name):GetDescendants()) do
		if Descendant.Name == Index then
			if type(Descendant.Value) == "number" then
				if Set == true then
					Descendant.Value = Value
				else
					Descendant.Value += Value
				end
			elseif type(Descendant.Value) == "boolean" or type(Descendant.Value) == "string" then
				Descendant.Value = Value
			end
		end
	end
end

--Connections
ReadDataRemote.OnServerInvoke = function(Player)
	return Manager.Read(Player)
end
1 Like

Ignore some of this code, just focus on the main parts
Cya!

2 Likes

Hello! Instead of storing instances, you could use HTTP Service to do JSONEncode on a table containing information about the item you want to store so that you can store it in Datastore as a string.

For example, if you wanted to store the name of an item and its value, you can do this.

local Item = {
 ["Name"] = "Apple",
 ["Value"] = 1
}

local toStore = game:GetService("HttpService"):JSONEncode(Item)

Then you can store toStore in Datastore.

To get the dictionary again, you can do

local decodedStore = game:GetService("HttpService"):JSONDecode(ItemInDatastore)

Hope this helped!

2 Likes

Even thats actually smart!

Read on HTTP and DSS too
*DSS - DataStoreService

1 Like

Hello!
I see you have already gotten A LOT of help by the previous people, but I just came here to tell my opinion.

So I think in roblox you can’t actually serialize data. Serialization is when you convert an object into plain text. The method we use to save data here isn’t serialization, we just take the main properties and store them in a table.

Like for example, if, let’s say you want to store the position of a part. (Suppose it’s moveable and a player moved it). You would just save the Part.Position or Part.CFrame value. You won’t actually serialize it. And suppose you have a building system, you would then store the BrickColor, CFrame, etc. etc. You get my point. (hopefully)

I’m not writing all the code because i’m lazy but it would be something like this
DISCLAIMER: THIS IS TRASH CODE, DO NOT USE THIS! IT IS ONLY FOR THE PURPOSE OF SHOWING MY POINT.

-- Saving the data
local data = {Part.Position, Part.Color}
Datastore:SetAsync(key, data)

-- Retrieving the data
local data = Datastore:GetAsync(key)
local partPosition = data[1] --It's a table, so we access the data by indexing the table
local partColor = data[2]

Part.Position = partPosition
Part.Color = partColor

So that’s basically it. My code is terrible, it doesn’t use pcalls or BindToClose, heck, it doesn’t even connect to the PlayerAdded or PlayerRemoved functions, but i hope this helps!

1 Like

Question, where do i add this into my line of code?

local DataStoreService = game:GetService("DataStoreService")
local DataStore = DataStoreService:GetDataStore("InventoryDataStore")

local TableToStore = {}
local Data = nil

function SaveData(Player, StoreStuff)
	
end

game.Players.PlayerAdded:Connect(function(Player)
	Player.PlayerGui.InventoryUI.CharacterFrame.CharacterList.Changed:Connect(function()
		for i, v in pairs(Player.PlayerGui.InventoryUI.CharacterFrame.CharacterList:GetChildren()) do
			if v:IsA("GuiButton") then
				local ButtonTable = {}
				table.insert(ButtonTable, v.Name)
				table.insert(ButtonTable, v.Text)
			end
		end
	end)
end)

game.Players.PlayerRemoving:Connect(function(Player)
	
end)

Hello, i’m back, i’m trying to see the other peoples solutions and idk if it’s gonna to work

1 Like

Hey friend, i think i did it, first of all i don’t know if this code will work, second of all, what do i write on the If Success and Data then on the player added function:

local DataStoreService = game:GetService("DataStoreService")
local DataStore = DataStoreService:GetDataStore("InventoryDataStore")

--local TableToStore = {}
local Data = nil

local ToStore = nil

function SaveData(Player)
	local DecodedStore = game:GetService("HttpService"):JSONDecode(ToStore)
	local Success, Err = pcall(function()
		DataStore:SetAsync(Player.UserId, DecodedStore)
	end)
	
	if Success then
		print("Data has been succefully saved!")
	else
		warn(Err)
	end
end

game.Players.PlayerAdded:Connect(function(Player)
	Player.PlayerGui:WaitForChild("InventoryUI").CharacterFrame.CharacterList.Changed:Connect(function()
		for i, v in pairs(Player.PlayerGui.InventoryUI.CharacterFrame.CharacterList:GetChildren()) do
			if v:IsA("GuiButton") then
				local Item = {
					["Name"] = v.Name
				}
				ToStore = game:GetService("HttpService"):JSONEncode(Item)
			end
		end
	end)
	
	local Success, Err = pcall(function()
		Data = DataStore:GetAsync(Player.UserId)
	end)
	
	if Success and Data then
		
	end
end)

game.Players.PlayerRemoving:Connect(function(Player)
	local Success, Err = pcall(function()
		SaveData(Player)
	end)
	
	if Success then
		print("Inventory saved!")
	else
		warn(Err)
	end
end)

Did the tutorial have the pcall?
edt: nvm ur not using profiles

1 Like

I think now that you have the data, you can start to use it pretty much.
(im not good with pcalls)

If Error Message does come, warn it in output and then retry it until success maybe?

Keep the player from loading into the game until success is reached, and dont reach the datastore method limits. Only launch another :GetAsync() when 5 seconds or 10 seconds are up after the last failed try.

1 Like

Well, for some reason, this is not working:

local Players = game.Players
local DSS = game:GetService("DataStoreService")
local Datastore = DSS:GetDataStore("InstanceSave")

local TableToSave = {}
local SaveInventory = game.ReplicatedStorage.Events.SaveInventory

local CharacterList = nil

local Data = nil

function SaveData(Player)
	local Success, Err = pcall(function()
		Datastore:SetAsync(Player.UserId, TableToSave)
	end)
	
	if Success then
		print("Inventory saved!")
	else
		print("Inventory was not saved :(")
		warn(Err)
	end
end

game.Players.PlayerRemoving:Connect(function(Player)
	for _, Button in pairs(CharacterList:GetChildren()) do
		if Button:IsA("GuiButton") then
			table.insert(Button)

			SaveData(Player)
		end
	end
end)

game.Players.PlayerAdded:Connect(function(Player)
	local Success, Err = pcall(function()
		Data = Datastore:GetAsync(Player.UserId)
	end)
	
	CharacterList = Player.PlayerGui:WaitForChild("InventoryUI").CharacterFrame.CharacterList
	
	if Success and Data then
		for _, Child in pairs(TableToSave) do
			Child.Parent = Player.PlayerGui.InventoryUI.CharacterFrame.CharacterList
		end
	end
end)

--[[SaveInventory.OnServerEvent:Connect(function(Player, CharacterListFrame)
	for _, Button in pairs(CharacterListFrame:GetChildren()) do
		if Button:IsA("GuiButton") then
			table.insert(Button)
			
			SaveData(Player)
		end
	end
end)--]]

Edit: i actually reworked the whole script lol

1 Like