lua

Procedurally generated missions in Spy DNA

By Alex Maier, Writer of Words

Here’s a basic overview of how we generate randomized missions. We’ve built a Mission Editor tool for that, and here’s how it looks when you open a mission in it. Here we set all the basics for a mission, such as terrain type, time of day, and so on.

Spy DNA mission editor "Map" tab screenshot

Then we add all the interesting stuff, like the NPCs you’ll encounter on a mission: enemies, neutrals, people to be rescued, that sort of thing. This is also where we add eligible infiltration options. Not every infil option makes sense for every mission, so we make a list of the ones that do for a given one, and also describe the outcomes.

Spy DNA mission editor "Gameplay" tab screenshot

When the mission is generated, only a subset of the infiltration options are picked.

Generally, you’ll see four kinds of infiltration outcomes, and each of them influences the mission at spawn:

Outcome

What it means for the mission

You did great and have ALL the intel

You’ll see mission markers for some of the objectives, such as hostage location and enemy camp HQ, or enemy patrols won’t be concealed by the fog of war.

You did okay, and have some intel

You’ll see a mission marker for the some objectives, but not for others. In the case of our hostage mission here, you’ll see where they hold the prisoner, but not where the enemy HQ is, or you’ll find out the enemy patrol route, but not the schedule.

You failed, and have no intel

This is the equivalent of going in without any infiltration. Nothing lost and nothing gained.

You failed, and now the enemy knows you’re there

You’ll be going in blind, and the enemy will be on high alert. They may have added more patrols, etc. Examples of such failures would be to have your recon drone shot down by enemy, or have your agent captured during infiltration.

In-game, you select the infiltration option during the mission brief meeting, and it’s simulated prior to mission start by using the stats of the character you chose to complete the infil. This will allow for different members of the squad to shine, and for the player it will make sense to pick the right person for the right task. Or not, and deal with the consequences.

Here’s how the infiltration planning meeting looks like in-game.

You pick which infiltration option you like best

We use Lua to script all the different things we’d like to randomize. For example, the mission description (see first and second screenshot) has all these variables, and below it there’s a box where we define them. The randomizing function pulls the values such as countries, diplomatic titles, and such from a table where we store all kinds of things, tagged with metadata for searching, and the player sees the mission description like this.

Pardon the layout - it's a dev build :)

Here’s how it looks in the tool.

Randomizing names is a bit trickier, because unlike the stuff that is only used in the description, the random name has to be assigned to the character when they are spawned on the mission map. We have a way of doing that when we add the character to the mission.

This is also where we pick the character template for a given NPC, which includes the types of things they wear (military uniform or civilian clothes etc.) and some other aspects of their appearance such as hair styles (again, military personnel will have simpler hair styles and natural colored hair, while the civilians may have wider choices of both).

This is the NPC we're going to need to rescue

In most cases, unless it’s an NPC that persists throughout the game, we fully randomize gender, skin color, and body type. Military personnel will again have fewer choices in the body type department, as we will only allow them to have an “average,” “fit,” or “fighter” fitness level. Civilians get a fourth option in fitness level: “unfit.”

The level of fitness and body type aren’t just for show either, they influence the body owner’s attributes as well, so if you meet someone who looks strong and fit, they very likely are.

To make sure that the spread of different body types is more realistic, we weight the probability of each of them occurring. After all, you don’t see twenty-five MMA-fighter-level-fit people for every hundred you meet.

Body types matrix for female and male bodies:

light

average

heavy

unfit

f-un-lt, m-un-lt

f-un-avg, m-un-avg

f-un-hvy, m-un-hvy

average

f-avg-lt, m-avg-lt

f-avg-avg, m-avg-avg

f-avg-hvy, m-avg-hvy

fit

f-fit-lt, m-fit-lt

f-fit-avg, m-fit-avg

f-fit-hvy, m-fit-hvy

fighter

f-ftr-lt, m-ftr-lt

f-ftr-avg, m-ftr-avg

f-ftr-hvy, m-ftr-hvy

With that, we can populate the world with a fairly diverse set of characters for the player to encounter. And often, shoot. Oh, and also create for yourself at the beginning of the game.

Other things you will have noticed in the mission generation tool would be buildings. We generate buildings at runtime from a floor plan which we also create in our tool, but that is a topic for another post.

For now, suffice it to say that when the map is generated, the buildings are placed on it somewhat randomly, according to the parameters specified when the building is added to the mission.

Let’s not forget the objectives! They contain Lua commands to evaluate when the conditions for a particular objective have been met, or failed, such as in case of having the civilian you’re supposed to protect, die. If an objective is marked as required, failing it will mean mission failure and you’ll have to do it over, and if an objective doesn’t have this box checked, you can fail it all you want and still complete the overall mission.

The Lua check is to make sure that the NPC 39 (our Hostage) is alive. Because this is a required objective, the mission is failed the moment the NPC dies.

Some objectives are only available when particular conditions are met. Case in point: “recover drone wreckage” is only shown if you chose the drone reconnaissance option and the drone crashed. If the drone is shot down and captured by the enemy, your objective (and area of search) will change to retrieving the drone from the camp.

When everything is said and done, we’ll have a mission that can be replayed over and over, but it will never be exactly the same. You’ll get different infiltration options, the terrain will be different, and the buildings will never be in the same spot. Same goes for objectives such as which building the hostage is in, or where the drone wreckage is.

By the time we ship the Early Access version, we’ll have a number of such missions implemented, in addition to a handful of storyline ones to tide y’all over until the full version is released.

We’re also thinking of creating affordances for players to design their own mission mods, and whole missions down the road. That’s something that will have to wait until after Early Access though.