rpg oop class design

Started by
5 comments, last by pulpfist 14 years, 10 months ago
Hi, I'm just starting with this, hoping to make some toy program if not a game. I just need to know if I'm on the right track with this. It's gonna be pretty hard to read, but this is what I have thought of so far - its c++ by the way. I tried to copy some ideas from: Link. I'm trying to work out a system where weapons/clothes get there stats from what elements they're made of, as well as a way to change your body or even go without one.

#ifndef _STATS_H_
#define _STATS_H_

#include <string>
#include <list>

/*
    Elements for all tangible entities.
*/

// Elemental Makeup, 0 to 100.
#define ELEMENT_WOOD 0
#define ELEMENT_FIRE 1
#define ELEMENT_EARTH 2
#define ELEMENT_METAL 3
#define ELEMENT_WATER 4
#define ELEMENT_AIR 5

// The number of elements.
#define NUM_ELEMENTS 6

/*
    Attributes for all creatures.
*/

// Attributes, 0 to +100.
#define BODY_POTENTIAL 0
#define BODY_CURRENT 1 

#define MIND_POTENTIAL 2
#define MIND_CURRENT 3

#define SOUL_POTENTIAL 4     
#define SOUL_CURRENT 5

// Attributes, -100 to +100.
#define APPEARANCE 6
#define AURA 7

// The number of attributes.
#define NUM_ATTRIBUTES 8

/*
    Skills for all characters.
*/

// Combat Skills, 0 to +100.
#define SKILL_UNARMED 0
#define SKILL_MELEE 1
#define SKILL_RANGED 2

// Mundane Skills, 0 to +100.
#define SKILL_BUSINESS 3
#define SKILL_MEDICINE 4
#define SKILL_SEDUCTION 5
#define SKILL_SPEECH 6
#define SKILL_TECHNOLOGY 7
#define SKILL_THEFT 8
#define SKILL_MUSIC 9

// Spell Skills, 0 to +100.
#define SKILL_NECROMANCY 10
#define SKILL_TELEPATHY 11
#define SKILL_SUMMONING 12
#define SKILL_ENCHANTING 13
#define SKILL_NATURE 14

#define NUM_SKILLS 15

/*
    Any Entity in the game.
*/
class Entity
{
    private:
    protected:
        static std::list <Entity*> s_entities;
    public:
};

/*
    Any tangible entity in the game. Eg. An instance of a creature or item.
    Every tangible entity in the game has an elemental makeup.
*/
class Tangible : public Entity
{
    private:
    protected:
        float m_elements[NUM_ELEMENTS];
    public:
};

/*
    Any item.
*/
class Item : public Tangible
{
    private:
    protected:
        float m_weight, m_value;
        std::string m_name, m_description;
    public:
};

/*
    Any item that can be equipped by a creature.
*/
class Equippable : public Item
{
    private:
    protected:
        std::vector <Trait*> m_traits;
    public:
};

/*
    An item that is weilded to do damage in combat.
*/
class Weildable : public Equippable
{
    private:
    protected:
        float m_range;
    public:
};

/*
    An item that is worn.
*/
class Wearable : public Equippable
{
    private:
    protected:
        float m_appearance;
    public:
};

/*
    An item that characters can own, and use for transport.
*/
class Vehicle : public Tangible
{
    private:
    protected:
    public:
};

/*
    A living creature.
*/
class Creature : public Tangible
{
    private:
    protected:
        float m_attributes[NUM_ATTRIBUTES];
        float m_skills[NUM_SKILLS];
        bool m_usesItems, m_usesVehicles, m_eatsMeat, m_eatsVeges, m_male, 
        m_female, m_livesIndoors;
    public:
};

/*
    A creature that follows a character.
*/
class Companion : public Creature
{
    private:
    protected:
    public:
};

/*
    A kind of creature that can have other creatures follow it and can move
    around, etc.
*/
class Character : public Creature
{
    private:
    protected:
        std::vector <Trait*> m_traits;
    public:
};   

/*
    A character that is automatically controlled.
*/
class NonPlayerCharacter : public Character
{
    private:
    protected:
    public:
};

/*
    A character that is controlled by a human player.
*/
class PlayerCharacter : public Character
{
    private:
    protected:
    public:
};

/*
    Any location.
*/
class Location : public Tangible
{
    private:
    protected:
    public:
};

/*
    A world contains cities, has DateTime.
*/
class World : public Location
{
    private:
    protected:
    public:
};

/*
    A city contains areas, has weather.
*/
class City : public Location
{
    private:
    protected:
    public:
};

/*
    An area can store items, can be owned, can be visited by characters.
*/
class Area : public Location
{
    private:
    protected:
    public:
};

