Storing information in individual objects VS a centralized location

I’m working on a inventory/item system and am wondering what design would be best for performance and usability.
My current thinking is that variables that change object to object should be stored in the object and variables that don’t change should be kept in one location and have functions to request that data when its needed.

In the following two examples CustomName is a variable unique to each Item and changeable by the user at any point.

In this example the object has all the variables.

local Item = {}

function Item.New(Id, Name, Description, Icon, Weight,CustomName)
    return setmetatable({Id = Id,CustomName = CustomName, Name = Name, Description = Description, Icon = Icon, Weight = Weight}, Item)
end

Item.__index = Item

function Item:GetId()
    return self.Id
end

function Item:GetName()
    return self.Name
end

function Item:GetDescription()
    return self.Description
end

function Item:SetCustomName(NewValue)
    self.CustomName = NewValue
    return self.CustomName
end

function Item:GetCustomName()
    return self.CustomName
end

return Item

In this example CentralizedItems stores all the variables for each item.Id in a table where the index is the item’s Id.

local Item = {}

local CentralizedItems = require(game.Workspace.CentralizedItems)

function Item.New(Id,CustomName)
    return setmetatable({Id = Id, CustomName = CustomName}, Item)
end

Item.__index = Item

function Item:GetId()
    return self.Id
end

function Item:GetName()
    return CentralizedItems.GetItemNameForId(self.Id)
end

function Item:GetDescription()
    return CentralizedItems.GetItemDescriptionForId(self.Id)
end

function Item:SetCustomName(NewValue)
    self.CustomName = NewValue
    return self.CustomName
end

function Item:GetCustomName()
    return self.CustomName
end

return Item

If anyone has any input on which design is best in regards to programming functionality/ease of use and game performance impact I’d appreciate it, especially if you would choose one over the other depending on if you were dealing with 10’s of Item VS 1000’s.

I haven’t read the entire thread, you should make a TL;DR

From what I comprehend;

There is no reason to call a function within a function for no reason, I’d use the first one

There’s a lot of reasoning to why but I don’t want to get into it, just take it as method 1 is better and any programer who knows what they are doing should agree on that.

And I do hope that these are just examples because I wouldn’t want to call a function to get a name or property instead of just indexing, that’s only redundant.

Would you use

Item = {"NameHere","DescriptionHere","CustomNameHere"}
print("Name" .. tostring(Item[1]))

or

Item = {Name = "NameHere", Description = "DescriptionHere",CustomName = "CustomNameHere"}
print("Name" .. tostring(Item.Name))

Method 2 because of readability and accessibility.

I would use method 1 for other use cases that I don’t need to know what to index an entry with, something that is fully automated. I can’t be bothered to look at which numerical index is which value.

Performance wise it shouldn’t be too different, you are paying for readability and accessibility.

You don’t have to do tostring it’s already a string

For “static” and immutable properties like the item’s name and description, I would just store that inside your CentralizedItems module, since there is no reason to duplicate that for every instance of the item (and saves memory if you will be using many items).

1 Like

If anyone else has an issue like this and wants to learn more the terminology is ‘Shallow copies’ and ‘Deep copies’, Where Shallow copies use pointers to reference data and Deep copies duplicate data.