Best practice for storing and getting item data for a inventory system

Hello, I have a basic inventory system in place that adds and removes items. My only issue is I’m unsure about the best way to store and handle my item data. I want to create a system like the following:

local Inventory -- requires the inventory module i have
local Items -- something that has returns all items in a table
Inventory:AddItem(Items["Wooden Blade"])

In my current system “Items” is module script that has a functions which creates and returns a table of the item’s description, example:

function Item:Apple()
	local itemData = {
		Name = "Apple", 
		Desc = "It probably came from a healthy tree.", 
		Amount = 1, 
		Type = "Material", 
		Picture = 137510460,
	}

	return itemData
end

Yes this system works but would it not be better to have a table that has the details already stored, so one could simply use that table with all the item data to get an item? (Like the example above)

Truly I would like to create a class of “Item” and return its data like this:

function Item:Wood()
	return Item("Wood", "Plain wood.", 1, "Material", 7466356907)
end

Although I think this is kind of harder to read I would like to create the actual class, than just send a table. This will also allow me to extend from my other class “Gear” from items appropriately. Down below is the full code and examples, any suggestions would be greatly appreciated.

KidNooblysProblem.rbxl (47.4 KB)

6 Likes

I would personally just have a module which returns a table that stores all the item data instead of having individual functions that return the item data. You could use an id as an index to find the itemData, or just loop through the table and find the itemData with a target Name.

3 Likes

I like the idea and an ID will allow me to have multiple items of the same name. Do you think I should still create item classes in the item data table or use:

local items = {
	[1] =  {
		Name = "Apple", 
		Desc = "It probably came from a healthy tree.", 
		Amount = 1, 
		Type = "Material", 
		Picture = 137510460,
	}
}
2 Likes

I would personally do that. You can still have classes if you want through a custom Enum system, and have a class property of each item. This system is more modular and also cleaner!

2 Likes

Ah could you please give me and example of what you have just exampled, I’m a little puzzled.

1 Like

I made one long back and I remember having an ItemData module with all the item info for eg:

return {
    Apple = {
        Desc = "It probably came from a healthy tree.", 
		Type = "Material", 
		Picture = 137510460,
    }
}

And what I would do is have an Inventory:AddItem function which takes in the item data and amount (default 1).

Inventory:AddItem(ItemData.Apple, 64)
3 Likes

A custom “enum” would just allow you to have generic properties for an item. For example, all fruit could be of a Fruit item class which would have generic properties that every fruit should have, then separately have other properties which are unique to the item. I will provide a very basic example to hopefully aid you in understanding:

return {
  ["Apple"] = {
    name = "name",
    desc = "description here",
    type = "whatever type here",
    icon = 0,
    class = Classes.Fruit,
  }
}

Keep in mind that Classes would refer to a module script that returns information about each individual class.

2 Likes

Also I’m not sure exactly what data you are saving as the inventory, but I do not recommend storing ALL information about an item in the player’s data. Instead, only save the unique id of the item alongside the amount of the item the player has. This allows you to change properties of the item in the future, and also prevents saving unnecessary data in the player’s data.

You would fetch the item data via a module script using the id stored in the player’s data to find the item you are looking for.

2 Likes

I hadn’t noticed until now that I technically do not need to store the Amount inside of the item data, but rather i could have the inventory module create an amount property.

Also thank you for your recommendation about having all the item data in one place, through the example you’ve given me, it would be easy to do so.

2 Likes

This is a VERY good idea to cut down on the amount of data being stored tysm!

Also regarding the code example, thanks to your class idea, it would be a great way of organising the data and also allows me to not repeat myself as much. This would also mean that I can create the extra properties equipment would need through the Classes module script.

return {
    Apple = {
        Desc = "It probably came from a healthy tree.", 
		Type = "Material", 
		Icon = 137510460,
        Class = Classes.Fruit
    }
}

Previously you had mentioned item ID’s

I do not plan on having any items that consist of the same name so I’m currently unsure how item IDs could benefit the current system (going off the assumption you meant each item would have a unique ID to differentiate from items with the same name). Did you mean something else? Or is there another benefit of item IDs I am simply not seeing here?

1 Like

Alongside being able to have multiple items of the same name, using item IDs basically ensures there is a constant way you can always find a specific item. For instance if you made a typo in an item name and saved the item data using that item name in the player data, you could not go back and change the item name without those players losing access to that item with ease as the item with the old item name no longer exists. For example:
If I had an item called ‘Appl’ and player1 has this stored in their inventory, changing the item name to ‘Apple’ and pushing this to the game would mean that the item stored in player1’s inventory known as ‘Appl’ technically no longer exists, and would no longer have any item data. However using an item id would mean I could store this item using a unique id (for example item_1 but this can be changed to a more meaningful id) and have a separate displayName property stored in the item’s data instead of the player’s inventory data. This means that I can change the name of ‘Appl’ to ‘Apple’, but still use the item id of item_1 to find the item data for the item stored in the player’s inventory.

I hope this made more sense, I’m not really too sure how to explain it properly? But by all means if you do not think this will be an issue for you, item ids are not necessary at all.

2 Likes

I see that is a VERY good point that I have overlooked. Now I do want to add IDs.

Assuming I save the player data like you had suggested, saving the item ID as well as the amount of the item, would it be okay to save the item’s ID as a property, like so:

return {
    Apple = {
        Desc = "It probably came from a healthy tree.", 
		Type = "Material", 
		Icon = 137510460,
        Class = Classes.Fruit,
        ID = "Material_1"
    }
}

But considering during the player’s load the script would have to find the item based on its ID and not its name; a system that can easily find the ID without having to iterate throughout the entire list of items should be in place. Especially considering that the table will eventually become very large.

Just now I was thinking of a system that would use the first part of the ID (before the “_”) to find the itemData, but to do this I’d need to create individual tables of each type with the same itemData in them and that seems messy.

return {
    Material_1 = {
        Name = "Apple",
        Desc = "It probably came from a healthy tree.", 
		Type = "Material", 
		Icon = 137510460,
        Class = Classes.Fruit,
    }
}

I wouldn’t really want to do something like the following above because that would mean when I want to add an item I’d have to do Inventory:AddItem(ItemData.Material_1, 64).

… In the case above since I ideally want to address the item by it’s Name I could iterate through the table to get the item via name but, agh that also sounds messy.

Any suggestions would be greatly appreciated.

1 Like

… Or I guess this would be better?

return {
    Apple = {
        Name = "Apple",
        Desc = "It probably came from a healthy tree.", 
		Type = "Material", 
		Icon = 137510460,
        Class = Classes.Fruit,
    }
}

Where the ID is something that is similar to its name.

1 Like

I do understand why you may not want to do this system, but I can’t really think of a solution to the issues you have described? Maybe someone else will suggest something you could do or maybe you will think of one yourself at a later date. If I do happen to think of one randomly I’ll let you know though.

1 Like

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