February 16, 2010

Character Skills

Now that I've covered Stats, I wanted to talk about Character Skills but let's start with a clear definition since skill has multiple meanings in the context of computer RPGs;
In Bogboa, Skill represents the actor's measure of talent when it comes to performing abilities within given categories.
So a player attempting to disarm a trap might rely on an comprehend_traps skill to provide the base number for the success check. Building on the stat post, that base number might be bumped up a few percent if they possess lots of cunning.

Skill Modifiers

The idea is to maintain a list of skill modifiers that vary per guild (character class). The rogue guild might have a comprehend_traps modifier of 1.0 while the warrior guild has .01. This results in a warrior having 1/10th of the trap removing potential of a rogue. If we set it to zero, warriors will always fail regardless of level and cunning.

You can imagine these modifiers like the sliders on an equalizer as we use them to control the relative power of each guild. Creating hybrid classes would be a simple matter of setting a ratio for primary skill modifiers -- a paladin might have a healing skill of .65 and a combat skill of .85 as compared to a cleric's (1.0, 0.5) and a warrior's (0.0, 1.0). If a guild does not list a given skill we treat the modifier as zero.

The potential power of a skill modifier is immense and, like a thermostat that goes to a billion, should be used great care. It's my intention to stick very close to 1.0 as the maximum modifier value*. This keeps power ratios cleanly defined across guilds and relative to mob level. Let's contrive an example to illustrate why this is probably a good idea. We have a designer that wants to create a Cavalier Guild and decides they're like warriors but better with swords. Assuming the warrior had 1.0 sword skill modifier, he gives his cavalier 1.2. Now they are 20% deadlier than mobs their level -- a level 40 cavalier attacks like he's 8 levels above his opponent. This makes them too easy, so our designer bumps up NPCs to compensate and now every other player guild has a rougher time of it.

The designer could try to balance this offense power with lower defense but it's tricky. Sustained damage output sets the rate of experience gain for the character. Unless you implement some form of downtime, almost dying is meaningless.

* An exception to this would be Wizard Guild defense and health modifiers, which will be something like 100000.0 to make them immortal. Conversely, their offensive skills should be 0.0 to discourage abuse.

Skill Caps

Skills are capped at;
actor_level * 10 * guild_modifier
Not much needs explained here; a level 20 warrior with a 1.0 combat modifier will have a maximum combat skill of 200.

Raising Skills

There are many ways to handle this but I've always been partial to raising skills through using them. Most of the skill rating functions (see below) have an optional tutor argument. If this is set to True and the player's current skill is not maxed, he gets a chance to increase his current skill during the check. The chance becomes progressively lower as the player closes in on his current max skill.

Rating Skills

This is the meat and potatoes of the skill system. Using a group of functions, we rate an actor's skill by looking up the current value and applying any stat related bonuses or penalties. The result is a rating: a numeric value used for comparisons and success/failure checks. Some ratings are derived by combining other ratings. For example, a player's hit rating is the average of his melee combat rating and the specific weapon rating for the type of weapon he's carrying. This is to accommodate scenarios like a level 20 warrior who has never touched a mace suddenly picking one up. Even though his skill in blunt weapons is zero, his melee combat skill provides some chance of landing a hit.

It's a small shift it perspective, but thinking in terms of skill ratings was something I found helpful.


We've already covered that we'd use skill ratings for deciding success but not how those rolls will be calculated. Here's an example for striking with the player's primary weapon. Basically, we pick a random number in the range of 0 to (defender's defense rating + attacker's hit rating ). If the number is higher than the defender's defense, it is a hit. You can see how either value grows, probability will shift accordingly but the attack always has a chance to hit.

def primary_weapon_test(src, tar):
Test for a hit using Source's primary melee weapon.
hit = skill.primary_hit_rating(src)
defend = skill.defense_rating(tar)
return bool(random.randrange(defend + hit) > defend)

One of my goals is to avoid hard-coding rules as much as possible. So rather than telling a magician he cannot use plate armor, I'd rather use his guild's skill modifiers to provide more benefit and AC from a robe but, if he really wants to, he can dress up in heavy plate. Same thing for weapons.

Similarly, learned abilities wont be guild specific but will require certain skill values to obtain. A potent healing spell might be available to a cleric at level 10, a druid at 20, and a templar at 40 depending on their healing_magic modifiers.