November 29, 2008

Why variables are a combat designer's best friend

When people find out I design videogames for a living, and invariably ask me "yes, but what do you DO," I often joke that if you sat behind us and watched us work all day without knowing our job titles, you might think we were a bunch of accountants on casual Friday. MMO Combat Designers in particular spend a large proportion of our day dealing with numbers in various forms. For example, every power, item, piece of gear, aggro range, AI profile, and character are all big clouds of data, comprised mainly of a huge amount of numbers, with a few text strings (display name, description) thrown in.

A misconception that many people have about tuning a game is that designers actually go through and type in specific numbers for every value in the game: "This creature will have, hrm, 247 points of health, and its attack will hit for, oh, let's say 37 damage every 1.7 seconds." If you've got thousands of creatures in your game, the first pass of tuning alone would take an incredible amount of time to enter and test, and more importantly, revisions would be incredibly hard to do. If you decide you need to revise all [5 thousand!] of your enemies to have 8 percent less health, and you've entered them all by hand, there's not much to do but have a good cry and cancel your weekend plans.

This is where abstraction (also known as variables or references), comes in. Using a variable to stand for a number is a common practice in all aspects of game development and programming, but your first exposure to it was probably 7th grade algebra (If A = 5, and B = 2A, then B = 10).

You can create a central database for your game where different amounts of health and damage are defined and assigned variable names, for example Normal_Creature_Health and Normal_Creature_Damage. Once defined, you can now use these variables to tune a creature in a way that does not require literal numbers: "This creature will have 1.5*Normal_Creature_Health as its hit points, but its attacks will only do .5*Normal_Creature_Damage."

Setting tuning up with variables has several benefits to designers and players:

Benefit 1. Any other designers who look at this creature can clearly see that it's doing less damage than other creatures but has more health, without having to look through several other sets of data for comparison.

Benefit 2. The variables Normal_Critter_Health and Normal_Critter_Damage can be defined in a central location, and dynamically multiplied by level (Normal_Critter_Health at level 1 = 40, while Normal_Critter_Health at level 2 = 44, etc).

Benefit 3. The same is true for other pieces of data. Perhaps a creature marked as Epic gets its health points multiplied by a further 1.5, after its level has been taken into account.

Benefit 4. Now when defining creatures, all that's important is making sure the creatures are balanced against each other. As long as a big brute has lots of health, and the weakling caster has very little health, in a ratio that is properly balanced, it won't matter later when someone need to go back and tune Normal_Creature_Health to be 235 instead of 892.

Benefit 5. These numbers can be abstracted even further. If most brute creatures have 1.5*Normal_Critter_Health hit points, and most casters have .7*Normal_Critter_Health, why not define new variables called Brute_Health and Caster_Health? Suddenly, instead of having to type a number at all for a creature's health, it becomes possible to just choose its category from a list that includes Brute, Caster, Healer, Hostage, 5_Man_Boss, Exploding_Barrel or anything else that will come in handy for your game. Then, if you like, you can still have the option of adding multipliers to those values per creature, or just leave the field for modifiers off and agree to never worry about an individual creature's health again.

Benefit 6. Tuning health through these variables will always allow your players to accumulate knowledge of how difficult a given creature will be, and to feel more like a master of your game. (How to keep players informed, mastery, and the benefits of standardization are all likely candidates to receive posts of their own some time soon.)

After seeing how variables work for creature health, it's not much of a stretch to see how they could be applied to other areas of the game.

  • You could add in damage numbers to match all of the creature types (Caster_Damage, Brute_Damage, 5_Man_Boss_Damage) and allow those to be called by an attack power.
  • You could define variables for small chunks of a given attribute, and apply those to gear (This sword gives the user some damage and some health, in the amount of 3*Item_Damage and 2*Item_Health).
  • You could tune quest rewards based on fractions of XP_Hour, the amount of XP the player is intended to be able to earn per hour .

There are also ways to get the functionality of variables without a game engine needing to support it. I have a friend who worked on a game that didn't have much in the way of editors or tech support for designers, so he created a big spreadsheet that handled all his variables and dynamically generated a ton of data, which then then pushed to the game data with the use of a script he had written. It saved him a lot of time, but obviously this method can be a lot more dangerous if you're not as good with scripting as he is.

No comments: