Jump to content

  • Log In with Google      Sign In   
  • Create Account

Inventory System


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
11 replies to this topic

#1 Phil123   Members   -  Reputation: 675

Like
0Likes
Like

Posted 18 July 2012 - 03:34 PM

Alright, so I've been working on a Text-Based RPG during my spare time for a few weeks now and I'm kind of stuck on how I want to implement an inventory system.

Before you say, "you're wasting your time, you should do X, Y, or Z instead," I decided to start this project for a few reasons:

1. For fun (gasp!)
2. To solidify the concepts I've learned over the past few months
3. To develop my ability to work with larger projects (3400ish lines of code)
4. To continue developing my ability to debug code
5. And lastly, because I can Posted Image

Now that that's out of the way, here's my question:

So it's your standard text-based RPG. Monsters, abilities, levels, spells, unique battle system, different areas, merchants/other NPCs (eventually), towns (eventually), quests (eventually). All of this was quite easy to implement, given I have the time (which I did, and I still do). But one thing I've learned is that I should know exactly how I want to do something before investing hours into it to make it perfect and 100% bug free.

Here in lies my problem - I don't really have a solid idea of how I should go about implementing an inventory system (hence why I'm looking any ideas/advice/tips that people can provide).

Sponsor:

#2 kseh   Crossbones+   -  Reputation: 2087

Like
0Likes
Like

Posted 18 July 2012 - 04:06 PM

Perhaps start with telling us what is it exactly that you need the inventory system to do? Do you need to track the location and status of every item in a dungeon or would something like Hero.HealingPotionCount++ be sufficient?

#3 Mussi   Crossbones+   -  Reputation: 1977

Like
0Likes
Like

Posted 18 July 2012 - 04:15 PM

What kind of language are you using?

#4 Phil123   Members   -  Reputation: 675

Like
0Likes
Like

Posted 18 July 2012 - 08:21 PM

Perhaps start with telling us what is it exactly that you need the inventory system to do? Do you need to track the location and status of every item in a dungeon or would something like Hero.HealingPotionCount++ be sufficient?


Ack, had this in the original post, but I deleted it (was in a rush Posted Image ).

Some things I will want included in said inventory system:

