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

Saving amount of items player has?

This is my current invenotry saving/loading script

local inv = game:GetService("DataStoreService"):GetDataStore("inv_01")
game.Players.PlayerAdded:Connect(function(plr)
	local items = inv:GetAsync(plr.UserId) or {}
	local inventory = Instance.new("Folder",plr)
	inventory.Name = "Inventory"
	--Load items
	for i,v in pairs(items) do
		if game.ReplicatedStorage.Items:FindFirstChild(v) ~= nil then
			game.ReplicatedStorage.Items[v]:Clone().Parent = inventory
		end
	end
	--Save inventory when item added
	inventory.ChildAdded:Connect(function(c)
		items[#items+1] = c.Name
		inv:SetAsync(plr.UserId, items)
	end)
	--save inventory when item removed
	inventory.ChildRemoved:Connect(function(c)
		items = {}
		for i,v in pairs(inventory:GetChildren()) do
			items[i] = v.Name
		end
		inv:SetAsync(plr.UserId, items)
	end)
	
end)


Not asking for an entire script just a way.

7 comments

0

What? Can you explain the error?

0

There is no error, but I need a kind of way to store the value of an item someone has. For example: Player1 has 21 Items.

0

Let's say you want to leave in value a texture saved?

0

Not sure if I'm being clear enough but what I do mean is I want to save the quantity/amount of an item someone has

0

Huum, this script not saving itens correct? if no i can post a script that save.

0

no the script itself saves items properly but I need to know how I can make it so it will save the ammount of that item the players have. Like I said before. So again for example when someone picks up an item they already have it would show "item x2" meaning they have 2 of item

0

I'm looking for this too lol. i try to make this~

2 answers

I worked on an inventory system not too long ago, I can think of 2 solutions for your problem

EDIT: I made a test place that has a basic item give shop and date store setup(Uncopylocked) Inventory Data Store Test Place

  1. Use the name of the item as the name to save Make it an IntValue and use the value as the number of the item

  2. The way I did it a while ago since I had multiple things to save for the item was placing values inside of the item and saving/loading those

Example for #2

This will save all the values into a table and then load them 1 by 1 into your inventory folder

It automatically saves every 300 seconds with a 30 second delay between players

I am not very good at coding so I'm sure there are more efficient ways but this is my way of doing it

local DSS = game:GetService("DataStoreService")
local set = "example1"
local invds = DSS:GetDataStore("inventory"..set)

game.Players.PlayerAdded:connect(function(player)
	
	local key = tostring(player.UserId..set)

	local inventory = Instance.new("Folder", player)
	inventory.Name = "inventory"

	if invds:GetAsync(key) ~= nil then
		local tablea1 = invds:GetAsync(key)
		for k,v in pairs(tablea1) do
			local itemname = Instance.new("StringValue",player.inventory)
			itemname.Name = v[1]
			local itemlevel = Instance.new("IntValue",itemname)
			itemlevel.Value = v[2]
			itemlevel.Name = "Level"
			local itemamount = Instance.new("IntValue",itemname)
			itemamount.Value = v[3]
			itemamount.Name = "Amount"
		end
	else
		local iddata = {}
		invds:SetAsync(key, iddata)
	end

end)

function SaveData(player)

	local key = tostring(player.UserId..set)

	invds:UpdateAsync(key, function(OldValue)
		if type(OldValue) == "table" then
			local tablea1 = {}
			for k,v in pairs(player.inventory:GetChildren()) do
				local tabledata = {v.Name, v["Level"].Value, v["Amount"].Value}
				table.insert(tablea1, tabledata)
			end
			OldValue = tablea1
		end
		return OldValue
	end)

end

game.Players.PlayerRemoving:Connect(SaveData)


while wait(300) do
	for k,v in pairs(game.Players:GetChildren()) do
		wait(30)
		SaveData(v)
	end
end

4 comments

0

I'll test both methods and get back to you with the result of it

0

if you encounter any errors just reply here or send me a message and I'll get back to you asap!

0

Alright so here's an error I got with the 2nd option while testing. Apparently Id is an "unknown global" not sure if this is because the above code may be a snippet from something else or I'm doing something wrong

0

ah my mistake use the code now and it should be good, I forgot to change a variable

The short answer, with least modification to your existing system is to simply save a slightly more complex data struct. For example, instead of just saving the array of names, save a small table. So this:

items[i] = v.Name

Might become something like this:

items[i] = {
	name = itemName,
	quantity = quantityOfItem,
}

How you track the quantity of the item in memory on the server is another matter. I would recommend just using a dictionary keyed with the item name. Don't make multiple copies of the actual items, that is a huge waste of memory. In fact, cloning the items into the player's inventory folder is probably already wasteful. The items probably don't need to exist until you are ready to parent them to something in Workspace or ReplicatedStorage. It's probably best to do all of this inventory stuff just in a table, and only worry about instantiating the actual items when they need to be spawned in world or at least made available to clients.

A side note, you will find a lot of examples and many inventory systems that unpack datastore data into folders of value objects. This is mostly a legacy from the times before RemoteEvents, when this was a way to get values replicated to clients. This a horribly memory-inefficient way to store simple data, equally terrible for read/write performance--recursive search of hierarchical structure where a simple O(1) dictionary could be used--and no longer a good practice for sending data server-to-client. Use tables in server Scripts, and RemoteEvents to communicate values between server and clients.

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