I’m having troubles wrapping my head around how to organize the classes within my RPG project that I’m making. I’ve tried to implement a battle system but I am not comfortable with my initial results.
This is the basic layout I currently have for my classes.
clsCharacter > clsTeam > clsBattle
clsCharacter contains statistics pertaining to one character, including magic available to that character to use. Also includes what weapons that character has equipped.
clsTeam contains multiple clsCharacter, as well as a list of items that each clsCharacter in the team can use.
clsBattle contains two clsTeams. One team is the player and the other is the computer.
Now, this is a wonderful way to organize data. However, I see limitations with this approach. For instance, to pass data from Battle to Character, it has to pass through the team class and vice-versa. Plus, if I use Properties, it transfers data as ByVal instead of ByRef, so I cannot guarentee that I’m editing the original and not a copy of the passed object (IIRC)
In addition, I feel it is just messy code to include methods within the clsCharacter class that invoke this: MyTeam.MyBattle.DoAction(). Plus, the clsCharacter might not even be in the battle at the time – I don’t won’t to bog down that class featuring code that is exclusive for battling when I also need to be concerned about moving around the map, saving/loading data, etc.
So, any suggestions? Right now, I’m burnt out of ideas. One idea I have so far is to include a function for the clsCharacter that exports a list of all possible moves the character could make, and if the character is CPU choose the most optimal one, and if Human than wrap it up in some nifty GUI so they can choose what action to take. But at the same time, how do I use that information within the context of the battle?
NOTE: This answer ended up being WAY longer than I expected, but I taylored it specifically to your RPG situation, so hopefully you find it helpful. It might be useful to actually copy the code into a Console application and play around with it to understand how it actually works.
Have you considered using interfaces in your design? I think they would really help a lot. I asked a question a week ago and got some great suggestions about using interfaces with Dependency Injection.
Using interfaces, you can avoid thinking “what containers of data do I need to perform this action?” and instead think “what action do I need?” Here’s a simple example of how you might model your code to pull out the method of attacking in a battle:
In the above code, the
Battleclass only knows that it needs an object that implementsIAttacker. It doesn’t care how that object implementsGetAttackDamage(), only that it can call the method when it needs to. TheNameproperty is also abstracted into the interface. See the following procedural examples of how this might work:Hopefully you can see from this (woefully lengthy) example the advantage of using interfaces to help encapsulate specific functionality. This allows you to decouple the functionality you expect from a class from the class itself and allow the objects that consume that class to call the functionality it needs directly through the interface.
In the example I showed, the
Battledidn’t care if it had a character. All it need to know about was that it had things that could attack, that is, things which implemented theIAttackerinterface. Because we wrote it this way, we weren’t limiting our battles to justCharacters. We are also giving theBattleobject only the things necessary to fight. TheBattledoesn’t necessarily need to know about all of the experience points, items, pets, etc. associated with an attacker. The only thing it cares about is that when it asks for the total damage that an attacker can give, the attacker provides that information. EachIAttackermight implement it differently, but that’s OK, as long as theBattleobject gets the information it needs.If you mix interfaces with base classes in your design, you’ll be off to a very good start in structuring your class hierarchy.