Search icon CANCEL
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Procedural Content Generation for C++ Game Development
Procedural Content Generation for C++ Game Development

Procedural Content Generation for C++ Game Development: Get to know techniques and approaches to procedurally generate game content in C++ using Simple and Fast Multimedia Library

eBook
AU$41.99 AU$60.99
Paperback
AU$75.99
Subscription
Free Trial
Renews at AU$24.99p/m

What do you get with Print?

Product feature icon Instant access to your digital eBook copy whilst your Print order is Shipped
Product feature icon Paperback book shipped to your preferred address
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
Table of content icon View table of contents Preview book icon Preview Book

Procedural Content Generation for C++ Game Development

Chapter 1. An Introduction to Procedural Generation

When you load an image on a PC, a song on an iPod, or a book on a Kindle, you load it from storage. That image, song, and book already exists as a whole, and whenever you want to access it, you grab the whole previously created thing. In the case of music or a video, you can stream it in chunks, but it still already exists as a whole in storage. Let's compare this to buying a ready-made desk from a furniture store. You get the entire desk as one single thing and that's that; you have a desk.

Now, let's imagine that instead of buying a complete desk, you buy one that's flat-packed. Instead of getting a pre-built desk, you get all the pieces that you need to build one, and instructions on how to do so. When you get home, you can follow those instructions, and you will have a desk. If you feel so inclined, you can even deviate from the instructions and create a unique desk that is different from that of everyone else.

Let's use this analogy in the context of game development by substituting the purchasing of a desk with the loading of a level. In the first case, we loaded the level as a whole, as it was pre-built. However, in the second example, we got all the pieces that we need to build a level and put them together ourselves in whatever order we choose.

This process of something being created via an algorithm or procedure, as opposed to already existing, is called procedural generation. The desk was created procedurally as you followed an algorithm to put its pieces together. The same goes for the game level. This can be extended to almost anything. For example, music, images, games, and text can all be procedurally generated.

In this chapter, we will cover the following topics:

  • Procedural generation versus random generation
  • Generating pseudorandom numbers in C++
  • Seeds
  • The benefits and drawbacks of procedural generation
  • A brief history of rogue-like games
  • How to implement procedural generation

Procedural generation versus random generation

I'd like to make a distinction before we go any further. In this book, we're going to talk a lot about procedural generation and random generation. These terms are often used interchangeably, but they are not the same thing. Therefore, let's take a moment to define them.

Procedural generation

Procedural generation is the process of creating content using an algorithm. This in itself has no element of randomness. If the functions, expressions, algorithms, and inputs that are used to generate the content remain the same, then you'll always get the same results. This is due to the fact that computers are deterministic, which is something that we'll cover shortly. Procedural generation is not inherently random.

Random generation

Randomness is induced when we give these algorithms different inputs or alter their expressions. This variance is what creates the variety of the output. When someone says something was procedurally generated, they usually mean procedurally generated utilizing randomness.

Introducing randomness

Computers are deterministic machines. This means that if you give them the same input, and perform the same operations, you'll get the same output every time. With respect to the desk example, everyone gets the same pieces, follows the same instructions, and so builds the same desk.

Again, using the context of games, if everyone gets the same assets and algorithms to put them together, we will all get the same game and experience. Sometimes, this is the goal. However, in our case, we want to create game systems that are unpredictable and dynamic. Therefore, we need to introduce an element of randomness to procedural generation.

Pseudorandom number generation

Random number generation is simply the process of picking a number at random. This is pretty straightforward for us, but it is a much tougher task for a computer. In fact, it's impossible for a computer to generate a truly random number without special hardware. You'll understand why this is so in a moment.

The next best thing is pseudorandom number generation. The word pseudo literally means not genuine. Therefore, pseudorandom number generation can be thought of as a fake random number generation. The numbers appear to be random but are actually the result of complex equations and algorithms that could in fact be calculated in advance.

Bear in mind that not all pseudorandom number generators are built equally. For applications such as trivial simulations and games, fairly linear algorithms can be used and are perfectly suitable. However, pseudorandom number generation is also used in applications such as cryptography, and will use much more complex algorithms so that the outcome cannot be determined via patterns created from earlier outputs.

The pseudorandom number generators that we use as developers fall firmly into the first category and are perfectly suitable. Luckily for us, C++ offers a number of ways in which trivial pseudorandom numbers can be generated. Throughout the course of this book, we will use std::rand() and std::srand(), both of which standard C++ functions that are included in <cstdlib> library.

Tip

Learning how to read and extract information from documentation is a skill that I feel is often overlooked. With a multitude of great forums at hand it's easy to go straight to Google for a solution to your problem, but first, always read the documentation. http://www.cplusplus.com is a great C++ reference, and SFML is fully documented at http://www.sfml-dev.org/documentation/.

Why computers can't generate truly random numbers

We now know that computers can't generate random numbers, and that we generate pseudorandom numbers instead. Let's have a look at why this is so.

The reason behind this is the same as the reason why two computers will reach the same output given the same input and operation; computers are deterministic. Everything that a computer produces is the result of an algorithm or equation. They are nothing more than highly sophisticated calculators. Therefore, you can't ask them to act unpredictably.

True random numbers can be generated, but you need to utilize systems outside the machine. For example, at https://www.random.org/ you can generate truly random numbers using atmospheric noise. There are other systems that are akin to this, but unless you are generating random numbers for something important such as security purposes, trivial pseudorandom number generation will suffice.

