Inventory System: How to go about to make sure only new items are added and old ones do not duplicate?

This sort of ‘issue’ has been bugging me for a few days already. Here’s an example scenario of my intended effect vs. what happens
Intention

  1. Player goes to buy an item from an NPC
  2. Item gets added into inventory folder
  3. New item shows up in the GUI and old ones are not duplicated

What actually happens

  1. Player goes to buy an item from an NPC
  2. Item gets added into inventory folder
  3. New item shows up in the GUI. However, the already existing items before get duplicated in the GUI

A side note, the item icons get duplicated, not the items in the data folder. It may not be big of an issue, but it gets really messy after a while

I have tried using a debounce. To no avail, it still doesn’t solve the issue.

Here is my current code

local player = game.Players.LocalPlayer
local replicatedstorage = game.ReplicatedStorage
local itembase = require(replicatedstorage.itemDatabase)
local inventory = player:WaitForChild("bag")
local items = {}
local buttons = {}
	--if player has stuff
	function search(location)
	for i,v in pairs(location:GetChildren()) do
		if v:isA("ValueBase") then
			table.insert(items,v)
		end
	end
end

function rfresh()
	for i,v in pairs(items) do
		local button = script.sample:Clone() 
		button.name.Value = v.Name
		button.Name = v.Name
		button.Parent = script.Parent
		for Index, Value in pairs(itembase) do
    if Value.name == button.name.Value then
		button:WaitForChild("itemimage").Image = Value.image
		end
		    end
		table.insert(buttons,button)
	end
end
	function backpackRefresh()
	search(inventory)
	rfresh()
	end
	
backpackRefresh()

inventory.ChildAdded:Connect(backpackRefresh)
inventory.ChildRemoved:Connect(backpackRefresh)
1 Like

At the moment I see some strange issues, specifically that the buttons array is added to but never used. It would make things a lot easier for us to provide support if you try to format your code to make it more readable, and document what each part of the code is doing.

That being said, the problem appears to stem from the fact that your search function is iterating through your inventory and adding everything inside it to your items array, possibly duplicating the array each time. I’m fairly certain this is the problem, but it’s hard to say without spending some more time pondering over the code since you haven’t documented what this function is supposed to do.

Please try to document the code and tell us your thought process, it will make it much easier for us to help you. It will also help you avoid the same mistakes next time, instead of blindly accepting a fix.

Apparently, you’re duplicating new buttons after every rfresh call. The backpack keeps on duplicating old ones because of faulty refresh, where the inventory is duplicating without any buttons removing.

Is it possible to iterate through the table using a for loop to check for duplicates?

That’s possible, but I’d suggest adding up new buttons for each new item added, rather than full refresh. In other words, after buying, create a button and add it. Do not use rfresh.

I’m currently doing something very similar for any inventory I create (actually creating one right now for a RPG)

I use 100% tables though

I keep two inventory tables, one on the server, and a clone on the client

I request the server inventory table on the client using a remote function when they join the game and then store this client side, and then make a new gui item slot

anytime the server inventory is updated(item added/remove/changed) I fire the client using a remote event telling which item has been added/removed/changed and update the client inventory table

from there I either create/remove/update a gui item slot depending on what the server sent

hope this helps, you could also change stuff around to apply this to folders

7 Likes

I re-did my ChildRemoved function, looping through the frame, then checking if there is a button with the item’s name, then removing that button and the item from the table. This is what I’ve tried

inventory.ChildRemoved:Connect(function(child)
	for i,v in pairs(script.Parent:GetChildren())do --get all buttons in the frame
		if child.Name == v.Name then
			table.remove(items,child)-- remove items in the table
			v:Destroy()
		end
	end
		end)

However, the issue is table.remove requires the value’s position which I don’t know how to get. How would I go about doing this?

1 Like

I made an inventory system and i used ChildAdded and ChildRemoved to update the inventory
ChildAdded is pretty simple i just made it loop through the positions for the item guis until it finds an empty slot then make it occupied then it uses break in the loop
and with the ChildRemoved i made it reload the inventory every time an item gets removed to keep them in a nice list with no gaps in the slots

It will not work if you are using only tables though
this is just the way i did mine but anyway i hope this helps.

Thanks for the guide! Finally got it to work properly!

1 Like