Jan 23 2012

SYSTEM DESIGN

Today I’ve been reworking how combat stats (most importantly attack and defense) function in Cardinal Quest II. This blog entry’s going to be quite dry and mathsy, so if that’s not your bag feel free to come back on Wednesday when I’ll have more screenshots. 😀

See, design work isn’t all about interfaces and player choice. In many games you also have these systems on the back end handling damage, % to hit, movement speed, etc. This is where tables of statistics come in, and balancing those statistics is super important to balance units – but before that you need to nail down how the statistics interact, what calculations they get involved in, and that’s system design.

Cardinal Quest 1’s “chance to hit” formula is the main thing I’ve been tweaking today. It uses two stats – the attacker’s Attack stat and the defender’s Defense stat.

% to Hit = 100 * Attacker.attack / (Attacker.attack + Defender.defense);

To really understand how even a pretty simple formula works you need to visualise it. It’s a good place to break out a spreadsheet, run the numbers and draw some graphs.

The important thing is, the lines go up! The higher your attack stat, the more often you’ll hit your target. Also, lower Defense stats on your enemy mean you’ll hit them more often.

That’s groovy, but… there are some issues here. Firstly, the exact number for each stat gets less important the bigger it is. The difference between 1 attack and 2 attack or 1 defense and 2 defense is huge, but there’s hardly any difference going from 6 to 7.  Secondly, almost all of our % to hit calculations are bunched in between 40% and 70% to hit. That’s going to make our classes feel a bit samey in melee combat.

We’ve got a system where, halfway through the game, adding 20% to your attack can alter your chance to hit by less than 5%. That was fine for CQ 1, but in Cardinal Quest 2 with its talent tree system, every single point needs to matter. So this has to change.

Here’s where we need to lay down some goals for redesigning the system.

  • We’ll keep to the two attack and defense stats. We could add a mechanism for reducing damage or add a separate armour stat, but really that stuff’s redundant given we can just give the player more hit points and achieve the same effect.
  • If the attack and defense stats are the same, the % to hit should be 50%. This feels like a good middle ground. If we reduce that neutral chance to hit too far, it’ll slow down combat; if we increase it there’ll be no headroom for higher stats to kick ass.
  • How far you are through the game shouldn’t affect the importance of a single point. In the old system, the first few points of attack or defense had a huge impact, but once players and enemies had eight points or more towards the end of the game, each further point added very little. We need to fix that.
  •  Investing a single point in attack or defense should be able to improve to-hit odds by 20%.  This is just a quantitative target for “one point should matter”. Improving your attack should take your attack stat from 41% to 50%, or 50% to 60% (both of these are 20% jumps); likewise improving your defense should send things the other way by a similar amount.

Point 3 – how far you are through the game shouldn’t matter – tells us we need to stop caring about the absolute values of each statistic and only look at them relative to each other. In other words, we just need a formula that takes a single input: Attacker.attack – Defender.defense.

At this point I went back to the spreadsheet and started roughing out some numbers that felt good for various values.

The column on the right shows how much of an improvement that row is vs. the row above. Each point from -2 to +2 increases the hit chance by 20% relative to what it was before, so we’ve met our 20% goal where it really matters. We then tail off from that in either direction.

That’s where I hit the first snag: you can’t actually have a 115% chance to hit, and really I didn’t even want to use more than 80% because it’d take too much of the randomness out of combat. However, if I limit the top end to 80% and keep the differences symmetrical, we’re back to everything interesting happening in the 40-70% range. That’s so narrow, we’d have to compromise our 20% goal. We can’t scale all the percentages down either, since that wouldn’t meet our goal of having the “break even” chance to hit be 50%.

Fortunately, there’s a common mechanism in RPGs for doing more than 100% damage and keeping an interesting level of probability involved in the process. It’s called critical hits.

I added a row for a chance to do double damage if your hit connects, chucked in some arbitrary values and had the spreadsheet work out the % to hit needed to combine with that critical chance to give the correct damage, on average.

Result! The high end fits under 100% and there’s still an interesting element of probability even with massive attack/defense imbalances.

Let’s run that graph at the top again with the new system.

So how much does this graph improve on the first one?

  • Every line goes up at a decent, consistent angle, meaning that every single point you invest in Attack is equally meaningful and valuable.
  • The lines are evenly and well spaced, meaning that improving your Defense is pretty good, too.
  • Our chances to hit (+crit) are spread out over the 30 – 100% range, not just 40-70% as before. That means the whole system is way more important and its effects are going to be way more obvious.

We have a winner! So, what’s the new formula to go into the code?

Honestly, there isn’t one. I could probably work one out! It’s an exponential curve in the middle and it flattens out towards limits above and below. But why put in the effort? This isn’t World of Warcraft or Disgaea, with key stats well into four or five digits. The stats used in CQ have quite a small, discrete range. I can get away with just writing that table of hit chances and crit chances into the code.

So I did. 🙂

System design may feel pretty abstract, but anywhere stats show up work like this is key. Not just to ensure that stats are balanced, but to ensure they can be balanced. It’s the foundation of a well-balanced stats system, whether it’s for an RPG, a strategy game or an action game with RPG elements. Getting that straight is totally worth learning what an exponential function can do for you and poking around OpenOffice Calc or similar.

5 Comments on “SYSTEM DESIGN

  1. I wrote about something a bit similar to the Roguetemple forums a couple of months ago. It specs out a reasonably straightforward formula that satisfies similar goals as you have, no separate critical hits though.

  2. Just watch out that you don’t create a “no matter how hard you try you are always the same” system. For example, if the monsters increase their attack and defense levels at the same rate the player does, you’ve just implemented the most hated feature of Oblivion.

  3. @rsaarelm: Hey, looks interesting. Good to see someone else coming to the similar conclusions.

    @Burzmali: Haha! No, no way. There’s a fixed difficulty ramp, so smart character build choices will definitely make the late game easier.

  4. @randomnine I’m sure you’ll be fine, it’s just a friendly warning. Balancing longer games to prevent players from trivially min-maxing a relative system while not being brutal to generalists is a non-trivial task. Short games are usually better served by hardcoding all possible interactions of attack and defense values.

    Consider for a moment magic items, a ring of attack +1 is just as important on level one as level twenty. A ring of attack +5 breaks level one as much as it does level twenty.

  5. Oh yeah, for sure.

    In CQ2, the ramp up of the enemy stats in the game is balanced against the expected ramp up in player + item stats. We have a lot of control over that – it’s a linear game so we know the XP level and gear with which players will enter each level. Your ring of attack +5 will tend to show up later, when the enemy defense stats tend to be several points higher. It’s inflationary, for sure, but that points inflation is a necessary pressure to push people to mix their gear up as they progress.

    As for specialists vs generalists: though the class system, talent tree system and different methods of dealing damage encourage specialisation, each stat has diminishing returns once you surpass your enemy’s relevant stat. If your Attack is more than 3 points higher than your opponent’s Defense, additional points are gradually worth less and less – until an opponent with a higher Defense value comes along.

    In addition, certain enemies will be strong against certain approaches but weak vs others, punishing over-specialisation. You won’t be able to change gear when you’re in combat or easily carry around alternate gear sets, either.

    I don’t know if that’ll all solve it, but we definitely have these mechanisms for tilting the balance either way until it feels right 🙂

Comments are closed.