I'm currently prototyping a silly management sim about public restrooms - keep the impatient cafe hipsters happy, stave off the hobos in a library, and prepare for the lunch hour rush! Is your bathroom good enough even for the Popeâ€™s tooshie?
As I mentioned before, there is a lot of variables to take into account! From per-patron stats like happiness, temperate tolerance and homophobia, to global stats about cleanliness and comfort level. Once I got all the systems in I realized - this is really hard to make sense of!
From a balancing standpoint, what does "Patience Depletion Rate" really mean? How can I juxtapose radiatorâ€™s â€śheat rangeâ€ť against personâ€™s â€śheat tolerance level?â€ť I was struggling with adjusting my stats and variables until I had an epiphany.
The problem wasn't my system - the problem was my naming conventions.
My variables made logical sense for the game code, but not for the designer. I set out to rename all my stats, shifting from â€śhow does this workâ€ť to â€śwhat makes most sense to me?â€ť
One important variable is a personâ€™s patience. If they have to wait too long to make a poopoo or wash their hands, they will get increasingly impatient and angry. I start off with everyone at 100% Patience that slowly drains as they wait, multiplied by my crucial â€śPatience Depletion Rate.â€ť
Logical right? But not easy to balance! Adjusting the "depletion rate" was a blind guess until it felt right. Combined with 10 other similarly ambiguous variables, trying to make the whole system work together was a nightmare.
Patience = CurrentPatience - PatienceDepletionRate * DeltaTime
So I redid my calculations to replace Patience Depletion Rate with WaitTime, or how long it takes before happiness hits zero and person storms off disgruntled. The math got marginally more complex, but the designer's job much easier.
Patience = CurrentPatience - (1 / WaitTime) * DeltaTime
Now it was easy to make sense of it! â€śOk so a minute is how long a person will stand waiting! Half a minute will drop them to half patience." Now I had something tangible to balance.
Another problem were my radiators, modeled after beloved Theme Hospital. A person has a certain temperature min and max they tolerate and outside of that their comfort decreases. Too few radiators spaced too far and it gets cold, too many and it gets too hot. Tracking a temperature is a simple matter of a â€śHeatStrengthâ€ť variable on the radiator, right?
Foreach( radiator ): TotalTemp += HeatStrength / DistanceToRadiator
Yet a nightmare to balance - â€śso, uhh, how far can a person stand from a radiator? What if I have 2?â€ť I couldnâ€™t even imagine having more in my head. So I changed the stat to HeatRadius.
Foreach( radiator ): TotalTemp += (HeatRadius - DistanceToRadiator)/HeatRadius * 100%
Boom. At half the distance, half the heat. Right next to it, full heat. Note I also change from â€śdegreesâ€ť to % as unit of measurement since, effectively, thatâ€™s all a designer cares for - what is the range of comfort? A 50%-90% scale is easier to think of than 65F - 85F.
(Minor note: I ommited Clamp to 0-1 range for the heat radius calculation for brevity. Don't forget if you dont want negative values!)
Letâ€™s tackle something more useful for most devs, an RPG where weapons slowly break over time. A dimple â€śdepletion per useâ€ť rate seems sufficient, right?
OnUse: Durability = Durability - DepletionRate
But again, arbitrary! Lets change it to:
OnUse: Durability = Durability - ( 1 / UsesBeforeBroken )
Bam - now whatever value I set I instantly know this is how many times the weapon can be used. I donâ€™t need to do any mental math to make sense of my system, the system does it for me.
The point I am driving here is - name your balancing config variables to make sense for your designers, not the code. You can always convert between different style of stats, but make your code do the conversion, not your designers. Few extra tips:
Keep variables direction consistent - either high is good or low is good. For example, Health (high good) or Weapon State (high good). Rename other stats to match, i.e. Fatigue => Energy, ItemUseCount=> ItemDurability etc.
Keep your math linear if you can - a lot of things in physics follow the Inverse Square Law, producing an exponential curve (i.e. 1/(Distance*2) ). Cheat it to be linear (1/Distance) if you don't need complete accuracy, it is much easier to predict. When you double your distance, you cut the effect in half, not by four.
And lastly, think what units are easiest to make sense of! Oftentimes, a percentage rating is much easier to tweak than an arbitrary scale or, god forbid, the US metric system. You can always convert an optimal Temperature % to Fahrenheit if the game lore requires it, but make it easy on your developers. If you know all stats must be >50%, that takes a lot of needless mental math out of designer's job!
Hope this is useful!
Karaski: What Goes Up... is a an open-ended, story-driven stealthy adventure game that takes place onboard a sabotaged 1920s Airship - who is the saboteur, who can be saved?! Deus Ex meets Clue with a bit of Telltale!