Inventory System, is this a good use of metatables?

The code attaches a metatable of info to items in a player’s inventory so I can access a items info easily without having to datastore/store data that will always be the same

an item’s metatable is set when a player’s data is loaded, and whenever a item is added to a player’s inventory

function SharedInventoryModule:SetItemMeta(item)
	local meta = ItemDatabase:GetItem(item.Id)
	if meta then
		setmetatable(item, meta)
	end
end
function InventoryModule:AddItem(inventory, id)
	local item = ItemDatabase:GetItem(id)
	if item then
		local newItem = {Id = id}
		SharedInventoryModule:SetItemMeta(newItem)
		table.insert(inventory, newItem)
	end
en

the metatable is something like{name = “Name”, stats = {}} etc
while the item would be {ID = 1, Amount = 5}

so this is possible item.name etc

is this a good idea?

Another solution could be:
a GetItemInfo() function, but then I’d have to call this function quite often to access info

3 Likes

Apologies if I’m missing something but I don’t see a reason for using metatables within this inventory system. Mind explaining it?

2 Likes

I didn’t add any uses for it yet but one of them is gonna be for showing item info in a inventory gui on client

another could be for getting the stats of a equipped weapon

but yeah maybe it’s not as practical as I thought it was

Hey!

As far as I know setmetatable function only binds functions like __index. It shouldn’t work with custom names, so I doubt your example works. (Or I am wrong?) Might be useful solution depending on how you use it though. You would just need to modify it a little bit.

Edit: you can see pretty good tutorial about metatables there: https://www.tutorialspoint.com/lua/lua_metatables.htm

I set the __index, I didn’t post the code for it though

local Item = {
	new = function(id, name, desc, stats)
		local newItem = {}
		newItem.__index = newItem
		newItem.Id = id
		newItem.Name = name
		newItem.Desc = desc
		newItem.Stats = stats
		return newItem
	end
}

return Item
local ItemDatabase = {
	Item.new(1, "Sword", "Sword Description", {
		Damage = 10,	
		Value = 10
		}
	),
	Item.new(2, "Axe", "Axe Description", {
		Damage = 15,	
		Value = 11
		}
	)	
	
}
3 Likes

Metatables are a decent option here. Or you can have a field named “Data” which references back to this Item from the item database.

1 Like

I don’t understand the use case of metatables here. Why not just use a regular table to store data? It seems quite redundant to store data inside of an __index metamethod.

1 Like