Over the past few weeks, we’ve been adding a lot of randomness to our game, Project Skyring. In addition to the standard random appearance of enemies and their configurations, we’re also randomly generating the hex grid islands that form our map’s terrain. These hex tiles include beaches for landing and taking off, plains for quick movement, forests that generate enemies and impede movement, and impassable mountains.
Each island is created using a seed that starts by defining whether the island will be small or large. Then, using that for the range, it generates spurs in 6 directions (starting from the original hexagon tile) and fills in the gaps. Once the generic “stem cell”-like hex tiles are laid down, they transform into other tiles based on a few rules. Beaches border oceans, forests come in clumps at least a short distance from the coast, and mountains come in clumps towards the middle of the island. After that, various nodes used for enemies are laid down and possible items or checkpoints are generated.
Except for where rules takeover, most of these decisions are “random.” We’re putting random in quotes like any computer programming book will likely do when first introducing the concept because computers aren’t random. They use complicated methods to turn data (seeds) into numbers. The most common “random” method is to use the system time as the seed for generating a random number, which GameMaker: Studio will gladly do for us as long as we call Randomize().
There are other options, however, when you want to control the randomness. In most games, you have no reason to do that, but in Project Skyring, we can take advantage of the computer’s non-random nature to give the appearance of randomness, while actually remaining in control.
Why would we want to do this? Well, the first, and less important reason is debugging purposes. As in Episode 21, sometimes the random islands don’t give us the conditions we need to test a code change. (For example, no mountains when we want to test something with mountains) The other reason is that we actually don’t want our game world to be a giant random mess. For example, in Episode 23, we’ll be doing some winter islands (as it is the Christmas season), so we might want to make the islands trend more and more towards snowy islands as the player journeys up=north, down=south across the world map. If we control the seed, we could add a few markers to the front of the seed to do this for us.
An example might be: If the first digit in the seed is 0, make a normal island, if the first digit is 1, make a snowy island, etc. Or we could get more precise by saying 1 means a 25% chance of a snowy island, 2 means a 50% chance of a snowy island, 3 is 75% and 4 is 100% just to smooth out the world transitions. We could also use those percentages when building the islands themselves, so it’s not just a full-on snowy island followed by a full-on normal island.
Although we’ll be using some of the digits in the random seed to control the pattern, there are still more than enough other numbers to give us the randomness we need for each room to feel different. By manipulating the seed directly, we can obtain a good balance of patterns with randomness.