Generating random numbers in C++

Let's start coding by writing a small program to generate some pseudorandom numbers. To do this, we will use the std::rand() function. It generates a pseudorandom integer in the range between 0 to RAND_MAX. The RAND_MAX variable is a constant defined in <cstdlib>. Its value will vary depending on the library that you are using. On a standard library implementation, it's guaranteed to be at least 32767.

Tip

If you're already familiar with this topic, feel free to skip ahead to the sub-chapter named Seeds.

You can download the code for this program from the Packt website at http://www.packtpub.com/support. It will be present in the Examples folder, and the project name is random_numbers:

// Random number generation
// This program will generate a random number each time we press enter.

#include <iostream>

using namespace std;

int main()
{
  while (true)
  {
    cout << "Press enter to generate a random number:";
    cin.get();

    // Generate a random integer.
    int randomInteger = rand();

    cout << randomInteger << endl << endl;
  }

  return 0;
}

Tip

Downloading the example code

You can download the example code files from your account at http://www.packtpub.com for all the Packt Publishing books you have purchased. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.

This is a very simple console application that makes a call to std::rand() every time we press the Enter key. This returns us the pseudorandom number, and we pass it to std::cout to display it. That's how easy it is!

Generating random numbers in C++

Generating random numbers within a range

The previous code generated numbers between 0 and RAND_MAX. That's great, but we'll usually want more control over this in order to generate numbers within a certain range. To do this, we are going to use the modulo operator.

Tip

In C++, the modulo operator is the % symbol. This varies between languages, but is generally either % or Mod.

The modulo operator returns the remainder of the division between two numbers. So, 9 mod 2 is 1, as 2 goes into 9 four times with 1 left over. We can use this to create a range for the pseudorandom number generation. Let's generate a number between 0 and 249.

To do this, we need to make the following change:

// Generate a random integer.
//int randomInteger = rand();
int randomInteger = rand() % 250;

Run the program a few times now, and you'll see that all the results are limited to the range that we just defined. So now we can generate a number between 0 and n, but what if we don't want our range to start from 0? To do this, we need to make one more change to the line that generates a number:

// Generate a random integer.
//int randomInteger = rand() % 250;
int randomInteger = rand() % 201 + 50;

Remember that the number we used in the mod calculation will generate a number between 0 and n-1, and the number we add afterwards will increase the range by that amount. So here, we generate a number between 0 and 200 and then increase the range by 50 to get a number between 50 and 250.

Tip

If you're not fully comfortable with the math behind what we're doing here, head over to Khan Academy. It's a fantastic resource for learning and has lots of great mathematics-related material.

Run the program and note the first five numbers that are generated. In my case, they are 91, 226, 153, 219, and 124. Now, run it again. You'll notice that something strange happens; we received the exact same numbers.

They were generated in a pseudorandom manner, right? Maybe it was just a fluke. Let's run it again and see what we get. You will get the same result again. To understand what's happening here, we need to take a look at seeds.

Seeds

We just created a program to generate pseudorandom numbers, but every time we run it we get the same results. We know that these numbers are the results of complex equations and algorithms, so why are they the same? It's because each time we run the program, we're starting with the same seed.

Defining seeds

A seed provides a starting point for an algorithm. So, in the previous example, yes we're using complex algorithms to generate numbers, but we're kicking off the algorithm at the same point each time. No matter how complex the algorithm is, if you start at the same point, and perform the same operations, you're going to get the same results.

Imagine that we have three people, and each person is about to walk the same path by 5 steps. If they all start from the same square, they will end at the same square:

Defining seeds

Now, in the next diagram, we give these three people unique starting positions. Even though they are doing the same actions as before, and are on the same path, their results are different because they started from different locations:

Defining seeds

In this analogy, the path is the algorithm, and the starting square is the seed. By changing the seed we can get different results from the same actions.

You will have most likely used seeds before and not even known it. Games that procedurally generate worlds, such as Minecraft and Lego Worlds, give you the option to set a seed manually before generating a world. If your friend generates a world that looks great, they can grab their seed and give it to you. When you input that seed yourself, you kick off the algorithm at the same place that your friends did and you end up with the same worlds.

Using seeds

Now that we know what seeds are, let's fix the previous example so that we don't keep generating the same numbers. To do this, we will use the std::srand() function. It's similar to std::rand(), but it takes an argument. This argument is used to set the seed for an algorithm. We'll add the call to std::srand() before we enter the while loop.

Tip

You only need to set the seed once per run of the application. Once std::srand() has been called, all the subsequent calls to std::rand() will be based upon the updated initial seed.

The updated code should look like this:

// Random number generation
// This program will generate a random number each time we press enter.

#include <iostream>

using namespace std;

int main()
{
  // Here we will call srand() to set the seed for future rand() calls.
  srand(100);

  while (true)
  {
    cout << "Press enter to generate a random number:";
    cin.get();

    // Generate a random integer.
    int randomInteger = rand() % 201 + 50;

    cout << randomInteger << endl << endl;
  }

  return 0;
}

Now when we run this code we get different results! I got 214, 60, 239, 71, and 233. Don't worry if your numbers don't match mine exactly; they are both CPU- and vendor-specific. So, what will happen if we run the program again? We changed the seed. So we should get different numbers again, right?

