When building an inventory system, there are a lot of different approaches that you can take. Some developers simply hard-code everything, while others make sure that nothing is hard-coded – and in between both of these two extremes is a comfortable middle point, where we have most of the flexibility of not having anything hard-coded, while still being able to develop with the same level of ease as if we had hard-coded it.
Designing an inventory system like this takes time – you can’t just throw everything together and hope it works. You need to plan it out first.
One question you need to ask yourself is: what about different item types? If there are weapons, armor, and general items, how will you handle that?
A hard-coded solution would be to create three tables – weapons,armor, and items. But at that point, you have a problem; how will you link specific items to something like monsters? You would need to create three more tables – monster_weapons, monster_armor, and monster_items. And then figuring out what particular item a monster might drop at any given time would be a major headache.
An easier solution to this is to create a single items table, with a ‘type’ column that can be used to track the type – that way, we only need to link monsters up to single items, and we can retrieve all of the monster’s droppables with a single, simple database query. Here’s what a simple items table might look like:
CREATE TABLE items ( id int NOT NULL AUTO_INCREMENT, name text, type text, PRIMARY KEY(id) );
At this point, we now have a single table that we can use to track our different items – and the flexbility to categorize them all by type if we so choose. This allows us to do something like this to create three different items(each a different type):
INSERT INTO items(name,type) VALUES ('Wooden Armor','armor'); INSERT INTO items(name,type) VALUES ('Wooden Sword','weapon'); INSERT INTO items(name,type) VALUES ('Red Potion','consumable');
By building our items table in this way, we only need one table to link a monster to the items that they will drop – and we can easily make them drop any type of item we want them to. We can also create an item_stats table, so that all of our items can have stats applied to them:
CREATE TABLE item_stats ( id int NOT NULL AUTO_INCREMENT, item_id int, stat_id int, value text, PRIMARY KEY(id) );
And this way, we can leverage our stats system to allow our items to have the same stats as our players or our monsters. We can easily add and remove stats for any item we choose – if a potion should have a defence of 4 and a maximum HP of 8, we can do that. The flexibility is there.
While it’s not the perfect system, this inventory system is ‘good enough’ – as long as the only thing you know is that you will need to add and remove item types, and have different items with different stats, this item system will work perfectly for you.
Do you know of a better way to design an inventory system? Shoot me an e-mail at firstname.lastname@example.org, or leave a message in the comments!
Edit: sepp has pointed out that the item.type column would be a perfect location to use what’s known as an enum. According to the MySQL documentation on enums, an enum is “a string object with a value chosen from a list of allowed values that are enumerated explicitly in the column specification at table creation time.” – which is perfect for what we need. Because we will only have so many item types within our game, using an enum will ensure that we can’t have situations where we make a typo and end up with an item with a type of ‘weapoh’ or anything. Here’s the table creation code, using a basic enum to set up 3 item types:
CREATE TABLE items ( id int NOT NULL AUTO_INCREMENT, name text, type ENUM('Weapon','Armor','Usable'), PRIMARY KEY(id) );
Wish there was more?
I'm considering writing an ebook - click here.
Luke is the primary editor of Building Browsergames, and has written a large portion of the articles that you read here. He generally has no idea what to say when asked to write about himself in the third person.