Shadows of Doubt is a detective stealth game set in a fully-simulated sci-fi metropolis! There’s been a murder and it’s up to you to solve it by any means necessary, with the condition that you keep a low profile. A unique mix of procedural generation and hand-crafted design enables every room of every building to be explored. Citizens go about their lives independent of the player as you watch from the Shadows, in search of crucial information. Read previous dev blog entries here.

I’ve been working on quite an exciting new feature for Shadows this month: Procedurally generated ventilation shafts! If you don’t play many games then that might sound incredibly boring, but to any seasoned FPS or immersive sim player then hopefully that sounds excellent.

One of the biggest things missing from the gameplay right now is multiple ways to get in and out of locations: The choice-driven stealth gameplay I’m shooting for requires that the player is given a choice in how to infiltrate their places of interest. Before this update, there was only the front door, and in the future, there will be yet more options including fire escapes and windows. But one of the biggest tasks on my to-do list was these air ducts that the player can crawl through to get places they shouldn’t.

Originally the ducts appeared on the exterior of buildings by accident, but I figured they looked way too cool to get rid of.

Previously in the project, I briefly toyed with having a more realistic air duct system as described in this article. I have kept a few issues in mind, although in the end, I decided to prioritize gameplay over realism- and with that I decided to leave my air ducts at the mercy of procedural generation. The air ducts are completely procedurally generated within each building. Even if two or more share a similar floor plan then the shaft system within each will still be completely different, and your infiltration routes and options will be different too.

Going into the technical side of things a little: Basically, in the configuration settings I have for each room, I’ve added range variables for how many air vents can be added. For example, a bathroom might have one, or a kitchen, but less likely a lounge area. So when the rooms are generated they will also look for a place to put an air vent; often in the ceiling but sometimes high up on a wall or (less likely) closer to ground level on a wall. So now we’ve got all the points where we want the vents to be in the building.

Next up I map all the available space that the ducts can use. Mostly this is the space between ceiling and floors, but it can also cover spaces inside maintenance closets and even space outside the building. Now I have this space mapped out and the points I need to connect, I can simply use an A* pathfinding routine to connect points together- this becomes the path of the ducts. With every path calculation, I can weight already-placed ducts so the game won’t create air ducts which run immediately parallel to each other.

This is what the duct system looks like minus room and building models.

As with the walls/floors/ceilings, I have a different model for each possible turn/junction of duct- this is how it’s possible to create them. They all share the same material within unity, so I can easily combine them together to form one model and keep performance high.

It’s working really nicely! When inside the player can freely climb up and down vertical duct sections too. One last thing that I need to work on (aside from a couple of misc wall bugs) is enabling ducts to be discovered and mapped on the minimap. It would be cool to maybe be able to discover blueprints that map out the ducts and vents of the whole building- adding incentive to research your places of interest before infiltration.

Anyways, that’s it for this update. Progress is going nicely on the game- next up is a focus on improving the AI some more and fleshing out the side mission I showed off a few weeks back. Stay tuned for more soon!