Not quite. We called std::srand() and set a new seed, but each time we run the program we're setting the same seed again. We're kicking the algorithm off at the same position each time, so we're seeing the same results. What we really want to do is randomly generate a seed during runtime so that the algorithm always starts at a new position.

Generating random seeds during the runtime

There are many ways to achieve this, and your use case will determine which method is suitable. For us, as game developers, something relatively trivial such as the current system time will usually suffice.

This does mean that if you run the program at the exact same time you'll get the same results, but that's almost never going to be a problem for our use. C++ provides us with a nice function to get the current time, time(), which is located in <ctime>.

Let's update the program one last time and pass time() as a parameter in std::srand() so that we generate unique numbers with every run:

// Here we will call srand() to set the seed for future rand() calls.
//srand(100);
srand(time(nullptr));

Now, every time we run the program, we get unique numbers! You may have noticed that if you run the program multiple times in succession, the first number is always very similar to the last run. That's because between the runs time doesn't change a lot. This means that the starting points are close to each other and the results reflect this.

Controlled randomness is the key to generating random numbers

The process of generating random numbers is a huge component in creating systems that procedurally generate game content. There are lots of ways in which random data is generated, such as noise maps and other external systems, but in this book, we'll stick to these simple C++ functions.

We want systems that are predictable enough to give us control over them as developers, but they should be dynamic enough to create variations for the player. This balance can be hard to achieve, and sometimes games get it wrong. Later in this chapter, we'll look at some of the things that you have to watch out for when incorporating procedural generation into a game project to avoid this.

The use of procedural generation in games

Now we know what procedural generation is, and that it's the element of randomness we add that lets us create dynamic systems, let's take a look at some examples of how it is used in games. There are countless ways in which it can be utilized; the following are just a few major implementations.

Saving space

Necessity, as the saying goes, is the mother of invention. As developers of today we're spoiled with the hardware that we have at our disposal. Even the most baseline machines that you'll get today will have a hard drive of 500 GB in size and up as standard. This is quite a luxury considering that just a couple of decades ago that would be MB and not GB.

Game distribution was also a very different game back then. Today, we either buy games on a physical disk, with Blu-ray disks offering a whopping 25 GB per layer, or download them off the Internet, where there are no size restrictions at all. Keeping this in mind, now consider the fact that the size of most Nintendo Entertainment System (NES) games was a mere 128 to 384 KB! These storage restrictions meant that game developers had to fit lots of content into a small space, and procedural generation was a great way to do this.

Since building large levels and storing them wasn't possible in the past, games were designed to build their levels and resources algorithmically. You'd put all the resources needed on your storage media, and have the software assemble the level at the player's end.

Hopefully now, the earlier desk analogy makes more sense. It's just like how flat-packed furniture is easier to transport, and it can then be built at home. As hardware has developed, this has become less of a problem, but it was a great solution for early developers who had storage concerns.

Map generation

One of the most prominent uses of procedural generation in modern video games is the generation of game maps and terrain. The extent to which this can be used is vast, and ranges from generating simple 2D maps to full 3D worlds and terrain.

When procedurally generating 3D terrain, noise maps, such as the ones generated by Perlin noise, are used to represent random distribution by producing an image with areas of both high and low concentration. This data, the variance in concentration and intensity, can then be used in many ways. When generating a terrain, it's commonly used to determine the height at any given position.

Map generation

The procedural generation of complex 3D terrain is beyond the scope of this book. However, we will generate 2D dungeons later in this book.

Tip

If you do want to explore 3D terrain generation, read up on terms such as "fractal terrain generation", "height maps", and "noise generation". These will put you on the correct path.

Texture creation

Another prominent example of procedural generation is the creation of textures. Similar to terrain generation, the procedural generation of textures uses noise to create variance. This can then be used to create varying textures. Different patterns and equations are also used to create a more controlled noise that forms recognizable patterns.

Generating textures procedurally like this means that you can potentially have an unlimited number of possible textures without any overhead on storage. From a limited pool of initial resources, endless combinations can be generated, an example of which can be seen in the following image:

Texture creation

Perlin noise is just one example of the many algorithms that are commonly used in procedural generation. The study of these algorithms is beyond the scope of this book, but if you want to further explore the use of procedural generation, it would be a good place to start.

Animation

Traditionally, game animations are created by animators, and then exported as an animation file that is ready for use in the game. This file will store the various movements that each part of a model will go through during animation. It then gets applied to the game character during runtime. The player's current state will determine which animation should be playing. For example, when you press A to jump, the player will change to a jumping state, and the jumping animation will be triggered. This system works great, but it is very rigid. Each step, jump, and roll is identical.

However, procedural generation can be used to create real-time, dynamic animation. By taking the current position of the character's skeleton and calculating the multiple forces that are being imparted upon it, a new position can be calculated. The most prominent example of procedural animation is ragdoll physics.

Sound

Although less common than the previous examples, procedural generation is also used to create game sounds. This will commonly be in the form of manipulating existing sounds. For example, sound can be spatialized, meaning it appears to be coming from a specific position when heard by the user.

At a stretch, short, one-shot sound effects may be synthesized, but due to the little benefit that it brings as compared to the amount of work needed to implement it, it's seldom used. It's simply much easier to load premade sounds.

Note

Sfxr is a small program that generates random sound effects from scratch. Its source is available. So, if sound synthesis interests you, it will serve as a good starting point. You can find the project at https://github.com/grimfang4/sfxr.

Benefits of procedural generation

