3
\$\begingroup\$

I'm working on a Resident Evil 1/2/3/0/Remake type of game. Currently I've done a big part of the inventory system (here's a link if you wanna see my inventory, pretty outdated, added a lot of features and made a lot of enhancements)

Now I'm thinking about how to approach the items system, If you've played any Resident Evil game or any of its likes you should be familiar with what I'm trying to achieve. Here's a very simple category I made for the items: enter image description here enter image description here

So you have different items, with different operations you could perform on them, there are usable items that you could use, like for example herbs and first aid kits that 'using' them would affect your health, keys to unlock doors, and equipable items that you could 'equip' like weapons. Also, you can 'combine' two items together to get new one, like for example mixing a green and red herb would give you a new type of herb, or combining a lighter with a paper, would give you a burnt paper, or ammo with a gun, would reload the gun or something. etc. You know the usual RE drill.

Not all items are 'transformable', in that, for example: lighter + paper = burnt paper (it's the paper that 'transforms' to burnt paper and not the lighter, the lighter is not transformable it will remain as it is) green herb + red herb = newHerb1 (both herbs will vanish and transform to this new type of herb) ammo + gun = reload gun (ammo state will remain as it is, it won't change but it will just decrease, nothing will happen to the gun it just gets reloaded)

Also a key note to remember is that you can't just combine items randomly, each item has a 'mating' item(s).

So to sum up, different items, and different operations on them. The question is, how to approach this, design-wise?

I've been learning about interfaces, but it just doesn't quite get into my head, I mean, why not just use classes with the good old inheritance? I know the technical details of interfaces and that the cool thing about them is that they don't require an inheritance chain, but I just can't see how to use them properly, that is, if they were the right thing to use here.

So should I go with just classes and inheritance? just like in the tree I showed you? or should I think more about how to use interfaces? (IUsable, IEquipable, ITransformable) - why not just use classes UsableItem, Equipable item, TransformableItem?

I want something that won't give me headaches in the long run, something resilient/flexible to future changes. I'm OK using classes, but I smell something better here.

The way I'm thinking is to possibly use both inheritance and interfaces, so that you have a branch like this: item -> equipable -> weapon. but then again, the weapon has methods like 'reload' 'examine' 'equip' some of them 'combine' so I'm thinking to make weapon implement ICombinable?... not all items get used the same way, using herbs will increase your health, using a key will open a door, so IUsable maybe?

Should I use a big database (XML for example) for all the items, items names, mates, nRowsReq, nColsReq, etc?

Thanks so much for your answers in advanced, note that demo 3 is coming after I'm done with items :D

\$\endgroup\$
3
  • 3
    \$\begingroup\$ That's one big ass tree. Cut it down in size and go data-driven. \$\endgroup\$ Commented Jul 29, 2013 at 22:15
  • \$\begingroup\$ For the big ass, that's actually a small-sized version of the actual tree. For the data-driven, could you elaborate more? \$\endgroup\$
    – vexe
    Commented Jul 30, 2013 at 0:36
  • \$\begingroup\$ I agree with @VaughanHilts, if this is the design you have decided on you should atleast try and generalize certain objects. If you think about it, all the weapons have same the parameters: clip size, bullet velocity, trajectory etc. The values are simply different for each weapon type. The weapons class could therefore be merged into one generic class. \$\endgroup\$
    – Dadgron
    Commented Aug 2, 2013 at 15:51

2 Answers 2

5
\$\begingroup\$

This is probably not the answer you were hoping for, but I think the best way to implement this is to use both inheritance AND interfaces.

The inheritance tree you describe above seems pretty good, in that it's fairly complete (you may find you want to add some extra abstract classes for common functionality between some of those branches, but that's an easy change to make. The obvious example to me is "Firearm" between weapon and both Rifle and Handgun).

