I've made an inventory system, but I want to save it with DataStore2 and I have no clue where to start

I’ve tried looking at the different posts on here but I just can’t seem to wrap my head around everything, so If someone could just explain how to save the player data, then load it when the players comes back and remove it when the leave would be awesome since I really need to get over this hump so I can finally get back to developing more things In my game.

What I’ve gotten so far

Video :

https://gyazo.com/af1479c115bf49cdb9a65ad4b7caefdf

2 Likes

It would be nice to know how it looks like under the hood.

The gif doesn’t tell us much about how the script is structured.

What do you mean by that my good sir?

Well, it’s an inventory so it’s structured like how an inventory would be structured all I need to know is how to save it and load it.

Could we see it? I really can’t help you if I don’t know how it’s structured, since datastore2 is, yknow, a module.

First, you’ll need to decide what structure you want to save your data in. You could use a dictionary to store all of their inventory and save that in a datastore if you’d like.
Basic use of DataStore2 is surprisingly easy (the key here is to remember that each store object is retrieved by using the module’s variable and two arguments: the store name and the player object):

DataStore2 = require(MODULE_PATH)
DataStore2.Combine("Main", "Inventory") -- This just prevents us from spamming Roblox with requests, i suggest you look at the documentation for more information.
game.Players.PlayerAdded:Connect(function(player)
    local inventoryStore = DataStore2("Inventory", player) -- Load our player's stored inventory
    local inventoryContents = inventoryStore:Get({}) -- Now you are left with the dictionary you stored there, with an empty dict being returned if none exists
end)

You should not save on player exit, simply updating your player’s inventory dictionary/datastructure when a change is made is enough:

inventoryStore:Set(inventoryContents)

This is super basic use but should suffice for saving/loading data for each player. I would strongly recommend visiting the docs at DataStore2 for further information, especially serialization which will allow you to sort data in structures like inventory dictionaries much more easily.

When the player picks up the weapon
→ Modules
local Pickupables = require(game.ReplicatedStorage.Pickupables)
local DataStore2 = require(game.ServerStorage.DataStore2)

Pickup.OnServerEvent:Connect(function(plr, item)
	local char = plr.Character
	local humrp = char:WaitForChild("HumanoidRootPart")
	
	--> Variables
	
	local Inventory = plr:WaitForChild("Inventory")

	
	for i,v in ipairs(Pickupables.Weapons) do
		if item and item.Name == v and (item.PrimaryPart.Position - humrp.Position).Magnitude <= 5 and item then
			if Inventory:FindFirstChild(item.Name) then
				
			elseif not Inventory:FindFirstChild(item.Name) then
				print("The player has just picked up a "..item.Name)
				item:Destroy()
			end
		end
	end
end)


Update.OnServerEvent:Connect(function(plr, item)
	local InventoryUI = plr.PlayerGui.Inventory.Outer.Inventory
	local Template = InventoryUI.Template:WaitForChild("ItemImage")
	if not InventoryUI:FindFirstChild(item.Name) then
		local itemclone = Template:Clone()
		itemclone.Visible = true
		itemclone.Parent = InventoryUI
		itemclone.Name = item.Name
		local Name = itemclone:FindFirstChild("ItemName")
		Name.Text = item.Name
	end
end)

Okay, so, your inventory system is directly just the gui then? To save in datastore2, you need to convert whatever data you want to save into a table (For clarity, strings and numbers work as well, but you really shouldn’t have single keys for those kinds of things. It would be inefficient.).

With datastore2, you can combine multiple tables under the same “key”. This is a vital part of DS2.

ds2.Combine("EXAMPLENAME", "lvl", "inventory", "money", "gamepasses", "ban")

Something like that. You combine each table you want to save. The first string you pass along is simply the name of the datastore. There is no need to change it other than for wiping players (or having multiple save files). Also multiple players can share the same name; it’s unique per player.

You may then load a single one of these tables by doing the following:

loadedstore = datastore2("lvl", player)

With this loaded store, you can hook it up to OnUpdate for it to, well, update your data whenever a request to modify this store is made.

loadedstore:OnUpdate(function(newvalue)
		--say for level, you would update the level number here.
		--for inventory, you would update their inventory.
	end)

Now instead of adding the new item via a script, you would add it in exclusively off of that onupdate function.

--if you want to add to the past value (negative numbers work as well)
--I am unsure how it works with tables
loadedstore:Increment(value)
--or, if you want to set it directly
loadedstore:Set(value)

Once you run one of those functions, the loaded store’s respective update function would run and, well, in your case, add an item to the gui.

Finally, there is also the :Get() function. You can pass in a value and that will be the default value it will be set as if it does not find a previous value. Something like:

print(moneystore:Get(100))--prints saved money, 100 if the player had no money before

If I remember correctly, :Get() will also run the update function. However, for the first time it is called, it will not. Citation needed here, I may be wrong.

Hopefully this helps!

1 Like

I still don’t understand how to save and set data and you said I can add the item off the onupdate function but you said your not sure how it works with tables and I’m saving a table, also you never explained anything about how to load the data and what to do if the player already has data and how to set that all up, but nice explanation of everything

I already knew the basics of how to combine and get the data store but you never really showed me how to load the data and I’m trying to save the inventory as the player gets the weapon they’ve picked up

:Get() is loading the data.
DS2 automatically saves everything as long as you update and add everything via those functions.
You pass tables into the loaded stores to save a table. :Get({}) would be an empty table as a default value, for instance.
If the player has data, it will simply load it.
It’s all in the post.

Could you show me example of this “:Get()”, It’d be greatly appreciated!

I have already in my first explanation of datastore2.

local ds2 = require(datastore2module)
local player = --player goes here
ds2.Combine("EXAMPLENAME", "lvl", "inventory")--only run once per server
local inventory = ds2("inventory", player)
inventory:OnUpdate(function(newvalue)
    --update your gui stuff here
end)
local defaultinventory = {"Sword"}
inventory:Get(defaultinventory)--inventory loaded as either their save or default inventory
--if it didn't find anything previously saved (do not worry about corrupted saves, ds2 knows the difference)

You can’t get player through a server script, DataStore2 is only able to be used on the server

That’s why I said “Player goes here”. There’s a bunch of ways to get a player on the server, like the playeradded event. This stuff is for you to figure out.

Wow, so it’s that simple? Well thanks man

Thanks for taking your time to help me we need more people like you

Make sure to mark your post as solved for future people who have the same issue

Hmm, it seems to be not working at all

local DataStore2 = require(game.ServerStorage.DataStore2)

local Defaults = {}

function Added(plr)
	
	local Inventory = Instance.new("Folder")
	Inventory.Parent = plr
	Inventory.Name = "Inventory"
	
	local InventoryStore = DataStore2("Inventory", plr)
	

	InventoryStore:Get(Defaults)

	
local function UpdateUI(plr)
	for _, item in pairs(Inventory:GetChildren()) do	
		if item then
			local InventoryUI = plr.PlayerGui:WaitForChild("Inventory").Outer.Inventory
			local Template = InventoryUI.Template:WaitForChild("ItemImage")
			local itemclone = Template:Clone()
			itemclone.Visible = true
			itemclone.Parent = InventoryUI
			itemclone.Name = item.Name
			local Name = itemclone:FindFirstChild("ItemName")
			Name.Text = item.Name
		end
	end
end



UpdateUI(plr)

end



game.Players.PlayerAdded:Connect(Added)