ProcJam 25 Diary - p3 bells and whistles

This is the final article about my spooky SCP bunker generator that I revised for ProcJam 25. You can read the previous parts here and here. You can also play the final demo here.

Today I'm going to talk about how I take the plain 3d room generator and add props and atmospheric elements to add some of that juicy Stalker SCP vibe.

Preparing to decorate

Like all good DIY projects preparation is important. I want to place furniture and other items in my newly generated rooms, but there needs to be some logic in how they are instantiated. Having chairs facing walls or ladders leaning against nothing might look odd (and not in the right way). 

To add some sense to the furniture placement I flag cells in the map with certain qualities. For example in the image above, cells on the periphery of a room are marked green and cells that are at a door entrance are flagged in red. I can use this to make sure that items aren't placed where they might block doors, and I can use the "wall adjacent" information to place and align objects like shelving or cupboards, items of furniture which would naturally fit next to a wall.

Procedural Kitbashing

Its probably important at this point to explain how I use/choose/edit the assets I use in this project (and most of my other work). I pride myself on a sort of procedural kitbashing approach.

I start with assets I have either bought or found free from various sources (Unity asset store, Fab store etc). I create a separate scene from the rest of my project where I set up these objects in order to prepare them for use. At this stage I often write new shaders to apply to all the objects, add layers of extra texturing to their materials, edit/add/remove elements to the fbxs using blender and frequently combine models form different sources to create a new object. I like to think of this as similar to the workshops in set design where artists will paint on grime or modify costumes in order to create a more holistic set of pieces. Of course lighting, colour grading and so on are also really good at bringing together disparate source materials.

When I have enough items prepared that I like the look of I set up a list of categories for them, something like the following.

 public GameObject[] m_CeilingObjects;
 public GameObject[] m_WallLightOnObjects;
 public GameObject[] m_WallLightOffObjects;
 public GameObject[] m_RoofTopObjects;
 public GameObject[] m_RoofLightObjects;
 public GameObject[] m_FloorWallObjects;
 public GameObject[] m_FloorWallFreeObjects;

The locations where these items are placed should be obvious from their names, and I can use the map data I already have (see previous articles), in order to place them sensibly.

Here are a couple of examples of some placement rules.

When instantiating these objects my code always attempts to leave 1 cell around any object (especially if it is freestanding) in order to ensure the player can navigate the surrounding space. But I don't want every room to have the same set of furniture or the same style of placement layout. So how can I avoid this?

Room decoration types

I use a set of pre-defined room "types" which hold specific model sets to create a theme for an individual room. Since all the rooms have individual ids and data its trivial to assign a type to each one in the data.

These room types hold furniture lists (see above) and specific placement rules. Such as the school-room placing desking and chairs in organised rows. The rooftops are decorated in a similar way, as they are effectively just rooms without walls. 

With this groundwork established.  its mostly about adding in extra furniture sets, different floor and wall materials and iterating on how these elements look when combined. The demo features around 6 or 6 room types, but feels like more because the rooms shapes and materials can also change.

Because I am generating everything in discreet blocks (see previous article) Its also easy for my code to occasionally omit objects, railings, bits of walls or even entire floors. This introduces even more variation and gives an nice sense of decay or deconstruction to the architecture.

Connections

The corridors from my underlying map generation data are either drawn as enclosed tunnels, or as exposed gantries. This gives another nice mix of material types and allows more sightlines and verticality to the scene.

Similarly, the connections between floors are built with ladder placements (the spiral staircase tiles from our original 2d generator!), and in some cases I even allow the floors themselves to use gantry tiles to create a more vertiginous vibe.

The surroundings of the generated base are supplied by a predefined terrain patch that I hand authored. I make sure to set a decent fog range so the player cant see the distant edges.

Anomalies

What's a containment facility without the anomalies!? There are about seven or so anomalies and they can appear in any room (but no more than one type per rooms). Some are subtle and static (placed like furniture), some wander around, some are interactive, and there's even a (fairly rare) poltergeist!

Conclusions

I make a lot of prototypes, and almost all of them end up resting in some dusty folder on my PC never to see the light of day. And although I didn't fully develop this demo during procjam25 I did fix it up significantly and spent a decent amount of time documenting the process. I'm glad I did, I think its a cool project and I'm very happy that I've returned to it and made it playable. You can download the demo on itch and let me know what you think there or on my socials.

This article was updated on

Related post