However, you mention (correctly) TransformableItem in your question, and that's not in the list of classes. Where would you add it if you wanted to make it a class? You could make it a child of Item, and have everything else inherit from it, but then EVERY class would be transformable, and that's no what you want. Anywhere else in the inheritance structure though, and not every desired class inherits it.

So a way (certainly not the only, and not necessarily the best, but that recommendation would require a lot more knowledge of your game) to implement this is to have herb, firearm, and some of your other item classes implement ITransformable. Then functionality is common between classes, re-used, and not present where you don't need it. Testing for .Implements(ITransformable) allows you to decide when to show those menu items, and the methods for combining take ITransformable parameters to stop you from trying to transform a first aid kit (or whatever).

In short, not every class should be an interface, but some functionality should be wrapped in one, so it can be applied to "arbitrary" classes within an inheritance tree.

\$\endgroup\$
8
  • \$\begingroup\$ +1 because I agree on using both interfaces and classes. I think the root of the tree can be done using interfaces, while it gets usefull to use classes down the way from weapon to machine gun. \$\endgroup\$
    – Thomas
    Commented Jul 29, 2013 at 6:55
  • \$\begingroup\$ +1 good answer, I like your firearm idea, but here's a couple of things: 1- about the ITransformable interface, I imagine that all what needs to be put inside of it is the TransformationData (which for me is just a new item name and texture, could make this a struct) and Transform(), which doesn't need to take parameters, because when an item implements that interface and needs to Transform, it just calls the method and transform according to the data (is it that simple or am I missing something?) \$\endgroup\$
    – vexe
    Commented Jul 30, 2013 at 0:50
  • \$\begingroup\$ 2-its true that not all items are transformable which justifies the need of an interface but lets talk about Misc items for example. yes not all of them do BUT if some of them do, then they transform in the same way! lets say keys dont transform but some of 'others' do, how to appraoch this, should I make a class called TransformableOthers and NonTransformableOthers? 3- All equipable items equip in the same way, play some anim, set as equipped etc. But not all Usable get used the same way, does this mean that I should make a class EquipableItem and an interface IUsable? am I thinking right? \$\endgroup\$
    – vexe
    Commented Jul 30, 2013 at 1:00
  • \$\begingroup\$ Another problem, let's say green herb + red herb = new herb; who's gonna be transformable? the red or green herb? to get the new herb, I only need the transformation data from one of the herbs, if both were transformable, it means that one of them has extra redundant luggage. \$\endgroup\$
    – vexe
    Commented Jul 30, 2013 at 1:22
  • 1
    \$\begingroup\$ To answer the other query there - I assumed you would have a class for each misc object (keys, money, ammo etc) that would inherit from "other" in non-key examples. That is the class that would implement ITransformable, not the "other" class. Your distinction between EquippableItem and IUsable suggests to me that you haven't quite understood the distinction between class and interface. This isn't really the place for a full-on programming tutorial, but the twitter version: A Class is for an object that IS something, an interface is for an object that DOES something, and so more arbitrary. \$\endgroup\$
    – Ryno
    Commented Jul 30, 2013 at 3:01
1
\$\begingroup\$

Have you tried an component based entity system? Here's an example I think would be good to check out: http://cowboyprogramming.com/2007/01/05/evolve-your-heirachy/

\$\endgroup\$
3
  • \$\begingroup\$ You should edit your answer to add some more information. In its current state, it is more appropriate as a comment. \$\endgroup\$
    – user15805
    Commented Aug 2, 2013 at 14:22
  • \$\begingroup\$ I can't go back now, I went too deep and actually implemented inheritance and all that OOP stuff, but I will keep this in mind for future designs, thanks. \$\endgroup\$
    – vexe
    Commented Aug 6, 2013 at 11:02
  • \$\begingroup\$ I'm actually leaning towards this approach now. I found pure inheritance and object hierarchy to be very troublesome and inflexible. \$\endgroup\$
    – vexe
    Commented Oct 13, 2013 at 11:09

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .