Your character has 1,000 hit points.
Your flaming sword does an average of 100 damage.
Your enemy has 3,000 hit points, does an average damage of 125 damage with their claws and has a 25% negative resistance to fire damage.
Q: Are you boned?
Scaling and, by extension, balance are a key challenge for RPGs. If you're off in either direction, your game could be either too easy or frustratingly difficult-to-impossible. You want to hit a sweet spot: players consistently challenged, but consistently able to overcome those challenges (see optional post-rant, below, for more on this topic).
I've been wrestling with scaling lately as part of my sim/RPG hybrid game project which is currently in development. Based on recent Twitter feedback and suggestions that I blog about my strategy, I'm not alone in this. So, I'll outline how I tackled initial scaling design for my game in hopes that it might help you, budding game maker, find your way forward a bit faster than I did.
Step 1 - Pacing
At the core of my game, the player is responsible for hiring, equipping and ordering around vict... explorers. These explorers venture into increasingly dangerous portals to unknown and unpredictable locations and encounter traps, enemies and the occassional piece of sweet loot. The game expects your explorers to die periodically--small bumps in your linear progression through the game. Therefore, the pace of my game is dictated almost entirely by the exploration mechanic and mortality rate.
Each portal exploration in my game involves a number of encounters. A short exploration might have 5 encounters, while a long one has 10. An additional variable paces exploration by determining the length of time between these encounters.
Explorers wear "frames" which protect them from damage--basically, their health pool. Traps and monsters deal damage. The explorers have a limited inventory capacity and can carrry, among other things, items to recharge their frame capacity. If they sustain enough damage to deplete their frame and they have no way to recharge it, RIP. They have to survive all the encounters before they can portal back to the ship. There are no random supply stores on an alien star. Space is a harsh mistress.
Therefore, if I want to kill a reasonable % of explorers, I need to ensure that traps and enemies do enough cumulative damage for an average number of encounters to exhaust a full inventory of frame rechargers. This is a simplified view, of course, ignoring other mechanics. But this interaction forms the core of scaling in my game:
- If the explorers do too much damage, they won't take enough hits to ever die.
- If frames have too much capacity, monsters won't do enough damage to exhaust an explorer's power cell supply.
- If explorer inventory is too large, power cells will make them pseudo-invulnerable.
That is an abbreviated list just to give you a taste of the knobs and levers. Most are variations on those, above.
Step 2 - Health Pool
The next question I had to answer was, at each level, how much of a health pool should an explorer have? I decided on the following baseline:
- Level 1 = 100 (minimum)
- Level 40 (max) = 9999 (capped)
Short answer: I like those numbers.
Long answer: The difference between those numbers is significant enough that a level 40 character looks and feels godlike compared to a level 1 character. Additionally, I want to create a David and Goliath situation where the monsters have much more hit points than the explorers. The monsters have a max of 999,999.
That looks unfair, but if you have good weapons, you'll punch above your weight and if you have a good frame with high resistances, you'll mitigate a % of the damage up front. The fights are just as fair, mathematically, as if max health pools were even. But I want them to feel epic. The explorer should feel like a human fighting an alien hegemony or a hypertrophic organism the size of a small star. But they should be able to pull it off thanks to their insane loot. Most of the time.
Step 3 - Math O_O'
WARNING: I'm about to mangle some sacred mathematical terms. Please forgive me. Hopefully the end justifies the medians. Means? Whatever.
Now that you have your health pool range, you need to pick a scaling model. How much "reference" health should an explorer in average gear have at any given level? If only it were as simple as 100 + 9999 / 40. Sadly, it's not.
I went with a linear scale. And because I'm bad at math and decent at Python, I tweaked a script until I got a scale I liked:
>>> curve(110, 1.12)
The "curve" function I wrote just starts at the first parameter for level 1 and then scales it by the second parameter each level for 40 levels. I simply tweaked the second paramemter until I got a curve that arrived near my desired cap of 9999 (a bit under, which is perfect because "average" level 40 gear should leave significant room for above average gear to shine). I rounded everything to the nearest 5, for aesthetics. So an "average" level 10 frame should have about 305 capacity. A better frame will have more than reference, whereas a crappy frame (or one with a gimmick, such as low capacity but regeneration) might have a lower capacity than reference for that level.
As you can see from reading the curve, this sticks with my goal of having the difference between each level feel progressively more meaningful, numerically. AKA, linear.
Is this the only model you can use? Definitely not. There are other formulas you can use that will achieve different results.
An exponential function might be appropriate for a Gurren Lagan-themed game where each level is increasingly, massively more powerful than the last. It comes with some downsides, though. First, you're going to be spending performance on stupidly large numbers. Second, the difference between gear by level becomes so severe, so quickly, that it's functionally impossible for a character to survive an encounter one level above their own. That fact alone would eat a ton of design space for breakfast.
You might want to create a game which is fast in the beginning, slow in the middle and then fast again towards the end. There are models for that. You could even go with a cosine wave or something. I would recommend avoiding being too creative here--there's generally a reason linear progression has been the defacto since I got hooked on 8-bit RPGs. Put the slow part at the end, when players are bought in enough to not require constant achievements to keep them motivated.
Step 3 - MOAR Math X_X
So, I know the average encounter length, I know the health pool for a given level, and I know my desired mortality rate (muahahaha), I know my power cell limits. The next thing I need to figure out is how hard an average monster or trap needs to hit the explorer to force them to use a power cell at a rate that runs the risk of killing them.
I'll spare you the deets on this one. I created a big, but simple spreadsheet that calculates hits-to-kill from the player's health pool at each level. I can adjust the reference damage-per-attack until I arrive near the desired number of whacks an explorer can take before having to recharge. It also factors in resistances, based on a reference of "how much average resistance should gear have at this level?" Then I turned it around and did the same thing for monster health and player damage.
Now I just have to make like a bajillion pieces of gear...
Will it Blend?
This is my first game. I cannot guarantee that this approach will work, although the fundamentals are sound. Of course, I'm not going to invest tons of money into promoting a game that might not work. How do I test it? Preferably before I subject vic... supporters to the beta?
This is where I turn to my friend Xzibit:
My plan is to code basic simulations. Pick an explorer level. Gear him/her up. Pit him/her against a random sequence of monsters at the same level. Clone 500 times. Repeat X adventures. How many died? How many power cells did the survivors have left? What happens if I make the adventure shorter or longer? What happens if I give them slightly better or worse gear?
I'm going to sim my sim. It's as sim-ple as that. Maybe I'll blog about how that goes!