Designing / Organizing code for skills and magic

Started by
5 comments, last by Caldur 15 years, 9 months ago
Hey, first post here. I'm writing a Rogue-like game in Java. My development process so far has been logged at: http://mycaldur.com/messagelist.php?board=3&topic=40 Everything has been going well so far. I've come onto a stumbling block though. I can't figure out how I want to set up the code for skills. Here's a quick run through of a few of the classes that will affect the problem: Character - The class that holds all information about each playable character. It has several other classes as fields within. It has an ArrayList of Skill classes. Skill - The superclass for skills. Has a type field, which will be used for offensive, healing, defensive, other, etc. etc. I'm just not sure how I want to organize everything for this. I'm sure I could hack my way through it, but I want it to be flexible, expandable, and well-written. The problem is, skills can do so many different things, I'm not sure where I want to put the code for it all! My only idea was to create a subclass of Skill for each different skill type. Skill would have an abstract method cast. Each subclass would contain the code inside cast. So then in the code for my battle class, I could do something like: (c is a type Character; mob is an enemy) int damage = c.cast("Lightning"); mob.setHP(mob.getHP() - damage); etc. There are a couple problems with this approach. If the Skill class is just in an ArrayList inside my Character class, it doesn't really have access to the character or the enemies statistics, which would be needed for stats such as intelligence, defense, etc. I'm basically just looking for a good way to do this. I'm sure I could do it if I just sat down and started writing code, but I want to do it a good way, and my brainstorming hasn't come up with much. Thanks for any help! ~Caldur
Advertisement
And the usual rule applies. If an object needs to know about two other things, it needs to be separate and above them.

It would be better I think to have the 'player has this skill' be separate from 'skill-activation'. The skill activation then checks if the actor of the activation is able to do the action, and if the target is valid. It then can take sp, do damage, etc.
Could you maybe layout a diagram of the classes you were describing, please? I don't understand how to make a Skill class be above the Character class..
I would suggest delegating everything to the skills, and giving the Skill class a method like this:
public virtual boolean cast(Character caster, Character target);
Which either performs the given skill and returns true, or returns false if the caster cannot (not enough mana, cooldown, etc.), or if the target is invalid. You can then continue to store skills in an array/list, and the skill will be able to query the caster during the cast.

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

Hm, yeah I like that, and I think I can make it work. Thank you!
Quote:Original post by Caldur
Skill - The superclass for skills. Has a type field, which will be used for offensive, healing, defensive, other, etc. etc.

What would this type field be used for? I don't see what use cases it would be useful for, since normal skill object access would be from the player to all of them (e.g. given the "use skill" command, list all skill objects, display them in a menu, and choose one for activation with player-selected parameters) or from special cases in the game engine to named skills (e.g. when the player is injured, check if he has enough First Aid or Regeneration to stop bleeding immediately).

You should also put the Skill objects in a Map, not in a List; they can be expected to be looked up by name very often, and they are not inherently sorted.

Omae Wa Mou Shindeiru

Well, I was thinking that the type would be an integer that specified if the skill was offensive, curative, utility, other, etc. My reasoning was that the cast method would require different arguments. But after thinking about it, I guess this isn't needed. For instance, the skill "Illuminate Floor" doesn't need a target character. However, I can just pass null for the second parameter, so that doesn't matter.

And yeah, I've got the skills set up in a HashMap within each skilltype's subclass. Then in my Character class I have an ArrayList of those skills. It seems to work pretty well I think.

Thanks for all the help!

This topic is closed to new replies.

Advertisement