Best way to store game items?

[Please read my first reply before commenting. I forgot something really important]
From my knowledge, it’s really common practice nowadays to store all your items in a ModuleScript in some form of table, with sub tables storing the properties. I’ll warn you in advance, In the examples I’m using, primary keys are stored as numbers in a dictionary. A fairly simple example of the “GameItems” table could be:

local gameItems =
{
[1] = {“Wooden Sword”, 3, 5, 10} – Let’s say 3 = Rarity, 5 = Damage, 10 = Price}
}

But I imagine a lot of programmers are internally (or perhaps externally) screaming at this malpractice.
I can think of another way:

local gameItems =
{
[1] = {[“Name”] = “Wooden Sword”,[“Rarity”] = 3, [“Damage”] = 5, [“Price”] = 10}
}

Which has the added advantage of being able to access psuedo properties of the “object”. For instance, gameItems[1][“Name”] returns “Wooden Sword” and so they start to feel more like objects. Ultimately, this system feels like one that lends itself to OOP and I’m wondering if any advanced programmers are out there using abstract / virtual classes out there to implement their items. I imagine this to be a serious step up from the predescribed dictionary format.

I’m a fan of inheritance and I’m curious if other scripters would have input on this topic. I’m more than happy to be told I’m wrong, so long as some insight as to why is provided!

Thanks for reading,

Zarkonan_Zenheart / Luke

5 Likes

@Thundermaker300 would know

The first example is simple and easy if you remember where the content is stored.

The second is a bit advanced, but it is easy to get the content.

I prefer to use the first example. But I think it’s up to each individual, how they would like to do it.

1 Like

I’ve used both methods. I generally like the second one better for readability. The only downside I can see is that it takes up more space if you’re saving it.

I’ve always done something like this

local gameItems =
{
["Wooden Sword"] = {["Rarity"] = 3, ["Damage"] = 5, ["Price"] = 10}
}

This is useful because you won’t have to memorize what number corresponds with what weapon.

This way, you can access the Damage of a Wooden Sword by doing gameItems["Wooden Sword"]["Damage"], for example.

Preface
It looks as though I haven’t really asked my own question!

The general consensus seems to be that the second method is preferable for readability purposes. I actually prefer neither solution, however!

I said in the post that I’m a fan of inheritance and briefly mentioned OOP and abstract classes. For those who don’t know what they are, I’ll explain as best as I can.

The relevant background explanation
Currently, the database described contains what we call primary keys (a uniquely identifier for each item in the database). There is then a corresponding table (containing values) or dictionary (keys with set values). The programmer is then assuming that they’ll set up the necessary parameters for the object to exist such as price, rarity, name, etc.

There’s a better way (in my opinion, that is)…
The aforementioned way of doing things is very simple to understand. It’s also fairly easy to implement, and in the second case, is somewhat readable. That, however, is not a good justification for using it (in my opinion)!

This fairly simple diagram describes how items can be categorised. For those entirely unfamiliar with anything like this, we call this inheritance. You may have seen something like :IsA(“BasePart”) before, which is actually something like this! Things like Unions, Meshes, Parts, Wedges, Spheres, etc all inherit properties of a BasePart such as Anchored, CanCollide, etc. However, they also have their own unique things EG Meshes have “MeshID”. This is called inheritance, where you collect properties as you go further down the tree.

The same kind of idea can work in these game objects as well. You can set up a more complicated but ultimately more desirable (again, in my opinion. Feel free to disagree :blush: ) system with inheritance. It is ugly to assume that certain indexes in an arbitrary table mean something. It is only slightly better to assume that the dictionary stores the corresponding values. I found an excellent guide on OOP here:

Where the fine chap describes it far better than I can! I’m looking for some programmers versed in programming practice to input their own views on this.

2 Likes

At the end of the day, I doubt the difference between them is large enough to choose one over the other except for preference.

I personally use neither for storing my items, and as of right now, have no interest in doing that. To me, they look hideous.

Once again though, preference.

I think preference is only acceptable when alternatives are of similar readability, functionality, and efficiency. As far as good practice goes, the first example is akin to:

x = 100
x = x ** x - (x-1)
(insert more badly written looking code)

When it’s far more meaningful to have:

function playerwin()
coins = (coins ** coins) - (coins-1)

coins = 100
playerwin()

Yes, I am well aware that the example I chose is actually ridiculous :joy: . I suppose I shouldn’t be so jovial about this, because it’s actually pretty serious to throw preference around as an excuse to do something.

You can argue that the first example uses up less space than the second. You can argue the second uses less than the third. However, the third example is an extremely important upgrade in the quality of your code. It uses far more examples of good practice, less assumptions, and introduces a much greater degree of readability. Good code is always self documenting (nowadays. We’re not constrained by mere kilobytes anymore, BBC micro [RIP]!).

Ultimately, inheritance helps to structure your code in a way the first two examples will realistically never be able to do. I implore you to consider using inheritance based item systems in the future. Once you convert, you’ll never go back!

I’m also curious as to what your intended method is. Your wording suggests that you missed my first reply to this thread (my apologies, I didn’t explain what I meant well enough in the first one). I offered an alternative method.

Your method is interesting, but yeah I never go through that much trouble. At the most, I would have a table of ranged weapons and one of melee. I usually handle ammo and stuff for the weapon itself, so I can make it more unique. No special dictionaries at all.

I like the idea of using an organized system like that, but I feel like for me personally it’s more trouble than it’s worth.

1 Like