The following blog post, unless otherwise noted, was written by a member of Gamasutras community.
The thoughts and opinions expressed are those of the writer and not Gamasutra or its parent company.
The Riftbreaker is a game that is heavily influenced by various genres. The base-building and base defense aspects of the game bring back memories of both classic and modern real-time strategy games. Looting and crafting systems resemble those known from action-RPG titles. Dynamic weather, time of day, and unique biomes are all valuable parts of games focused on exploration and survival. What connects all those genres is the fact that their gameplay benefits strongly from map variety.
[embedded content]Our latest base-building trailer shows off a variety of biomes and locations within them.
The Riftbreaker’s main advantage is that no two play sessions are ever the same. Even though you know what to expect, the exact details of each mission have to be discovered by the player every time they start a new game. The only way to achieve that sort of variety is through procedural map generation. This feature has always been one of the design pillars of The Riftbreaker and one of the most significant tasks for the entire project. The game uses our own engine, The Schmetterling, which also powered our previous projects, Zombie Driver and X-Morph: Defense. However, those games used pre-designed, fixed levels. In this article, we will tell you about the world generation system that we came up with for The Riftbreaker.
The map generation process is carried out before each new Survival Mode playthrough. The premise of this mode is for every session to be a standalone experience, and a procedurally generated world helps a great deal with that. The process is split into a couple of phases – let’s take a look at each of them.
The process begins with the choice of biome by the user. For the player, the choice of biome will affect the types of creatures they are going to encounter, the pool of available dynamic weather events, as well as the availability of resources and the overall look and feel of the play area. For the game itself, however, the biome defines a set of overarching parameters that will affect the world generation process. Every biome preset in The Riftbreaker contains information on the lighting parameters, the skybox, and its properties, as well as a set of materials to be used as the base textures for the terrain. Biomes also define what tiles are available for the game to use when generating the map.
Sample choice of textures for the jungle biome.
Snippets from the various biomes players will visit during the campaign: jungle, desert, acid and magma.
Biomes do not have a ‘fixed’ configuration, meaning that two ‘jungle biome’ maps can look very different from one another. We achieve that thanks to biome randomization. Instead of giving the game a set of properties it has to use, we give it a pre-configured set of options to randomize from. As a result, it is highly unlikely that the game will choose a set of identical materials, skyboxes, and lighting for any given two playthroughs. While still pre-defined by our designers, mixing and matching the biome properties introduces a little bit of variety into the world generation right from the start.
After all the biome parameters have been selected, the algorithm begins to perform the first operations on the tiles. Tiles are our basic building blocks for map generation in The Riftbreaker. They are the smallest editable chunks that our level designers prepare manually. Their minimum size is 128×128 meters (or 64×64 in-game grids. Each grid in our game is a 2x2m square). Tiles need to meet some basic criteria before they are ready to be put into the game. However, these requirements are easy to meet and they can be fulfilled in some creative ways so that they don’t limit the designers’ freedom.
The designer of the tile only has to cover the terrain with a couple of types of masks. The textures will be randomly chosen from the available set.
One such requirement is masking the surface with terrain blends. The surface area can be covered by one of three global materials – for simplicity’s sake let’s name them A, B, and C – the ones that were selected in the biome randomization process. Designers do not choose the materials, they simply designate zones that the game will cover using material set A (e.g. sandy textures), material set B (e.g. grassy terrain), and material set C (e.g. rocky bedding). It is also possible to paint an area with a real texture instead. In that case, the randomization process will not affect it.
If the designer chooses to use a regular texture instead of a mask, that area will not be affected by the randomization process. It’s useful for adding details beneath props.
After that, the creator of the map can start placing spawn points for the game logic elements. They decide where the player can possibly start their journey, the resource placement (and their variety), as well as all the NPCs that will fill the game world.
Here you can see exactly what area has been marked to be replaced by prefabs, as well as which props have been placed automatically.
An additional element of randomness that we decided to incorporate into the world generation algorithms for The Riftbreaker are so-called prefabs. In our case, a prefab is a special handcrafted scene, that is filled with various props by a designer. Their purpose is to fill the blank spaces of the map tiles left by designers and marked to be masked by prefabs. In other words – prefabs lie underneath the regular tiles and pop up wherever there is a window left for them to do so, filling the area with props in a randomized way without the need for any additional human input.
Painting with prefab mask allows you to get a unique-looking tile in no time.
The designer chooses which of the pre-made prefab scenes they would like to be used on their new tile. Every prefab has its own mask, and the designer decides where they would like to use it. Props from the predefined scene will then fill the masked area. When the map is being generated the positioning and orientation of the prefabs are chosen at random. Then, several copies of the prefab scenes are stitched together to lie underneath the entire area of the game world. This way, we can be sure that regardless of the area designated by the creator the prefab mask will be able to fill the area marked by the designer with props. Slight differences in positioning, orientation, and prefab choice can drastically change the feeling of the tile.
Several variants of prefab scenes. They are jam-packed with props so that they can do their job regardless of where they get positioned.
This is the same map. The only thing that changes is the generator seed for the prefab randomization. The effects of that range from very subtle to completely unrecognizable.
Tiled map generation
Now that the tiles have been randomized it is time to generate the map. The game checks how big the map should be – we support various map sizes, from single-tile ones to behemoths of 12×12 tiles. The current, builds of The Riftbreaker generate 5×5 maps for Survival Mode and varied sizes for Campaign mode. The size of the map affects both gameplay choices and engine performance. Exploration missions in the campaign require larger playable areas while base defense objectives can fit into smaller worlds for more streamlined gameplay.
The designer should also assign information to each edge of the a for matching purposes. Tiles will only be connected to each other if their sides match, preventing connection errors. The tile randomization process chooses which tiles are going to be used for map generation, which of the spawn points are going to be used, and how tiles are going to be rotated (we support rotations of 0, 90, 180, and 270 degrees). Tiles may repeat during the map generation process and they may vary in properties between instances.
The game world is generated by solving a version of the ‘Wang tile problem’. You can read about this concept here. In the original problem, the colored sides of the tiles have to match each other without performing any rotations. Our case is simplified a little since we allow for rotations, however, neighboring tiles still have to match each other when it comes to sides. It takes quite a bit of gymnastics to make it all work, but the resulting number of combinations is very high.
It is possible to add more surface area for your work. The game will still treat is as one tile, keep the entire creation in one piece and fit it with other tiles during map generation. It allows the designers to create multi-tile structures, like mountain ranges or canyons.
It is worth mentioning that not all tiles need to be 128×128 meter squares. We support combinations of several ‘base’ tiles as well to support unique structures spanning over several tiles, such as massive rock formations, large lakes, or rivers. If a special tile structure like this is chosen to be part of the generated world it is put on the map in its entirety to preserve the continuity of the props prepared by the designers. The surrounding area is then filled with randomized tiles as usual.
Resource and Player Spawn Point Randomization
Finally, after the algorithm has generated the map through all the steps described above, we can move on to the distribution of resources. Each mission in The Riftbreaker defines what kind of resources should be made available to the player. However, it only specifies the amounts of resources to be available during the mission, not their localization. That is randomized again. The game chooses possible spawn points for resource deposits and distributes them according to a relevant ruleset.
An example of the ruleset for resource distribution. All game modes and maps require their own rulesets to vary and balance the gameplay experience.
Once a resource spawn point is chosen by the algorithm, the process is rather straightforward. The resource type is chosen, followed by the ‘density’ of the deposit – the amount of resources that will be available for the player to use. That value is a simple roll between the minimum and maximum values defined in the mission logic file. Then, the game tries to determine the center of the resource deposit. The field will be the richest towards the center, which will be represented by a different physical model for easy visual identification.
Resources can spawn in the area marked with red. The game will determine the center of the resource deposit, its yield, and then adjust the mesh accordingly.
Once all the resources have been distributed, the game checks all the player spawn points and chooses the one which is the closest to the minimum basic resources necessary for the player. Once such a place is determined, the player can finally start the game.
We are happy with the map generation system that we developed for The Riftbreaker. It allows us to introduce a lot of variety to the game world in relatively short time. Adding even a couple of new tiles to the biome pool makes for an interesting experience for both new and returning players. Add randomized prefabs giving the map tiles a slightly different look and feel every time, and you have a solid foundation to build the game on.
The current state of the system is very functional, but it can still be improved with plenty of useful features to make the game world more realistic. We are working on dynamic NPC placement that will adapt according to the biome, the chosen difficulty level, time of day, as well as the player’s progress in the game. With such a system in place The Riftbreaker will become a game that encourages dynamic decision making and adjusting to the conditions, rather than learning the exact procedure needed to complete each mission.
That is all we have for you today. If you have any questions, feel free to post them in the comment section or catch us directly on our Discord server: www.discord.gg/exorstudios.
See you next time!