We've looked at some of the key ways in which procedural generation is used in games. So now let's take a look at some of its most important benefits.

Larger games can be created

If your game world is hand-built, it's going to have size restrictions for a number of reasons. Every object needs to be placed manually, every texture/model needs to be handcrafted, and so on. All of this takes time and money. Even the largest handcrafted game's world sizes, such as those seen in The The Witcher 3: Wild Hunt and Grand Theft Auto V, pale in comparison to what procedurally generated worlds can achieve.

If a game utilizes procedural generation correctly, then theoretically, there is no limit to the world size. For example, No Man's Sky is a science-fiction game set in an infinite, procedurally generated galaxy. When you start to get really big maps however, hardware becomes a limiting factor. Areas that have been generated need to be saved to the disk in order to revisit them, and this quickly adds up. For example, to generate the biggest world possible in Minecraft, you will need around 409 petabytes of storage for the level data!

Procedural generation can be used to lower budgets

Making games is expensive. Really expensive. In fact, most AAA games cost tens, if not hundreds, of millions of dollars to make. With budgets that are this high, any option to save money is welcome. Procedural generation can do just that.

Let's say that we are working on a title that needs 100 brick textures. Traditionally, you'd have one of your artists create each brick. While they will have top quality, this will cost both time and money. Alternately, by utilizing procedural generation techniques, you can have an artist create a handful of resources and use them to generate however many resources you need to use.

This is just one example, and the same goes for modeling, design, and so on. There are pros and cons of using procedural generation in this way, but it's a valid option.

An increase in gameplay variety

If your game world is handmade, the experience that players have is going to be fixed. Everyone will collect the same items, the terrain will be the same, and as a result, the overall experience will be the same. The defining feature of procedurally generated games is that experiences differ. There is a sense of unknown to the game, and every time you play, there will be something new waiting that you haven't encountered yet.

An increase in replayability

Let's continue from the last point. If a game is linear, without any procedural generation, the challenge is gone after you've played the game once. You know the plot, you know where the enemies will be, and unless it has an amazing story or mechanics, there's not much reason why you'd want to play the game again.

However, if your game utilizes procedural generation, then the challenge is fresh each time the game is run. The game is always evolving; the environments are always new. If you look at the games that have the greatest replayability, they tend to be the ones that give the player the greatest amount of control. Most of these games will utilize some form of procedural generation to do so.

The drawbacks of procedural generation

As with anything, there are two sides to a story. Procedural generation brings a myriad of possibilities and enhancements to games, but there are considerations to be taken when implementing it.

More taxing on the hardware

As we now know, procedural generation is the creation of content through running algorithms. These algorithms can be intense and require a lot of computing power. If you develop a game that makes heavy use of procedural generation, you need to ensure that a regular consumer PC or console is able to meet its demands.

For example, if you choose to generate trees procedurally in an open world game, there's going to be a big load on the CPU and GPU whenever that area needs to be generated. Lesser PCs might not have the power to do so, and therefore, they may stutter.

Worlds can feel repetitive

Another potential drawback is the fact that worlds can feel repetitive. If you allow your game system to generate incredibly large worlds, but use few and basic algorithms to do so, you'll inevitably have a lot of repetitive areas being generated. Patterns and repeating areas will be very easy to spot, and this will diminish from your game greatly.

You sacrifice quality control

Computers may be faster at crunching numbers than us humans, but there's one thing that we're vastly superior at, and that's creativity. No matter how amazing the procedural algorithm is, you lose the human touch. The little changes and subtleties that a seasoned designer can bring to a project are sacrificed.

It also means that you can't guarantee the same gameplay quality to all players. Some players may generate a really great map that facilitates gameplay, while others may generate a map that actively prohibits it.

You may generate an unplayable world

In extreme cases of the previous point, a level that is completely unplayable may be generated. The risk of this happening depends on how well your procedural content is generated, but it should always be considered.

When generating a 3D terrain map, you may accidently generate a terrain that is too high for the player to climb, or blocks off an area that needs to be accessible. The same goes for a 2D map. Later in this book we'll be generating dungeon rooms randomly. So for example, we need to ensure that each room has a valid entrance and exit.

It is hard to script set game events

Continuing with the previous point, procedural generation is uncertain. If the entire world around you is generated exclusively procedurally and randomly, then it makes it almost impossible to script fixed game events.

Game events are pre-scripted events, and the nature of procedural generation is to create unscripted worlds. Getting the two to work together is a tough challenge. For this reason, games tend to use a mix of procedural generation and premade game development. With this, you get the fixed game events and moments that are needed to drive a narrative, and in between all of this, you create a unique and open world for the player to explore and interact with at their own whim.

A brief history of rogue-like games

Since we're going to implement what we are learning in a rogue-like, let's just take a second to look at their history. It's always great to understand the origins of the things that you are doing!

Rogue is a dungeon crawling game that was first developed by Michael Toy and Glenn Wichman and initially released in 1980. Every level of the dungeon was randomly generated along with the positions of the object within. Rogue defined the dungeon crawling genre and was the inspiration for many titles that followed. This is why we call games of this type roguelikes, because they are literally like Rogue!

Procedural generation has been a key element in roguelikes since their conception. This is why I chose the genre to introduce the topic. Together, we will recreate the iconic features that define the genre, and approach procedural generation with a very practical and hands-on approach.

How we'll implement procedural generation

