Q&A: Building and balancing Battletech's procedural missions

May 11, 2018
Q&A: Building and balancing Battletech's procedural missions
Game Developer logo in a gray background | Game Developer

Fitting procedurally-generated elements into an RPG means walking a tightrope of careful balancing and tuning, a task that’s made even more challenging when the RPG in question is as nuanced and complex as Battletech.

It makes sense, then, that lead designer Kiva Maginn and the team at Harebrained Schemes attacked generating content for the recently-released strategy game in a layered, complicated way. 

Procedurally-generated missions weren't actually a core part of the Battletech game Harebrained pitched on Kickstarter; they were one of the stretch goals, and when the campaign raised enough money to merit their inclusion, the team had to decide how best to incorporate them into a hand-crafted strategy game with a core storyline.

Gamasutra recently reached out to Maginn to hear more about how she and her compatriots implemented a procedurally-generated mission system that can reliably present players with a believable setup and, perhaps more importantly, an interesting challenge.

Her answers were so fascinating (and so detailed) that we thought you might enjoy reading them for yourself, in full, below.

How are the game's side missions designed/generated? How much of the content in them is set, and how much is procedural?

 

"Too often, games offer you the chance to become powerful, and then instantly scale up the challenge to precisely compensate for your new powers."

Maginn: The procedural missions are built out of three layers. At the bottom layer is the map itself. Maps are hand-created by a designer, using assets created for us by the environment art team, and tools built by our technical art team. Then the environment artists go back over the map and polish it, adding details, filling out areas, sticking rocks all over everything, and so forth. The maps are intended to be large enough that we can stage several encounters on a map without you realizing it’s the same place, and there are some additional mechanics that allow us to switch what structures, facilities, roads, and so forth are on the map on a per-encounter basis.

The middle layer is the encounter. It’s a generic, flavor-free mission, one of eight types. We’ve tried to capture what we think are the most common scenarios in a BattleTech context -- a straight-up battle, a convoy ambush, a targeted assassination, and so forth. All the logic and scripting that makes an encounter work is embedded in the generic version. Designers then use the Unity prefab system to stick copies of the encounter and all its fiddly bits onto the maps. We move spawn points around, drag patrol paths into place, and generally get the encounter properly set up for the terrain it’s going to be on.

The final layer is the contract. A contract contains all the flavor bits that aren’t part of the raw mechanics of the encounter. So if you’re blowing up a warehouse full of weapons, that information is in the contract layer. The encounter just knows this is a mission where you’re going to destroy a base; it’s the contract that supplies the text to describe it as a weapons warehouse. Contracts are aware of the encounter they’re written for, so they map directly onto all the mechanics of the specific encounter; that is, if the encounter calls for two groups of enemies to spawn, the contract must specify what’s in those two groups.

The nice thing is, while maps and encounters are all part of the Unity scenes, the contracts are a JSON layer over the top of that, so they can be built and edited in a text editor. On top of that, I wrote a simple markup language to make contract creation even simpler, and that markup is parsed into the actual JSON the game uses. So we can rapidly create and iterate contracts, and (maybe most importantly) diff them against each other in git.

When you go to take a procedural mission in game, the game looks at the star system you’re in to figure out what maps are available. If it’s a frozen ice world, it’s going to look for an arctic or tundra map; if it’s a desert world, it will look for a desert or wasteland map. Then it looks at all the encounters on that map, and picks one. Then it looks at all the contracts that fit that encounter, and checks to see if you meet the contract’s requirements -- difficulty, reputation, and so forth -- and then picks one. It also looks at the possible employers and targets in that star system, and picks one of each for the contract.

I think the best way to describe the entire process is ‘procedurally generated from hand-created, curated parts’.

How do you balance the side content to be appropriate for the player's power level, without knowing specifically what the structure of their lance looks like?  How do you use main story progression to throttle player progression? 

Trying to figure out how strong a lance is turns out to be the great white whale of BattleTech design problems. There have been multiple different Battle Value metrics, with lots of complexity behind their valuations, but nothing has ever really been comprehensive. Our solution was, largely, to stop trying to understand the strength of a lance, and instead focus on what resources we expect you to have available.