1. There will be weapons, armour, accessories that the player can equip.
2. Consumables that the player will use (non-stackable, for example healing/mana potions - they will help, but won't make or break a player's ability to progress in the game)
3. The item data must be stored in a way such that it's easy to display to the player (shouldn't be a problem regardless of how it's implemented, but it's still something I have to take into account)
4. It must be designed/coded such that its functionality is simple and user friendly.
5. Each item must have a designation (for example, a sword could be labelled as a 1h Weapon - meaning, if the user tries to use a "sword" in battle, which is an equippable item and not say, a healing potion, it's extremely easy to distinguish between the two and tell the player "hey, what the hell, you don't want to do that.")
6. Inventory size will be limited.
7. Item pickup will be automated (may eventually make it manual, but for simplicity sake at the moment, it's planned to be automated), but the player can choose to drop items.
8. Items will always take up 1 slot, so I don't have to worry about different items taking up different amounts of space.

I've been thinking of a few things. I could use an array of strings to represent the player's inventory, with some file input to get the item stats and item type if need be. I could read in the item name, then read in the item type, and depending on the item type I'll read in different values to an cItem class.

But now when the player uses an item or equips an item I have to be careful as well because various items do different things, and I'd think it'd be inefficient to add 0 to every stat except for damage when the player equips a sword, or add 0 to every stat except for defense when they equip armour (maybe I'd just have to suck it up and have a separate function for EACH item type, but this seems time+space inefficient - there are many ways to do something in C++, but I'd prefer to do it the correct way the first time, or at least, a more "correct" way the first time). This is my main wall in my project currently.

What kind of language are you using?


Doh, was in the title (or at least it should have been...still new to the forums). C++, with Microsoft Visual C++ 2010 Express as the compiler/debugger.

Edited by Phil123, 18 July 2012 - 08:34 PM.


#5 Mussi   Crossbones+   -  Reputation: 1977

Like
3Likes
Like

Posted 19 July 2012 - 07:36 AM

How about something like this(just a rough and simple outline):

[source lang="cpp"]enum ItemSlot{ HEAD, CHEST, WEAPON, MAX_SLOTS};class Item{ ItemSlot slot; String name; // other base class stuff doStuff(); // maybe?};class ItemWeapon{ doStuff(){ /* special stuff */ }};class Player{ Item inventory[]; Item equipment[MAX_SLOTS]; equip(int i) { Item item = inventory[i]; // check if something else is equiped and revert stats if so equipment[item.slot] = item; // equip item // apply stats }};[/source]

Forgot about consumables when writing that, left some blanks as well, but I think this can get you going.

#6 CaptainKraft   Members   -  Reputation: 266

Like
4Likes
Like

Posted 19 July 2012 - 08:19 AM

I'm going to avoid answering the question to a specific programming language and just sort of explain my thinking based solely on OOP.

First, you could start with the "Item" class that you can extend in each other class for their respective item types. The fields and functions in "Item" would just be what is common between every item. (ie. name, size, etc.)

Once you start making new classes like "One Handers" or "Consumables" you can get more specific. You could create the functions that only those item types can use. (ie. equip, getDamage, etc.)

This is the very beginning of what could end up being your entire game's item system. I don't like providing code or getting into super specific details because it's more fun to figure it out on your own.

One more thing that I will say, is that you can break up your "Inventory" into multiple collections. For example, you could keep an array of consumables, an array of weapons, and an array of armor. Then when you display them to the player you could separate them logically. The problem that might come up is keeping track of how much stuff is in your inventory. This could easily be solved by using a counter for each item you pick up, or adding weight to your items.

Anyway, I hope I helped at least get the creative juices flowing. Also, I'd love to hear what your ideas are at this point. You may not have an answer yet, but you must have the beginnings of what your inventory will look like.

Happy coding

#7 Phil123   Members   -  Reputation: 675

Like
1Likes
Like

Posted 19 July 2012 - 10:03 AM

Thanks for the posts guys.

How about something like this(just a rough and simple outline):

Forgot about consumables when writing that, left some blanks as well, but I think this can get you going.


Hmm yeah, that helps a lot, thanks!

Anyway, I hope I helped at least get the creative juices flowing. Also, I'd love to hear what your ideas are at this point. You may not have an answer yet, but you must have the beginnings of what your inventory will look like.

Happy coding


Definitely, I didn't expect such quick responses - my plan was to establish some ideas in my head as to how I wanted to approach it and then really crack down on it this upcoming Weekend (Friday to Sunday) as I won't have much time to devote to it before then.

Really appreciate it guys, be sure to check this thread Sunday when I'm done Posted Image

#8 arkane7   Members   -  Reputation: 213

Like
1Likes
Like

Posted 19 July 2012 - 11:24 AM

just as JDGamedev mentioned, using OOP is your best bet at making it simple, shorter, and efficient (in some sense, since inheritance = virtual call table)

As he said, start with a base Item class that has everything that will be in common to everything in the inventory (i recommend not only name/proportionns etc but also a "type", so you can request anything that is an item what kind of item it is so you can do proper management)

from there make classes that inherit Item to be more specialized (armour, weapons, potions etc). Just keep a nice hierarchy but dont go too deep, as everyone know too many levels means a huge virtual lookup table (this is know when to use a subclasses function instead of a base classes function)

Then all you have to do is keep a vector/list/whathaveyou of Item pointers, then whenever something is added (like a Spear for example), just add its pointer to the list. Whenever you want to use an item, just find it (using its name or type) and use it; if its a weapon or potion that has specific functions that Item does not have, as long as you know it is the correct type you can use type-casting and call the function (Anyone here is free to correct me if I am wrong)
Always improve, never quit.

#9 Phil123   Members   -  Reputation: 675

Like
0Likes
Like

Posted 21 July 2012 - 07:09 PM

Okay, mostly done.

Item.h
[source lang="cpp"]#ifndef _ITEMS_H_#define _ITEMS_H_#include "Spells.h"// // // // // // // // // // // // ///* Inventory Class */// // // // // // // // // // // // //class Inventory{public: string Inv_List[InventorySize]; int Inv_Slots_Filled; string Weapon; string Chest; string Head; string Legs; string Feet; string Arms; string Hands; string Fingers; string Neck; string Ears;};// // // // // // // // // // // // ///* Inventory Class */// // // // // // // // // // // // //// // // // // // // // // // // // ///* Item Class */// // // // // // // // // // // // //class Item{public: string cName; string cType;};// // // // // // // ///* Weapon */// // // // // // // //class Weapon : public Item{public: int Offense_Increase; int Magic_Increase;};// // // // // // // ///* Chest */// // // // // // // //class Chest : public Item{public: int Defense_Increase; int Heal_Eff_Increase;};// // // // // // // ///* Head */// // // // // // // //class Head : public Item{public: int Defense_Increase; int Magic_Eff_Increase;};// // // // // // // ///* Legs */// // // // // // // //class Legs : public Item{public: int Defense_Increase; int Regen_Increase;};// // // // // // // ///* Feet */// // // // // // // //class Feet : public Item{public: int Defense_Increase; int Dodge_Increase;};// // // // // // // ///* Arms */// // // // // // // //class Arms : public Item{public: int Defense_Increase; int Magic_Eff_Increase;};// // // // // // // ///* Hands */// // // // // // // //class Hands : public Item{public: int Defense_Increase; int Accuracy_Increase;};// // // // // // // ///* Fingers */// // // // // // // //class Fingers : public Item{public: int Earth_Resist_Increase; int Air_Resist_Increase;};// // // // // // // ///* Neck */// // // // // // // //class Neck : public Item{public: int Death_Resist_Increase; int Holy_Resist_Increase;};// // // // // // // ///* Ears */// // // // // // // //class Ears : public Item{public: int Fire_Resist_Increase; int Ice_Resist_Increase; };// // // // // // // // // // // // ///* Item Class */// // // // // // // // // // // // // /* // // // // // // // // Item Objects // // // // // // // // */ Weapon cWeapon; /* Player Weapon */ Weapon tempWeapon; /* Temp Weapon */ Chest cChest; /* Player Chest */ Chest tempChest; /* Temp Chest */ Head cHead; /* Player Head */ Head tempHead; /* Temp Head */ Legs cLegs; /* Player Legs */ Legs tempLegs; /* Temp Legs */ Feet cFeet; /* Player Feet */ Feet tempFeet; /* Temp Feet */ Arms cArms; /* Player Arms */ Arms tempArms; /* Temp Arms */ Hands cHands; /* Player Hands */ Hands tempHands; /* Temp Hands */ Fingers cFingers; /* Player Fingers */ Fingers tempFingers; /* Temp Fingers */ Neck cNeck; /* Player Neck */ Neck tempNeck; /* Temp Neck */ Ears cEars; /* Player Ears */ Ears tempEars; /* Temp Ears */ /* // // // // // // // // Item Objects // // // // // // // // */#endif _ITEMS_H_[/source]

Normally I don't like using global objects, but in this case, it made life easier. Basically, I have one object for equipped items, and one object for temporary data. (cItemType and tempItemType respectively).

The object for the Inventory class is in my int main().

Function prototypes in my Main.cpp
[source lang="cpp"]string Get_Item_Stats (const string & szItemName);/* Inventory */void Equip_Item (Inventory & cInventory);/* Inventory */void Unequip_Item (Inventory & cInventory);/* Inventory */void Display_Gear (const Inventory & cInventory);/* Inventory */void Display_Inventory (const Inventory & cInventory);/* Inventory */void Display_Item ();/* Inventory */bool Slot_Open (const Inventory & cInventory);/* Inventory */void Drop_Item (Inventory & cInventory);[/source]

Get_Item_Stats uses file input to read in item stats. Depending on the item type, it'll read in to the corresponding tempItemType object. It also returns a string that contains the type of the item (this is important below).

Equip_Item allows the player to equip an item of his choice, granted that they have the item and the item slot is currently empty. Depending on the type of the item (which is where Get_Item_Stats comes in handy), the function will equip the item and store all of the data in the correct cItemType object, which I utilize in a different function to set the player's battle stats.

Unequip_Item unequips the specified item. Not much to say here.

Display_Gear displays the player's gear if they have something equipped in that slot. Again, nothing fancy here.

Display_Inventory lists what's currently in the player's inventory. It uses cInventory.Inv_Slots_Filled to determine how many items to display for cInventory.Inv_List[].

Display_Item displays the stats of a specific item. Again, uses Get_Item_Stats to temporarily store the item stat data, and it'll return the item type so my Display_Item function knows what item object to display.

Slot_Open returns true if a slot is open (who woulda thought). I'll be using this when monsters start dropping loot.

Drop_Item drops the item specified by the player (if they actually have that item).


Mission accomplished ^^ and after very minor amounts of testing, is 99.9% bug free. Thanks guys.

Edit: Didn't post the actual functions, but if anyone's curious, I can, just let me know.

Edited by Phil123, 21 July 2012 - 07:10 PM.


#10 arkane7   Members   -  Reputation: 213

Like
0Likes
Like

Posted 23 July 2012 - 09:55 AM

why do you have c and temp objects?

and more importantly, do you only have 1 type of items for each type of class? What I'm asking is wont you have like 3 different swords with various stats? or different clothing/gear?

The way you have set this up it seems like you can't expand it, the user can't have 5 differente unique weapons or clothing, only 1 of each. What i can see is that you edit the temp ones to accomodate changes to the particular item, where it can be a different weapon entirely, but this still prevents the user from having many different items of the same type. If this system serves your purposes that is fine, but this seems like a bad design approach. It is very limited and if you want to make changes to it later you most likely have to change the entire thing.


The point of recommending inheritance to aid you was to make this whole thing simlper, shorter and cleaner.

Your item hierarchy is fine, its just your c and temp globals that make this very unusual. I will come back to this thread and post an expanded example of how you may approach this (i am currently at work and cannot risk typing on here for an extended amount of time).
Like i said if your layout is working fine and your game is behaving how you want, you can just ignore me. I just want to help
Always improve, never quit.

#11 ZBethel   Members   -  Reputation: 577

Like
0Likes
Like

Posted 23 July 2012 - 01:17 PM

Let me just add that you don't need to justify your reasoning for working on this project. Often times 'reinventing the wheel' is the best way to learn, and this is the right place for that. Also, although I agree that you should have your requirements pretty much fleshed out before starting the development phase of a project, in my opinion it is often times impossible to know exactly how you're going to do everything--especially for large projects. The key is iteration. Start somewhere, and as you discover things that you need or approaches that don't work, take a step back and refactor. Unless you've written half a dozen inventory systems before, I would expect that kind of process.

EDIT: After reading a bit closer, it sounds like you were referring to not perfecting a piece of code that you're not sure is even what you want, which is good.

I recently wrote a resource manager for my game engine. I probably rewrote it three times until I found a design that I liked. It wasn't that I didn't figure out everything beforehand, it was mostly that my naive ideas of what I thought would work ended up being rather mediocre in the end, and I found better ways to do it only because I messed up the first two times.

Just saying.

Edited by ZBethel, 23 July 2012 - 02:49 PM.


#12 Phil123   Members   -  Reputation: 675

Like
0Likes
Like

Posted 23 July 2012 - 08:39 PM

why do you have c and temp objects?


c objects are for the player's equipped gear. When I determine the player's battle stats, the values stored in c will be added to this amount. (so... cBattleStats.Offense = cPlayer.Offense + cWeapon.Offense_Increase, etc etc). The reason why I can't just add this value to cPlayer is strictly because monster strength is partially based on cPlayer stats (and I only want enemies to get stronger based on your stats/level, rather than how good your gear is - to reward exploring more areas and fighting tougher enemies to get better gear rather than grinding the same area).

Temp objects are for storing temporary data that is used to display specific item stats (say, an item in the player's inventory). It opens the item data.txt file and reads in the values into the corresponding temp object.

I suppose I could skip the whole "temp" object and just display the info to the screen while I get the data from a file, but in this situation (doing something new) I decided to split everything up so if I end up with a nasty bug, it's much easier to pinpoint where it is.

What I'm asking is wont you have like 3 different swords with various stats?


Sure, but the player can only equip one. I could change my program so when the player wants the items in his inventory listed it'll display the stats for each item, but that'd be a mess when playing the game.

The way you have set this up it seems like you can't expand it, the user can't have 5 differente unique weapons or clothing, only 1 of each.


They indeed can. The item name of said weapons or clothing is stored in Inv_List, and the player can easily get the game to display the stats of said item through file input (item data.txt or whatever I called it).

Your item hierarchy is fine, its just your c and temp globals that make this very unusual.


Yeah, I know, I'm always open to ideas, just because I've implemented something and posted the general outline doesn't mean I'm not willing to change it up or completely redesign it.

Like i said if your layout is working fine and your game is behaving how you want, you can just ignore me. I just want to help


It's working great, but I'm always looking for new ideas to do things so please post away. And ignoring you would be extremely disrespectful as there's alot to learn from the people on these forums. And thanks - for wanting to help, it's appreciated.

Start somewhere, and as you discover things that you need or approaches that don't work, take a step back and refactor.


Yeah, this happened a few times. I'd say to myself "wait a second... ... ...this won't work, I have to change this because of this."

I probably rewrote it three times until I found a design that I liked. It wasn't that I didn't figure out everything beforehand, it was mostly that my naive ideas of what I thought would work ended up being rather mediocre in the end, and I found better ways to do it only because I messed up the first two times.


Yup, that's exactly why I keep an open mind to new ideas/ways of doing things.

Edited by Phil123, 23 July 2012 - 08:48 PM.





Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS