Advertisement

How do you code Skills/Abilites for characters in a Turn-Based RPG Game?

Started by May 13, 2024 07:59 AM
3 comments, last by SeanReid 5 months, 2 weeks ago

So I have been studying game programming for a while now, and something I can never figure out is how you code a skills for characters.

For example, imagine you have a game where a character can perform an attack, a unique skill, and use items. Lets say all characters use their 100% of their attack stat when performing an attack, and all your characters can use any item available in your inventory. In this case, you can just create a class for characters and code the function to perform an attack and use items, because all characters can do the same thing.

But then how does one go about making unique skills? For example, a skill that:
1. Compares the user and target's current health, and deals 200%/50% of the user's atk depending on if their current health is less/more than that of the target
2. User deals damage to target, and if that damage results in a kill, the user can then get an extra turn
3. After performing the skill, the user switches places with another character in their party, etc.

Another example would be in card games like Hearthstone or Shadowverse, every card has their own attack/defense stats, and they have unique effects when played

EDIT: I'm most experienced with Unity so if anyone could explain to me in the context of Unity I think it'd be the most helpful

Don't know Unity, but who said you can only have 1 class to perform a skill?

Make an interface for FooSkill, then implement 3 classes: FooHealthCompareSkill, FooExtraTrurnSkill, and FooSWapPersonSkill

Persons can have an instance of one of those three classes, et voila they do different things with the FooSkill.

If you want to do this trick more often for different skills, it will be beneficial if you break down the skill in a sequence of smaller steps. For the Foo skill, you could

1. Decide how much attack you use

2. Do damage

3. Do something additional if a kill occurs

4. Do something afterwards.

So now you have 4 separate steps that are not directly tied to the “Foo” skill, but apply in more skills (perhaps only the 2nd step would be Foo specific in having some visual effect or so).

For each of these 4 steps you can now do the above trick, and make several implementations for each of these steps. Then you make a generic skill that simply does the 4 steps in sequence.

Since you have several implementations of each of the steps you can easily make many different behaviors just by instantiating 1 class for each of the 4 steps in the generic skill.

Note there is no inherent reason why you would have to stop here. You can almost endlessly create new intermediate steps or refine existing steps to make more different combinations.

For example, instead of the 3rd step above, you can split it further, and eg decide to have

3a. Decide if a special condition applies

3b Do something additional if the special condition applies.

With this change you can have more variations for the “extra addition”. Not just if a kill occurs, but also eg if it is mid-night, the person has eaten in the last hour, or whatever.

Advertisement

@Alberth maybe interfaces may be just what I was looking for, I'll look into them. Thanks for the suggestion! I'll try it out right away!

It will be quite challenging for me to answer briefly, but I will try my best.

At its core, you would define skills as game objects much like how players, enemies, treasure chests, trees, etc are defined and instantiated. A character in your party will have instances of skills which have executable code via functions. As you've mentioned, this is where interfaces come in.

The piece of advice I can offer is that you would define the very basics of your game including basic skills like Attack. Once the basics are implemented and the game works, you would start to mod your own game like you were defining a plug-in system. For example, at the moment an enemy takes damage, you would implement a “OnCharacterDamaged” with a set of values relevant to the event.

If you have a gear system where the gear is also implemented as objects, the sword also can receive the “OnCharacterDamaged” event. The reason for this is because perhaps the sword is poisonous, and you can use that event on the sword object to apply a damage-over-time object to the target character. Then, the damage-over-time poison object can have a function such as “OnTurnEnded” function, so that at the end of each turn, the affected character will take additional damage. Be careful with recursion, but the poison damage could also implement the “OnCharacterDamaged" function – not to generate more damage, but perhaps to trigger a moment that damage number FX need to be spawned or poison cloud particles.

Going further into the example, a nearby ally could have a magical tunic which heals adjacent allies whenever they take poison damage specifically. The point here is that everything you can imagine could be a game object (gear, skills, items, damage-over-time, environmental state like rain, snow), and it will have a “Battle Encounter” interface implemented which is a definition of a wide range of plugin-style events.

I've used this overall design for Plague Road, and each object is powered by a Lua script to receive such events. One intricate example is the Witch's “Maelstrom” skill which casts a global rainstorm effect where all enemies are slowed (their movement range is reduced). I am able to alter the A-Star pathfinding to reduce the max movement by X% in such a plugin-style response (e.g. “OnGetMovementPathForCharacter”).

None

This topic is closed to new replies.

Advertisement