How do you do boss balancing in a game where you have a high number of variables?
I came across this problem while working on my game NEO Impossible Bosses, an RTS-MOBA that pits a party of heroes controllable by player(s) against bosses in a boss rush. Each boss needs to feel like an MMO raid boss, which means large health pools and having players do enough damage. In making a game like that, there are many concerns in which we have to account for in our balancing act of making the bosses feel fair enough.
For more context, here's some information on the number of variables that go in:
- Each hero class has up to 6 abilities that do damage.
- You can make a party of 6 heroes, with duplicate hero classes
- Each hero can have up to 6 items. Some of the items contribute to the hero's damage output.
- 3 difficulties for each boss.
And for course, there are things that you want players to feel with regards to each boss. If the boss is meant to be a tank capable of taking tons of damage from the player, he needs a hit point increase.
Fun fact: Your healer can take on bosses solo if he/she wears high armor/damage gear suited for other classes
While it seems like there are countless concerns, I'm confident that we can boil it down to a few manageable variables. Here are my attempts at finding such a system.
Mistake #1
When I started, the way I balanced the boss's hitpoints was a straight linear hitpoint increase per party member based on hero class, and with a base amount of hitpoints. While this seemed initially okay, this method fizzled out when I had a player clear the bosses with a single priest with items..
This formula for calculating the boss's hitpoints is:
[Boss Hp = Base hp + (X hp per party member, based on hero class)]
Mistake #2
So for the rework I defined this problem for me to solve:
- Find a base hit point amount for a boss that accounts for each party member dps, assuming that heroes have unlimited resources.
Seems easy. For each specific hero, find a number for normal attack dps, and per-ability dps, and sum them up together!
Attack dps = Damage * attacks per second
Per-Ability dps = Ability Damage / Ability Cooldown
Potential class dps = Attack dps + ability #1 dps + ability #2 dps + ... + ability #n dps
This formula assumes that all that damage is done within a second. However, some heroes like the Fire Mage have channeling times in which they do not attack at all while channeling their ability, therefore negating the amount of damage dealt. It seems impossible, wrong even, to determine the potential dps of a hero this way.
A breakthrough
So I had to go back to the drawing board. I looked at the hub area, and realized that I had a target dummy unit that was put in for testing reasons. Maybe I could use that! And there was also another thing I was able to draw from my experiences playing and researching on MMORPGs. A while back, a player by the name of Kripparian (that hearthstone superstar) posted videos on certain techniques that he uses to compare between abilities. He also has other videos detailing DPS rotations, a common concept in MMO raiding.
What he did was to find the most optimal set of abilities that would get you the best Damage per Second(DPS) over a certain length of time, via video recording/comparisons. Using this concept, I now simply need to find an optimal rotation per length of time. This length of time is currently set to 15 seconds (which also happens to be the longest duration of hero self-buff abilities), and from this onwards I'll change it to Damage per 15 seconds(dp15s). Through this technique, I solve the problem of that huge mass of independent variables.
Using the Guardian's Warrior Spirit ability as a visual guide, I try to find out how much damage I can do with my Firemage in that amount of time.
Controllable variables
Now that I have a solid dp15s number, I can adjust it accordingly to my needs. Of course, first of all I need to be able to adjust for the fact that in the heat of boss battles, there just isn't enough time and opportunity to execute that optimal dp15s cycle. So I'll need to multiply it by a value less than 1. We'll call this variable 'Suboptimal'.
Boss hp = Sum of [(optimal dp15s * Suboptimal) of heroes]
If I require the boss to feel 'tanky' and be able to take a ton of damage, I can introduce a DP15S_Cycles variable and multiply the above formula.
Boss hp = (Sum of [(optimal dp15s * Suboptimal) of heroes]) * DP15S_Cycles
I now need to account for the itemization bonuses and buffs. The current items can grant you a passive damage boost, an attack speed boost, and an ability damage boost. We'll need to apply a bit of mathematical rigor to get us an accurate gain of dp15s from these bonuses. We'll also need a sequence of ability usage and normal attacks during the 15 second window for our calculations so we can calculate the item bonuses correctly. Then we'll introduce a variable ItemDPSFactor.
Boss hp = (Sum of [((optimal dp15s + item_dp15s * ItemDPSFactor) * Suboptimal) of heroes]) * DP15S_Cycles
This sums up to 3 variables, Suboptimal, DP15S_Cycles and ItemDPSFactor that I can control to tweak the boss's hit points. For each difficulty, I can tweak these values differently – for example I can have the 'Suboptimal' values be lower for the easier difficulties to compensate for less player experience with his hero, since he/she hasn't figured out how to get good dps out of his hero.
Unaccounted variables
There are still some variables still unaccounted for:
Attack speed: There are suggestions that you can multiply the number of normal attacks by the percentage attack speed increase in the optimal dp15s sequence, but that is still likely to be inaccurate, due to the fact that normal attacks are done in between ability usage and in vastly different timing windows – I would have to enumerate all these timing windows and that's a ton of work.
Survivability attributes (eg. Healing, Damage reduction): These are variables that keep other heroes alive so that they are able to do more DP15s cycles. If I use a heal on an icemage, he can deal (for example) another DP15s cycle, If I use it on a tank, the entire party gets to live 1 more dp15s cycle due to taunting mechanics. Furthermore the boss's hitpoints are meant to be static throughout the encounter and most estimates would likely be inaccurate. If I account for this variable, I'll have to increase the DP15s cycle value whenever there's a healer hero.
That being said, it's okay to have slight bits of inaccurancy if you know that it doesn't contribute too much.
So that's all I have for this mathematically charged problem. It's intriguing to me that time has become the basis of the system that is able to boil down the high number of variables into only a few. I might have to increase the window of time from 15 seconds so I can get a more accurate gauge, but the same concepts still apply – I'm able to have a system that can account for difficulty, encounter length, party size and items.
If you've liked taking on MMO-styled bosses but can't find the time nowadays to play MMO games, you might want to look into or the game I'm working on called NEO Impossible Bosses!
Wishlist on Steam! | Devlog link | Twitter | Sign up for the mailing list!