There are two ways we control the overall player power and challenge level: the global difficulty, and travel restrictions. Global difficulty is a value from 1 to 10 that indicates how heavy the enemy ‘Mechs you face are likely to be. We’ve got over a hundred different lance definitions, each one rated by its difficulty, and each one specifying the weight and role of its members. When we spin up a new mission, we decide what enemies to spawn by taking the global difficulty and finding a lance that matches that difficulty. There’s a bit more complexity there, as the contract is allowed to modify the difficulty before it goes looking for a lance to fit, but that’s the basic structure.

The difficulty ticks up at specific events throughout the story, so that as you progress you face harder opponents. The way we handle loot, though, means that an increase in difficulty also means an increase in player power. If you meet a heavier ‘Mech than you’re used to, you have a good chance of being able to salvage it for yourself. So when we tick the difficulty up, we’re also expecting you to grow to meet that difficulty.

At the same time, we give you a fair bit of control over how tough you want your fights to be. Each star system has its own difficulty adjustment; some places are nastier than others. You can always fall back to easier locations if you’re getting overwhelmed by the battles, or push into harder hotspots to up the challenge. Additionally, when contracts are generated, we vary the difficulty by -1 to +1, giving you a range of possible battles even within a single system. If you’re getting stomped and need some recovery time while you send out the B-team, you can probably find an easier challenge.

None of this is perfect, of course, and you can still be surprised by a much harder or much easier mission than what you were expecting. That’s just part of the nature of procedural content, and of the kind of simulation we’re shooting for. If you realize you aren’t going to be able to make a profit off the mission you’re on, you can always retreat -- and if you’ve made a reasonable effort, you will still get paid for your attempt. One of the mantras we’ve repeated throughout the design process is ‘we want you to run away’, and the potential variance in contract difficulty feeds into that mantra.

That said, there are difficulty spikes and troughs that push a bit too far, into territory we consider potentially unfair, and so we’ve started addressing those on a contract-by-contract basis. Sometimes we meant for you to be fighting a tough ‘Mech, but other times we’re asking a mid-game player to fight an Atlas, and that’s just not fair. This is fallout from the way contracts layer onto encounters. The encounter might offer three different ‘ambush’ lances for the contract author to enable or disable. But if the contract author enables all three, she’s going to be asking the player to fight 12 enemies simultaneously. On some maps, this might be reasonable; maybe there’s a choke point, or some high ground with cover. But the contract author doesn’t know that; the encounter might be implemented on a lunar map that’s just a big open space with no cover and no way to cool off your ‘Mechs. That’s a death sentence.

So there’s a lot of moving parts in the difficulty mechanics, and the target isn’t perfect matching of difficulty to player power, but rather ballpark matching, with the assumption that the player can escape a bad situation by withdrawing, or prevent a bad situation by choosing slightly easier missions.

I mentioned travel restrictions, but that actually has more to do with a later question, so I’ll talk about it there instead.

Can you give me any specific examples that came up during development, play-testing, or during the beta of something that broke the balance you were looking for and prompted you to change the design of the side content?

 

"Trying to figure out how strong a lance is turns out to be the great white whale of BattleTech design problems."

The biggest challenge has been matching the difficulty progression in procedural content to the difficulty progression of the story. On one hand, we need to get you prepared for the story mission, which means we need to provide you with ‘Mechs we believe are capable of beating the mission. On the other hand, we want story missions to be major, memorable challenges, with enemies and situations you haven’t seen before and higher stakes than previous procedural content.

There’s a mission about a third of the way through the campaign where you have to stop a Union dropship from taking off. Based on what we expected the player to have available at that point in the game, I built the strongest lance I could -- with the rule that I could only use Medium ‘Mechs. We couldn’t be certain the player would have Heavies at that point, and I wanted to find out if the mission was winnable without them.

I got stomped into a pile of scrap. It wasn’t even close. I went back to the drawing board, trying a few different ‘Mech configurations, seeing if knowing the mission and building for that knowledge would make the difference. It didn’t; I failed three times in a row.

Tags:

No tags.

JikGuard.com, a high-tech security service provider focusing on game protection and anti-cheat, is committed to helping game companies solve the problem of cheats and hacks, and providing deeply integrated encryption protection solutions for games.

Explore Features>>