Sign in to follow this  
3dmodelerguy

Class Hierarchy Design

Recommended Posts

Class Hierarchy Design: Ok so I am going through the process to thinking about all the classes I am going to need from my RPG and writing them down(with properties, methods, etc…) before I start to actually get into the coding. One of my high level classes is going to be a item class that all game items(weapons, armor, potions, etc…) will derive from. Now I don’t want to create a system that has a million classes but I also don’t want to have classes that require 10 parameters. So basically the hierarchy form my potions, I was think something like this: item -potion --minor_mana_potion --mana_potion --major_mana_potion --minor_ health _potion --health _potion --major_health_potion Now each of these would only need to take a parameter for the stack size(and the other X members of the class would automatically be set in the definition of the parent constructor call of potion). Now the downside that I see if I want to add a new potion type I would have to add 3 classes for each. The next way I thought was: item -potion --minor_potion --normal_potion --major_potion and then I would provide the potion type and the stack size. Of course there might be a potion in the future that only supports normal and not minor/major. That lead me to think about this: item -potion --mana_potion --health_potion and then I would have to provide the potion’s strength(if it allowed more than one) and the stack size. Now this last way seems to offer the best as far as having few parameters and also fewer classes however the top one provides that best in the way of few parameters and would be more future proof. Now of course these classes are not used so often and not performance intense like a rendering engine or something like that so I would like I could add more classes to help with how well the system scales. This is current what I would think would be the best system for scaling: item -potion --health_potion ---minor_health_potion ---normal_health_potion ---major_health_potion --mana_potion ---minor_mana_potion ---normal_mana_potion ---major_mana_potion --stamina_potion This would seem to allow me the most flexible solution as it would allow me to be able to customize each potion on its own so I would make a change to the minor_health_potion without change any other health potion or any other minor potion. Do you think this would create to many classes or to much overhead and that I should loss the flexibility with one of the previous options? Any thoughts would be great.

Share this post


Link to post
Share on other sites
-item
-- potion
--- mana_potion
--- health_potion


// type of all potions
enum PotionType {
MINOR,
MAJOR,
SUPERIOR
}

// Defines functional interface to potion
struct potion {
int strength;
virtual void use() = 0;
};

struct mana_potion {
virtual void use() {
int s = strength;
if (player.class == MAGE) s = s * 3;

player.mana += s;
}
};

struct health_potion {
virtual void use() {
player.health += strength * player.healing_skill;
}
};



//Common entry point for creation of potions
mana_potion make_mana_potion(PotionType t) {
mana_potion mp;
switch (t) {
case MINOR : mp.strength = 10; break;
case MAJOR : mp.strength = 30; break;
case SUPERIOR : mp.strength = 50; break;
}
return mp;
}


All potions are then created via their make_xxx_potion.
Any potion can be use()d in the same way, regardless of what it actually does.

Alternative implementation s are possible, but neither requires complex class hierarchy.

Share this post


Link to post
Share on other sites
That would seem like a very good thing to do. However, if I were you, I would design this as following (coding out of the top of my head, could be riddled with errors)


//add any things a potion could do to a person
enum SkillsAndAbilities
{
saa_strength,
saa_power,
saa_health,
saa_mana
};

//this structure will contain the effect the potion has
struct PotionEffect
{
SkillsAndAbilities targetSkill;
float value;
};

//implement item class yourself
class Potion : public Item
{
public:
Potion(/*any constructor arguments?*/);
~Potion();

PotionEffect GetEffect() { return myeffect; }

protected:
PotionEffect myeffect;
//any other variables for this class
};

class NPC : public WhateverBaseClass
{
public:
NPC(/*constructor arguments*/
~NPC();

void Consume(Potion p)
{
PotionEffect pe = p.GetEffect();

swith (pe.targetSkill) {
case saa_strength:
myskills.strength += pe.value;
break;
//implement the rest
}
}
};



This way, you can add whatever items you want to your game and modify a lot of different skills/abilities/stats.

Share this post


Link to post
Share on other sites
Well the potion class stores the following information(note I am using C#)


protected potion_types type;
protected potion_strengths strength;
protected bool instant;
protected int duration;
protected int amount;
protected attribute_types effected_attribute;
protected int max_stack_size;
protected int stack_size;




Now the constructor requires each of these in order to create a potion and for each specific potion has the same value for each one(a minor_mana_potion can not have different values for amount of duration or anything else besided the stack size so my train of thought was:


//this seems very long and unnecessary since the only thing that would change in the last parameter for any minor mana potion
potion minor_mana_potion = new potion("Mana Potion", potion_types.mana, potion_strengths.minor, false, 3000, 10, attribute_types.mana, 20, 1);
//this seems a lot cleaner
minor_mana_potion minor_mana_pot = new minor_mana_potion(1);




and basically all the minor_mana_potion(or and xxx_xxx_potion) would just be a a class that inherits from potion class and would just call the potion's constructor with the values pre-populated, like a pre-populated template of a specific item. Now grant you I could do this with a potion static method like:


class potion : item
{
//code ...

static public potion make_minor_mana_potion(int stack_size)
{
return new potion("Mana Potion", potion_types.mana, potion_strengths.minor, false, 3000, 10, attribute_types.mana, 20, stack_size);
}
}




I just thought that using a class instead of a static method would look cleaner and allow for greater flexibility(so i could modify the minor_mana_potion without affecting any other mana potion classes or any other minor potion classes). It there a different way of doing that is more optimized and still allows the greater flexibility to modify each potion separately.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this