Thursday, July 26, 2007
Frayed Knights Dev Diary: Task Resolution Revisited
Once I pulled at the thread known as the spell system, the entire foundational game mechanics of Frayed Knights just started unraveling. It was rough watching it go, because I'd spent a lot of time on it. But even as it happened, it felt like the right thing. Because deep down inside, I knew the reason that I'd had to spend so much time on it was because it wasn't working, and I'd kept forcing it to fit.
Morphing into a more class-based system was the right thing to do, especially as the player is controlling a party of characters rather than just one uber-character. However, this really meant rewriting my game mechanics from scratch. The old idea of comparing ratios of skill ratings just didn't fit, for multiple reasons. There's only one number to compare, and I didn't want the level ranges to have to become extreme in order for the player to notice a difference in probabilities. Also, since bonuses and penalties would apply directly to your level, they would become less significant very quickly as you rose in level. In other words, a +2 bonus would be monstrous at 1st level, but lost in the noise at 15th.
Va Va Va Voom! Look At Those Curves!
Warning: This is a sleep-inducing section! If you feel your eyes droop, skip ahead to the next section!
So I decided to redo the entire foundational mechanics of the game. Joy. So I had to decide how I wanted it to simulate my imaginary reality.
First of all, in order to preserve the usefulness of bonuses across all level ranges (because a LOT of the game will still be accumulating building up one-shot bonuses rather than progressive skills), I wanted the mechanics to operate based upon the deltas of effective levels rather than their actual ratios or values. So the difference of a level 2 facing a level 3 will come out to exactly the same probabilities as a level 12 facing a level 13.
Next was the distribution to consider. For a given delta between scores, what is the probability of success?
Being a traditionalist, I wanted to center the distribution at 0.5 when both scores are equal. To keep things moving a little more actively, I can skew that distribution a little higher, but that's a playtesting thing.Next was what I wanted it to look like. The "D20" game system has something like this, where your target roll is determined by subtracting the defending score from the acting score, and adding it to 11. The probability curve is a flat line --- the higher the target number, the linearly greater the probability of success. The problem is that is has a fairly narrow range of -9 to +8 before you hit the end of the line, and bump up against the "automatic success / automatic failure" rolls of 20 and 1 respectively. So they have to constrain everything to fit within that range.
Some pen-and-paper RPGs use a bell curve to generate random values for task resolution, but that creates an even narrower range of useable values. Champions (the Hero System) uses this, with a system similar to D20's based on the difference of acting and defending scores, but in practice the only useful range is -4 to +3. The chance of rolling numbers outside that range plummet so far they aren't even interesting.
What I wanted was something resembling a parabolic curve. In practice, what this would mean is that if you are very close to your opponent's skill level, even a small difference will be very noticeable. But as the difference between your skills increases, the difference of a single +1 bonus has less and less of an impact on the direct probabilities. My idea was that a functional range should be around +/- 10, with +/- 5 being very common. But at even more extreme ranges, I wanted to see things be non-trivial. While a bunch of little ankle-biting goblins might not be a threat, I do want to see them be something that can hurt you.Ideally, I wanted to see something where a difference of 1 yielded a +/- 5% chance, and where chances went to +/- 25% somewhere after a difference of 5. And where your probabilities went to only about 10% of success or failure at + or - (respectively) 15.
Not being much of a math whiz, what I ended up with is a really ugly 1 / ( x * square root (x) ) function to get me the sort of curve I was looking for. In fact, here's the actual code:
function DiceCalcChance(%val)
{
%add = 14.0;
if (%val>0.0)
%chance = 1.0 - (%add * 0.5 / (%add + (%val * mSqrt(%val))));
else
%chance = (%add * 0.5) / (%add + (-%val * mSqrt(-%val)));
return %chance;
}
I first wrote it in Python and ran several checks while I played with the formula. I used Python because its an interactive language. Once I had the function about where I wanted it, I translated it into TorqueScript. Here's a sample of the results:
---===== DICE CHECK =====---
1: 0.533333 **** -1: 0.466667
2: 0.584037 **** -2: 0.415963
3: 0.635344 **** -3: 0.364656
4: 0.681818 **** -4: 0.318182
5: 0.722005 **** -5: 0.277995
7: 0.78475 **** -7: 0.21525
10: 0.846568 *** -10: 0.153432
12: 0.874031 *** -12: 0.125969
15: 0.902906 *** -15: 0.0970944
18: 0.922539 *** -18: 0.0774615
20: 0.93233 **** -20: 0.0676703
25: 0.94964 **** -25: 0.0503597
30: 0.960744 *** -30: 0.039256
The formula seems to create the right curve, with a scaler I can use to try and tease values into the right ratio. I'll be the first to admit that there's probably a much better way of achieving very similar results. Feel free to correct me or make suggestions. One obvious alternative is to convert this into a table of results, with everything beyond 30 or so being treated equally.
So How Does It Work?
Okay. Let's say you are a level 5 warrior with a 7 in Might battling a level 6 warrior with Reflexes of 5.
Your attack rating is your level plus your strength, so it's 5 + 7 = 12.
Your opponent's defense rating is his level plus his reflexes, so that's 6 + 5 = 11.
When you attack him, you have a +1 level advantage, which means you have 53.3% chance of hitting on each attack.
Your own Reflexes score is also 5, and his Might is 6, and he is wielding a magical Sword of the Smack-Down which gives him an additional +3 bonus. So his attack rating is a total of 6 + 6 + 3 = 15, to your defense rating of only 5 + 5 = 10. That's a difference of 5, to his advantage, which means his attacks are going to hit you 72.2% of the time.
The battle could still go either way easily enough, particularly if you are both low on hit points to begin with, but over several successive attacks vict very likely to go to your opponent. I hope you brought friends.
What Else Did I Get Done?
Fortunately, I had been fairly smart about how I'd implemented the game system, and I'd put all calls to the mechanics in the "character" class. Between that, and not actually having too much of the game written already, ripping out the guts of the old system and replacing it with the new one was actually pretty painless.
Aside from this, I also worked on spells. The spell system is still far from complete, but I can now cast damaging spells at enemies. In theory, I can cast healing spells at enemies too, but I don't actually have any "heal the enemy" spells in the game. Healing will be a lot more useful when I can have the player target their own party members. Maybe tomorrow.
And Now With The Fluff
Some bits of background lore, for your enjoyment.
The party begins near the village of Ardin. Ardin was a quiet, sleepy hamlet that has recently received an influx of adventurers intent on exploiting the newly discovered dungeons and underground complexes in the area. As such, Ardin has been transformed into something of a boom-town.
The resentment that the locals feel for this influx of ill-mannered "tourists" is matched only by their avarice: the bands of adventurers are bringing plenty of silver coins to the local economy, and traders from the city are making regular stops in Ardin.
One thing has not escaped their attention: Many treasures brought back to town are not long-lost artifacts from before the mage war, but the expensive equipment of previous adventuring parties who never returned...
(Vaguely) Related Various and Sundry...
* Frayed Knights: Characteristics and Task Resolution
* RPG Combat Design
* Lessons Learned Playing Computer RPGs
* The First Playable "Level"
Discuss on the Forums! Or ... not...
Labels: Frayed Knights, Game Design, Roleplaying Games