At the very start of the book I gave a brief overview of each chapter and what we will be covering in it. Now that we've covered what procedural generation is, let's take a look specifically at some of the ways in which we'll be implementing it as we work towards creating our own roguelike game. This list is not exhaustive.

Populating environments

When we load the game for the first time our objects will be in fixed locations. We're going to start our efforts by fixing this, implementing what we've learned in this chapter about random number generation to spawn our objects at random locations.

At the end of this chapter there are a few optional exercises that include generating numbers within a collection of different ranges. I suggest completing them if you're not comfortable with it already, as we'll be relying on it to achieve this.

Creating unique game objects

One of my personal favorite aspects of procedural generation is the creation of unique objects and items. Knowing that there is a wide variety of items in a game is awesome. Knowing that the items don't even exist yet, and that the possibilities are limitless, is even better!

We'll start simply by initializing our object's member variables randomly, and move up to giving our objects unique sprites and properties. We'll also look at creating dynamic classes that can create highly unique objects from a single base class.

Creating unique art

Generating textures and materials from scratch using procedural generation is a very large subject. There are lots of ways by which this can be achieved. Traditionally, we use things such as Perlin noise as their basis function and then build upon it with patterns and colors. We're not going to go into this topic to this extent. Instead, we're going to use the built-in image processing features of Simple and Fast Multimedia Library (SFML) to create unique textures during the runtime.

Starting with a simple approach, we'll change image properties such as size, color, and scale to create a variation in the existing assets. We'll then use render textures to combine multiple sprite components on the fly to create unique assets for our enemies.

Audio manipulation

As with graphics, SFML offers a number of functions that allow us to modify sounds. Therefore, we'll use these to alter the pitch and volume of our sound effects to create variance. We'll then use advanced functions to create 3D spatialized sound, bringing depth to the scene through our audio.

Behavior and mechanics

It's not just the static items and resources that can be generated procedurally. To add more variance to our gameplay, we'll use some procedural techniques to create dynamic gameplay mechanics. Specifically, we'll create a system that will generate a random goal for the player, and present them with a random reward should that goal be achieved.

We'll also give our enemies some basic Artificial Intelligence (AI) in the form of A Star (A*)pathfinding, allowing them to chase a player through the level.

Dungeon generation

Towards the end of the book, once we're comfortable using Random Number Generator (RNG) with procedural systems, and with our game project, we are going to implement the defining feature of roguelikes; randomly generated dungeons.

I've mentioned a few times that procedural generation can be used to create theoretically never-ending game worlds. So, we're going to do just that. We'll implement a system where every room that we visit is generated randomly, and we'll give each floor a distinct feel using the graphics manipulation techniques we'll learn in later chapters.

Component-based design

Procedural generation is all about creating dynamic systems, objects, and data. Therefore, it makes sense that we want the most flexible game framework that we can have so that it incorporates this well. One of the ways to achieve this is through component-based design. Therefore, to end our work, we're going to take a quick look at it, breaking our project down into a more component-based approach.

The complete game

These are the major systems changes that we'll implement. There will be lots in-between, but these examples will cover the major mechanics and skills that we will be using. When we reach the end of the book, you will have a fully working roguelike with an endless dungeon that is randomly generated, randomly generated items that spawn in random locations, procedural textures throughout the dungeon levels, and random enemies, all implemented with a flexible component-based architecture.

You will not only learn the skills needed to implement procedural generation in your own games, but also see how they all work in the context of one-another. Isolated exercises are great, but nothing beats working on a real-world example.

Exercises

To enable you to test your knowledge of this chapter's content, here are a few exercises that you should work on. They are not imperative to the rest of the book, but working on them will help you access your strengths and weaknesses in the material covered.

  1. Using the std::rand() function with the modulo operator (%), for updating random_numbers.cpp to generate numbers that fall within the following ranges:
    • 0 to 1000
    • 150 to 600
    • 198 to 246
  2. Come up with a new way of generating a random seed during the runtime. There are lots of ways to do this. So be creative! In my solution, the first numbers were always similar. Find out whether you can generate a random seed that mitigates that.
  3. Have a look at your game collection and find out whether you can identify where procedural generation has been used.
  4. Which of the following are examples of procedural generation?
    • Loading a song
    • Ragdoll physics
    • Creating unique objects during the runtime

Summary

In this chapter, we learned that procedural generation is the creation of content by using algorithms. This concept can be applied to all digital media and is used in games to create dynamic systems and environments. Procedural generation brings larger games, variety, and dynamism; all at the cost of lesser control, and potentially lesser performance as it is taxing on hardware. Some examples of the most popular uses of procedural generation in modern gaming include terrain generation, texture creation, and procedural animation.

In the next chapter, we will take a look at the project that has been supplied with the book. As we learn to create procedural systems, we will be implementing them in a real game project, with the ultimate goal of creating a roguelike game, a genre that heavily utilizes procedural generation. We will review the game template, the SFML modules that we will be using, and get the project setup. Then, we will compile it on your system.

If you are familiar with C++ game development and have used SFML before, you may already be familiar with the concepts presented in the next chapter. If that's the case, feel free to skim through the chapter to get right into the programming in Chapter 3, Using RNG with C++ Data Types.

Left arrow icon Right arrow icon

Key benefits

  • This book contains a bespoke Simple and Fast Multimedia Library (SFML) game engine with complete online documentation
  • Through this book, you’ll create games that are non-predictable and dynamic and have a high replayability factor
  • Get a breakdown of the key techniques and approaches applied to a real game.

