Skip to content

Random Level Generation With Objectives

Random level generation is a powerful tool that game developers can use to enhance replayability in their video games. By generating different levels each time a player starts a new game, developers can keep the gameplay fresh and exciting for players, encouraging them to come back for more. This can be especially useful in exploration games, where the procedural generation of levels can create a unique playthrough each time, allowing players to discover new areas and items with each playthrough.

A Game Changer

From the perspective of a solo developer, random level generation can be a game changer. As a solo developer, it can be challenging to create enough content to keep players engaged for a significant amount of time. However, by implementing level generation, a developer can significantly increase the scale of their game, creating virtually limitless content without having to create each level manually. This not only saves time and resources but also ensures that players will have a different experience each time they play the game, increasing its replayability and longevity. Overall, random level generation is an excellent tool that can benefit game design in multiple ways, whether it be improving replayability or increasing the scale of a game for a solo developer.

Both of my previously released games, Bloxkrieg and Boing!, have featured a different form of random level generation – Bloxkrieg creates blocks in various patterns within a set area with multiple different patterns to choose from, ranging from lines arranged vertically or horizontally within the play area, concentric circles, etc. To add further variation, each group of blocks could then be assigned a mover in reversing linear or circular motions.

Boing generates levels from a pool of predefined tiles, arranged one after the other according to a basic set of rules – for example it will never arrange two sets of “road” tiles one after the other.

Random Level Generation with Dungeon Architect

Over the last couple of weeks I have been getting to grips with the Dungeon Architect Unity addon. The Dungeon Architect addon is a powerful tool that is available for use in both Unity and Unreal game engines. This addon allows developers to generate complex dungeon environments with ease, using a simple and intuitive interface to create intricate layouts and paths. After some playing around with each of the generation options available, exploring the pros and cons of each, I decided that for my next game I was going to base the core of the level generation around the Snap Grid Flow generator.

Random Level Generation with Dungeon Architect
A complex level design template

The Snap Grid Flow generator allows me to specify a start, and end, and several paths between which may or may not intersect depending on the specification provided to the level generator. These paths can be locked, one way, require a key, contain treasure or enemies or any other prefab you want to spawn. The levels are then generated based on a collection of prefabs you configure to specify room layouts and door locations, resulting in a playable level with basic objectives.

A level generated out of pre defined rooms
A level generated out of pre defined rooms

Going Deeper

These levels are fun enough, but often can feel like randomly generated levels. With some further tinkering and constraints to the generation template I started getting more predictable results, and with these predictable results I started thinking about level objectives beyond collecting key cards – another level of randomization. Several levels, actually.

Dungeon Architect is generating levels out of prefabs of rooms. The first step to add more randomization was to create a simple script to handle multiple layouts within the same room prefab. This would allow me to have one “corridor”, one “apartment”, and so on – but then once the prefab had been instantiated, the script on the prefab would choose a layout for that instance of the prefab, so two corridors spawned next to each other would look different at runtime. This was fairly straight forward – we created a RoomLayerManager, with a List<GameObject> list, populated with the top level parent game object for each group of layout contents. Then, in the RoomLayerManager Start() function, we chose one layout at random from the list, enabled it and then disabled the rest.

The next layer of randomization relates to the level. We started to think about the kinds of scenarios we could want to occur during a particular playthrough and the first and most obvious one that came to mind was some kind of systems failure. We are boarding space stations in space and there are invariably going to be problems – the life support is going to be down, the reactor will be offline or the hull will be breached. These kinds of per level randomizations that exist outside of the geometry randomization needed a LevelManager to store some variables and top level logic, along with an expansion of how all of the individual rooms worked.

Let There Be Light

If we’re looking at failing systems on a space station, the first and most obvious one is power. We created a “Reactor Core” room prefab and then set about adding lights to every existing room, a light controller to turn the lights on and off, material managers to control emissions and then registering every room instance during the level creation process. Once complete we had to rework the lighting a bit on the level to ensure that the levels were actually “dark” when the lights are off. It’s not perfect but this is my proof of concept. Let me know what you think!

Leave a Reply

Your email address will not be published. Required fields are marked *