/*
    Any entity that is abstract. Eg. kinds of traits, weather, etc.
*/
class Intangible : public Entity
{
    private:
    protected:
    public:
};

/*
    Keeps track of the date and time of a world.
*/
class DateTime : public Intangible
{
    private:
    protected:
    public:
};

/*
    Keeps track of the weather of a city, seasons, etc.
*/
class Weather : public Intangible
{
    private:
    protected:
    public:
};

/*
    Some experience/trait/knowledge/form that a character has or that is 
    achieved from some item.
*/
class Modifier : public Intangible
{
    private:
    protected:
        std::string m_name, m_desc;
    public:
};

/*
    May modify attributes: Body, Elemental stats, appearance, and aura.
    Eg. Human(stat change), Female(maybe no stat change), Feline.
*/
class BodyForm : public Modifier
{
    private:
    protected:
    public:
};

/*
    May modify skills only. Eg. Combat Training, etc.
*/
class Trait : public Modifier
{
    private:
    protected:
    public:
};

/*
    An action that creatures and characters might be able to perform.
*/
class Action : public Intangible
{
    private:
    protected:
    public:
};

#endif




Dose it make sense? Where would the classes that create items and creatures and things fit in? Are they outside this heirarchy and just use the classes that they create? I'm not sure how that Action class would work. I don't want to hard-code the actions in, I want to be able to load them from XML. Thanks for reading my post :)
Advertisement
#define SKILL_UNARMED 0
#define SKILL_MELEE 1
#define SKILL_RANGED 2

Use enums it will be nicer and more object oriented..

class Entity
{
private:
protected:
static std::list <Entity*> s_entities;
public:
};

Here we have something bad the keyword static yes it would be nice if the entities manages themselves but in my experience it's always better to have some kind of EntityManager for creating entities and skip the static because then you could create a new EntityManager and pre load next area in the background to hide loading times for instance.

"Where would the classes that create items and creatures and things fit in? Are they outside this heirarchy and just use the classes that they create?"

You should maybe split into smaller pieces so you got one class FireProtection and WaterProtection and also a class FireAttack and WaterAttack so then you could use multiple inheritance for different kind of protections and attacks.

Weapons and clothes should inherit from these and you should always calculate the damage and protection from these.
I have just skimmed through your code so far but I thought I would start the feast with a minor suggestion.

You are using two booleans to represent gender. I think an enum would do this job better:
enum Gender { MALE, FEMALE, BISEXUAL };
Since you have a lot of empty base classes, I can't know whether they are really necessary. Do you really need a list of ALL the objects in your program, whether they are visible or abstract (including date and time)? What are you going to do with that list/what virtual methods would an Entity or Tangible have? Maybe it isn't required that every object in the game inherits from one base class?

And off course enums are a lot better than defines here (you won't have to explicitly assign them a value and they offer type protection).

Thanks! I changed everything to enums. I realised that the gender and all that stuff didn't belong where it was anyway. I changed it a bit so it makes more sense now.
Quote:Original post by beun
Since you have a lot of empty base classes, I can't know whether they are really necessary. Do you really need a list of ALL the objects in your program, whether they are visible or abstract (including date and time)? What are you going to do with that list/what virtual methods would an Entity or Tangible have? Maybe it isn't required that every object in the game inherits from one base class?

And off course enums are a lot better than defines here (you won't have to explicitly assign them a value and they offer type protection).


Heh yeah. Thanks. I was just trying to lay it out so I can understand where I'm heading with it. Lol they do seem like they are quite useless, I can't think of anything to put in the entity class.
I also think you should be a bit more conservative about adding new layers to your inheritance tree. I would suggest keeping it to a minimum, and think twice before you decide to create a new class.
Basically, I would not use classes to differentiate between different types of things.
Take Character, NonPlayerCharacter and PlayerCharacter for instance. Is it worth it to have three different classes for them? I'm not saying its wrong, I guess it depends on what your game requires of them. But right now I'm thinking that you can probably skip the Character. And for some games you could probably skip both NonPlayerCharater and PlayerCharacter, and just go with Character.
If you design things right an object of type Character could be driven by either a player or the computer. Leave it to the logic somewhere else to decide if the objects input comes from a player or the computer. The object itself doesn't really need to know the difference. On the other hand, if the NPC is going to tell stories and hand out quests, I can see the need to have two different classes. But not three.

Well, that was just some ideas. You will have to decide yourself what works for your game. Just remember the "keep it simple" principle.

On to something else; I like the fact that your Weather class contains elements. Makes me think about acid rain and what not. But I'm not so sure about the DateTime class. I can't imagine this as anything more than a member variable in the World class or something like that. Unless you are going hog wild with parallel dimensions and time travels of course =)

This topic is closed to new replies.

Advertisement