Description

Procedural generation is a growing trend in game development. It allows developers to create games that are bigger and more dynamic, giving the games a higher level of replayability. Procedural generation isn’t just one technique, it’s a collection of techniques and approaches that are used together to create dynamic systems and objects. C++ is the industry-standard programming language to write computer games. It’s at the heart of most engines, and is incredibly powerful. SFML is an easy-to-use, cross-platform, and open-source multimedia library. Access to computer hardware is broken into succinct modules, making it a great choice if you want to develop cross-platform games with ease. Using C++ and SFML technologies, this book will guide you through the techniques and approaches used to generate content procedurally within game development. Throughout the course of this book, we’ll look at examples of these technologies, starting with setting up a roguelike project using the C++ template. We’ll then move on to using RNG with C++ data types and randomly scattering objects within a game map. We will create simple console examples to implement in a real game by creating unique and randomised game items, dynamic sprites, and effects, and procedurally generating game events. Then we will walk you through generating random game maps. At the end, we will have a retrospective look at the project. By the end of the book, not only will you have a solid understanding of procedural generation, but you’ll also have a working roguelike game that you will have extended using the examples provided.

Who is this book for?

If you are a game developer who is familiar with C++ and is looking to create bigger and more dynamic games, then this book is for you. The book assumes some prior experience with C++, but any intermediate concepts are clarified in detail. No prior experience with SFML is required.

What you will learn

  • Discover the systems and ideology that lie at the heart of procedural systems
  • Use Random number generation (RNG) with C++ data types to create random but controlled results
  • Build levels procedurally with randomly located items and events
  • Create dynamic game objects at runtime
  • Construct games using a component-based approach
  • Assemble non-predictable game events and scenarios
  • Operate procedural generation to create dynamic content fast and easily
  • Generate game environments for endless replayability
Estimated delivery fee Deliver to Australia

Economy delivery 7 - 10 business days

AU$19.95

Product Details

Country selected
Publication date, Length, Edition, Language, ISBN-13
Publication date : Jan 30, 2016
Length: 304 pages
Edition : 1st
Language : English
ISBN-13 : 9781785886713
Languages :
Tools :

What do you get with Print?

Product feature icon Instant access to your digital eBook copy whilst your Print order is Shipped
Product feature icon Paperback book shipped to your preferred address
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
Estimated delivery fee Deliver to Australia

Economy delivery 7 - 10 business days

AU$19.95

Product Details

Publication date : Jan 30, 2016
Length: 304 pages
Edition : 1st
Language : English
ISBN-13 : 9781785886713
Languages :
Tools :

Packt Subscriptions

See our plans and pricing
Modal Close icon
AU$24.99 billed monthly
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Simple pricing, no contract
AU$249.99 billed annually
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just AU$5 each
Feature tick icon Exclusive print discounts
AU$349.99 billed in 18 months
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just AU$5 each
Feature tick icon Exclusive print discounts

Frequently bought together


Stars icon
Total AU$ 213.97
C++ Game Development Cookbook
AU$61.99
SFML Game Development By Example
AU$75.99
Procedural Content Generation for C++ Game Development
AU$75.99
Total AU$ 213.97 Stars icon

Table of Contents

12 Chapters
1. An Introduction to Procedural Generation Chevron down icon Chevron up icon
2. Project Setup and Breakdown Chevron down icon Chevron up icon
3. Using RNG with C++ Data Types Chevron down icon Chevron up icon
4. Procedurally Populating Game Environments Chevron down icon Chevron up icon
5. Creating Unique and Randomized Game Objects Chevron down icon Chevron up icon
6. Procedurally Generating Art Chevron down icon Chevron up icon
7. Procedurally Modifying Audio Chevron down icon Chevron up icon
8. Procedural Behavior and Mechanics Chevron down icon Chevron up icon
9. Procedural Dungeon Generation Chevron down icon Chevron up icon
10. Component-Based Architecture Chevron down icon Chevron up icon
11. Epilogue Chevron down icon Chevron up icon
Index Chevron down icon Chevron up icon

Customer reviews

Top Reviews
Rating distribution
Full star icon Full star icon Half star icon Empty star icon Empty star icon 2.7
(7 Ratings)
5 star 28.6%
4 star 14.3%
3 star 0%
2 star 14.3%
1 star 42.9%
Filter icon Filter
Top Reviews

Filter reviews by




