Member Avatar for Mouche

Hello,

I worked with Python for about a year. Then I moved on to C/C++. Now I'm learning Java. I know the basics of programming really well, and I'm starting to get a good grasp of OOP.

I'm learning the syntax of abstract classes and inheritance in Java. I thought it would be fun to make a small program to use the new syntax I learned, so decided to make a small RPG (I know--typical project).

Say I have a Character class.

public class Character
{
    private String name;
    private int level;

    public void moveNorth()
    {
        // code to move north
    }
    
    // more methods for movement
}

So, it's rather simple. What if I'm going about my business in a world and talk to an NPC. The NPC asks me if I want to be a magician or a warrior. I want the character to acquire a set of methods and variables depending on his/her answer.

For instance, a warrior might have DoubleSlash(), PowerStrike(), LungeAttack(), and a variable for keeping track of something like mana for warriors. And a magician might have FireBall(), LightningStrike(), Heal(), Weaken(), and a variable for mana.

How could I have my character gain a certain set of skills? I haven't found anything for java on conditional inheritance. I'm trying to avoid giving all the skills to the character and having a million true/false flags for whether the character can use the skill or not. That would add a lot of hassle.

Thanks for your input.
Mouche

Recommended Answers

All 8 Replies

O_o There is no such thing as this; not in Java anyway. It would require some kind of dynamic/run-time typing... You won't get that for free in a compiled language like Java, or C++.

One way to go about this would be to have 'helper objects' that contain the variables specific to an ability, and a interface/abstract method like doAbility( ) . Keep them in a dictionary/map/hash within each character; using a string key with the ability name. Instead of calling character.DoubleSlash( ) , you'd call character.getAbility( "DoubleSlash" ).doAbility( ) or similar. To link the two objects together ( i.e. so a 'DoubleSlash' helper can access the data in a Character; use a 'character' variable : either local to each helper ( perhaps provided as a constructor paramater ), or pass the character using the ability into the doAbility() function.

Member Avatar for Mouche

Hmmm.. that sure seems complicated.

So, have you ever played WoW, Runescape, MapleStory or an RPG similar to those? In those games, there are many skills that you can have. You can only use them at certain times, and depending on your class or job (whatever you call it), you may never get to use any abilities in a certain set. How do you think they programmed that? I haven't been able to find any code or ideas on that. Giving the main character all of the methods and variables and then using flags to turn them on and off for the character seems like it would bloat the class and create a huge hassle in the main code because of the tons of checks that would have to be put in.

For example, if you have a menu for a battle and you click "Attacks" to see which attacks you can use... say you get this screen:

- Slice
- Lunge Attack
- Double Slash

but the class actually had Slice, Lunge Attack, Double Slash, Heal, Fire Bolt, Lightning Strike, Summon Dragon, and Roar. Some of the methods would be for later levels and some for a different class. That would mean you would need a variety of checks. To get the above menu you'd need something like this:

if (character.job == "Warrior")
{
    System.out.println("- Slice");
}
if (character.job == "Warrior" && level > 5)
{
    System.out.println("- Lunge Attack");
}
if (character.job == "Mage")
{
    System.out.println("- Fire Bolt")
}
// etc. etc.

Or perhaps another way would be different. Have on and off flags for each ability. The character would have a ability_flag for every single ability available in the game.

Then when you got to the menu it would just be:

if (slice_flag)
{
    System.out.println("- Slice");
}
if (lungeattack_flag)
{
    System.out.println("- Lunge Attack");
}
if (firebolt_flag)
{
    System.out.println("- Fire Bolt")
}
// etc. etc.

In that case, the code would get huge really quickly. If you have three jobs, and each has 20 unique abilities ranging from level 1 to 40, that's 60 abilities right there. What if you want to add in professions such as mining, blacksmithing, cooking, fishing, leathermaking, etc. Even if there was a method for each of those classes with parameters (like blacksmithing("copper_chest") or cooking("lobster")), then there would be an extra ability and flag for each side profession. What if you have to have a certain level of cooking to cook lobster. There could be 10 types of fish to catch. Do you need a flag for each of those? CanCatchLobster, CanCatchTrout, CanCatch etc... if there are 10 flags per profession and you have 10 professions. That's 100 flags. That's 100 lines of code... 100 variables. Add that to your other 60 abilities and you now have 160 variables just for flags.