S. Morris Sep 11, 2017
Full star icon Full star icon Full star icon Full star icon Full star icon 5
I thought the book and the included code were a riot. The book opens with a working rpg game shell and you can follow the book and learn how to modify the game as you go along. How to add random foes and treasure and even create random stuff on the fly (procedural) It was a different concept for a book - great SFML learning tool to tear into the existing code to see how it works. Not a SFML starter book but if you have done one of the other packt books on SFML, or in my case two, you should have no problems picking this up. I think that the author (or publisher) missed an opportunity to add 100 pages and talk about the game shell programming first which would have made it ideal and better for the novice game programmer.
Amazon Verified review Amazon
William Oct 10, 2016
Full star icon Full star icon Full star icon Full star icon Full star icon 5
One of the best books I've read on game programming, and programming in general. For real!The author does a great job at explaining things, from simple to complex subjects, and provide all the assets you need to have a fully working game in the end. I'm new to game programming, and yet I'm able to follow along with this book just fine. Just beware that you should know some C++ before going into this adventure.Definitely worth the money. We need more content like this.
Amazon Verified review Amazon
Amazon Customer May 13, 2017
Full star icon Full star icon Full star icon Full star icon Empty star icon 4
Good clear book with a complete working game in c++.Easy to continue with more advanced sfml books.
Amazon Verified review Amazon
Zoe Oct 19, 2017
Full star icon Full star icon Empty star icon Empty star icon Empty star icon 2
In short: The goal of this book is to give only an introduction to proceduralcontent generation and is more for a beginner in C++ than for advanced coders.It comes with some errors and lacks for me some topics while could get rid ofothers.Pro:* showing how to randomize with rand and srand (because on iOS and Android it might crash with the C++11 generators)* explanation of pseudorandom number generators and simple vs. those used for crypto was ok* putting COUNT as last element of enum classes* creating a maze with codeCons:* a lot beginner level information ** setup (Visual Studio and Code::Blocks) ** OOP (polymorphism, inheritance, virtual functions) ** templates ** function overloading ** optional parameters ** modulo operator ** casting ** tips like "organize your code in a folder structure"* "out of scope topics" (topics which were said didn't fit into the book) ** procedural image creation such as with Perlin noise ** 3D terrain generation ** texture generation* not talking about C++11 random generators at all* sometimes using smart pointers, sometimes not (should be at least stick to one way)* showed only very simple pseudorandom number generation (also it might often be enough for the use-cases in the book)* when talking about storage concerns not talking about mobile clients (there the download size still matters...)* class diagram could have been printed in the book instead of being only available in the download* no CD - only download (Internet may change, so the contents might become unavailable)* repeated what the code does like "loop forever" in front of a while-true scenario multiple times in the comments* code errors and line-breaks even in the middle of variable names - once there is even a comment with a line break and the code afterwards sadly then looks like being part of the comment* use of C-array instead of vector - resulting in a section about how to return the C-array from a function - why not simply use a vector? (p. 97-98)* gray-scale screenshots in the printed book make it often difficult to see the differences, especially because the author often refers to that red or blue dot while both are just gray. Would have preferred to pay more for the book with colored images.* coding style differs in the examples* it's nice to have 3D-sound in, but I wouldn't call it a procedural generated content topic* I'm actually missing a block-based generated level like needed for Sokoban or side-scrollers, but because this book is only about one game, we only create a maze* p. 176 why is it not using the erase-remove idiom here?* sometimes "using namespace std;", sometimes not* component based architecture is not that great implemented. There are really better ways. Maybe a beginner would wirte it like that.* A* pathfinding was explained well, but for me that would fit more into an AI book - I mean it could be used to check the maze for being solvable, but that isn't even mentioned at that pointSo well - yes, it meets its goal, but I am somehow disappointed about the quality and contents. If the author would have let out all that noob-C++-coder stuff and the off-topic contents, he could have shown another way of generating levels (for example with blocks for a small Sokoban or side-scroller or whatever).
Amazon Verified review Amazon
Grzegorz Dalek Jun 20, 2017
Full star icon Empty star icon Empty star icon Empty star icon Empty star icon 1
I'm very disappointed by this book. It's lazy in terms of writing and presentation. Seems like a demo version or first draft rather than complete book. It clearly shows lack of experience of the author in the subject of procedural generation.There is no take on different approaches / algorithms. 80 % of the book is generating random number and hard-coding what it's supposed to do. Create classes for 5 different potions, and if you roll 1 then you spawn potion number 1. Here is the book. I don't think anybody who is proficient enough in C++ to understand the book needs tutorial on that.Parts of the book are repeated few times such as pros and cons of procedural generation. It's explained there 3 times each time taking few pages repeating the same stuff. Come on.The code is messy, chaotically explained. I was impressed by how complex explanation of the simple ideas was at times. There are parts of the book not even related to the subject - or hardly related such as how awesome component based architecture is in Unity or Pathfinding section with most basic implementation of A* explained.All illustrations in the book are black and white - and author uses color to illustrate the changes. As a result you end up staring at two or three identical images like a moron.If you're interested in procedural generation just look at the internet and you'll find way more comprehensive resources on the subject, for free.
Amazon Verified review Amazon
Get free access to Packt library with over 7500+ books and video courses for 7 days!
Start Free Trial

FAQs

What is the delivery time and cost of print book? Chevron down icon Chevron up icon

Shipping Details

USA:

'

Economy: Delivery to most addresses in the US within 10-15 business days

Premium: Trackable Delivery to most addresses in the US within 3-8 business days

UK:

Economy: Delivery to most addresses in the U.K. within 7-9 business days.
Shipments are not trackable

Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

EU:

Premium: Trackable delivery to most EU destinations within 4-9 business days.

Australia:

Economy: Can deliver to P. O. Boxes and private residences.
Trackable service with delivery to addresses in Australia only.
Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

Premium: Delivery to addresses in Australia only
Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

India:

Premium: Delivery to most Indian addresses within 5-6 business days

Rest of the World:

Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

Asia:

Premium: Delivery to most Asian addresses within 5-9 business days

Disclaimer:
All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


Unfortunately, due to several restrictions, we are unable to ship to the following countries:

  1. Afghanistan
  2. American Samoa
  3. Belarus
  4. Brunei Darussalam
  5. Central African Republic
  6. The Democratic Republic of Congo
  7. Eritrea
  8. Guinea-bissau
  9. Iran
  10. Lebanon
  11. Libiya Arab Jamahriya
  12. Somalia
  13. Sudan
  14. Russian Federation
  15. Syrian Arab Republic
  16. Ukraine
  17. Venezuela
What is custom duty/charge? Chevron down icon Chevron up icon

Customs duty are charges levied on goods when they cross international borders. It is a tax that is imposed on imported goods. These duties are charged by special authorities and bodies created by local governments and are meant to protect local industries, economies, and businesses.

Do I have to pay customs charges for the print book order? Chevron down icon Chevron up icon

The orders shipped to the countries that are listed under EU27 will not bear custom charges. They are paid by Packt as part of the order.

List of EU27 countries: www.gov.uk/eu-eea:

A custom duty or localized taxes may be applicable on the shipment and would be charged by the recipient country outside of the EU27 which should be paid by the customer and these duties are not included in the shipping charges been charged on the order.

How do I know my custom duty charges? Chevron down icon Chevron up icon

The amount of duty payable varies greatly depending on the imported goods, the country of origin and several other factors like the total invoice amount or dimensions like weight, and other such criteria applicable in your country.

For example:

  • If you live in Mexico, and the declared value of your ordered items is over $ 50, for you to receive a package, you will have to pay additional import tax of 19% which will be $ 9.50 to the courier service.
  • Whereas if you live in Turkey, and the declared value of your ordered items is over € 22, for you to receive a package, you will have to pay additional import tax of 18% which will be € 3.96 to the courier service.
How can I cancel my order? Chevron down icon Chevron up icon

Cancellation Policy for Published Printed Books:

You can cancel any order within 1 hour of placing the order. Simply contact customercare@packt.com with your order details or payment transaction id. If your order has already started the shipment process, we will do our best to stop it. However, if it is already on the way to you then when you receive it, you can contact us at customercare@packt.com using the returns and refund process.

Please understand that Packt Publishing cannot provide refunds or cancel any order except for the cases described in our Return Policy (i.e. Packt Publishing agrees to replace your printed book because it arrives damaged or material defect in book), Packt Publishing will not accept returns.

What is your returns and refunds policy? Chevron down icon Chevron up icon

Return Policy:

We want you to be happy with your purchase from Packtpub.com. We will not hassle you with returning print books to us. If the print book you receive from us is incorrect, damaged, doesn't work or is unacceptably late, please contact Customer Relations Team on customercare@packt.com with the order number and issue details as explained below:

  1. If you ordered (eBook, Video or Print Book) incorrectly or accidentally, please contact Customer Relations Team on customercare@packt.com within one hour of placing the order and we will replace/refund you the item cost.
  2. Sadly, if your eBook or Video file is faulty or a fault occurs during the eBook or Video being made available to you, i.e. during download then you should contact Customer Relations Team within 14 days of purchase on customercare@packt.com who will be able to resolve this issue for you.
  3. You will have a choice of replacement or refund of the problem items.(damaged, defective or incorrect)
  4. Once Customer Care Team confirms that you will be refunded, you should receive the refund within 10 to 12 working days.
  5. If you are only requesting a refund of one book from a multiple order, then we will refund you the appropriate single item.
  6. Where the items were shipped under a free shipping offer, there will be no shipping costs to refund.

On the off chance your printed book arrives damaged, with book material defect, contact our Customer Relation Team on customercare@packt.com within 14 days of receipt of the book with appropriate evidence of damage and we will work with you to secure a replacement copy, if necessary. Please note that each printed book you order from us is individually made by Packt's professional book-printing partner which is on a print-on-demand basis.

What tax is charged? Chevron down icon Chevron up icon

Currently, no tax is charged on the purchase of any print book (subject to change based on the laws and regulations). A localized VAT fee is charged only to our European and UK customers on eBooks, Video and subscriptions that they buy. GST is charged to Indian customers for eBooks and video purchases.

What payment methods can I use? Chevron down icon Chevron up icon

You can pay with the following card types:

  1. Visa Debit
  2. Visa Credit
  3. MasterCard
  4. PayPal
What is the delivery time and cost of print books? Chevron down icon Chevron up icon

Shipping Details

USA:

'

Economy: Delivery to most addresses in the US within 10-15 business days

Premium: Trackable Delivery to most addresses in the US within 3-8 business days

UK:

Economy: Delivery to most addresses in the U.K. within 7-9 business days.
Shipments are not trackable

Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

EU:

Premium: Trackable delivery to most EU destinations within 4-9 business days.

Australia:

Economy: Can deliver to P. O. Boxes and private residences.
Trackable service with delivery to addresses in Australia only.
Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

Premium: Delivery to addresses in Australia only
Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

India:

Premium: Delivery to most Indian addresses within 5-6 business days

Rest of the World:

Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

Asia:

Premium: Delivery to most Asian addresses within 5-9 business days

Disclaimer:
All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


Unfortunately, due to several restrictions, we are unable to ship to the following countries:

  1. Afghanistan
  2. American Samoa
  3. Belarus
  4. Brunei Darussalam
  5. Central African Republic
  6. The Democratic Republic of Congo
  7. Eritrea
  8. Guinea-bissau
  9. Iran
  10. Lebanon
  11. Libiya Arab Jamahriya
  12. Somalia
  13. Sudan
  14. Russian Federation
  15. Syrian Arab Republic
  16. Ukraine
  17. Venezuela