Do you see what I mean? Maybe I've gone overboard, but hopefully you understand my problem. What is a more efficient system. Surely WoW and other big MMORPGs don't have 500 lines of code dedicated to ability flags.

Look at a decorator pattern.

Member Avatar for Mouche

Thank you. That's exactly what I'm looking for. I'll keep looking into it, but would it be possible for you to explain how exactly I could implement this? It seems that the decorator classes would be the professions (like blacksmithing). But it seems like this still happens at run time, no?

instances of the decorator are assigned at runtime. When performing actions the action method from each decorator is executed, and only those that recognise the actual command will do anything.

Similarly each decorator can also provide (through other methods of course) information for skill distribution screens, character description, etc. etc., all depending on the interface definition you decide upon.

A standard phrase in modern OO programming is "composition over inheritance", which is what decorator (and similar) patterns provide.
Of course you may use inheritance in designing your decorators, but your tree will be far flatter and you will not have to mix functionality into other hierarchies that really doesn't belong there.

You could try factory methods:
http://en.wikipedia.org/wiki/Abstract_factory

For a game you could have an array/vector like
std::vector<bcAbility> hero_ability;

The base ability class

class bcAbility
{
 string AbilityName()
 void Do()
}

Having a factory class would allow addition/removal/modification of any number of abilities. Actual abilities would be derivatives of the base ability class and the factory class would take care of the initialization. This is a rough explanation, but this method's been in use for a while.


Factory Class Info (search)
Why Pluggable Factories Rock My Multiplayer World

http://www.gamedev.net/reference/articles/article2097.asp
http://www.gamedev.net/reference/articles/article1415.asp

Actually, I'd suggest a combination of the two.

In games like WoW, there are millions of characters, and many duplicates of many different classes. In that case, you never want to describe a character class more than once and there's no need to allow multiple instancing of description data.

So, you define once, and only once, a base class for your character Class and each inherited version (eg. Warrior, Druid). These classes are only accessed through a factory to ensure that character classes (henceforth called CC so as not to confuse with programming classes) that don't exist or require unlocking cannot be assigned.

Also, you define individual factories for skills, abilities, animations, etc. These also need only be described once. Here you can get a little fancy with your specific game data because skills and abilities are going to need to manipulate characters and enemies alike, so be very thoughtful for how you separate character's from their statistics so they can possibly share this with enemies and monsters.

Now the fun part! Usually through scripting (but there are other means such as coded macros), you set a list of skills, abilities, animations, etc. that are contained within each CC. Every CC should load this dynamically and contain their own references to each ability they contain. The reason this is done this way is for editing. You'd be surprised how often beta testing, MOD development, and expansions will drastically change how you'd like your abilities to be spread out. In one version, the Warrior is the only CC with Double Strike, but low and behold, an expansion comes out and suddenly the Paladin wants some of that action too. There's only one static instance of the Double Strike ability, but both CC classes will contain in their dynamic list a reference to it, so that they can both make use of it's description and effects.

Now all you need is to assign each character their class reference. When the HUD needs to show all of your abilities, simply do a character->class->EnumerateAbilities(string &szAbilityList), which returns to you the list of the character's abilities (or have even MORE fun with having each ability containing icons instead of string output).

Now, in this example, let's say a CC adds data to a character that needs supported, such as a character class that gains "charges" from their abilities (think Rogue from WoW). This is where you use decorators for your abilities, and every assignment of a CC to a character should enumerate all decorators and instantiate accordingly.

This is just one idea, give or take as I'm sure it's not perfect, but it's very similar to the architecture that's been used in many older games of a similar type (eg. Neverwinter Nights).

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.