Joust – It Begins

As I mentioned in my last post, which was incidentally also my first post, we are just starting up a big project based on the old school arcade game joust. We are taking the rider-on-flying-mount and the insta-kill dynamics and expanding upon them to create a large, multiplayer, persistent world. It is a big project to be sure, but exciting enough to get a couple people interested in it, which is really the goal.

One of the key features of the game is the large world it takes place in. We (the design team) want a really big world, but I (the one who has to actually do it) certainly don’t want to hand edit/model the terrain and platforms that would go into creating it. So, in comes step 1/1000 – procedural terrain generation. Basically, the goal is to create an algorithm that can be used to automatically create each piece of the world, as broken down into ’tiles’. To manage memory, we want to only load the tiles surrounding the player’s current position, so the algorithm needs to be able to get just the tiles we need and render them in real time.

The first thing I did was create a terrain generation algorithm to make simple, smooth ground for a single tile. For this I used a technique called ‘midpoint displacement’. It sounds fancy, but it is actually a very simple algorithm where you simply bisect a line and adjust its middle by a random number over and over until you get terrain. I set it up to seed the random number generator first so I could create exactly the same tile by just passing in the same seed. This also means that it generates different tiles for each new seed. Each tile has a unique location in the world, so by passing that in as the seed, I effectively have a function that will create every tile in the game! Simple, but cool!

I also added in a region dynamic so I can break the world into regions and the tiles within those regions will get created with different parameters. For example, mountain tiles will be generated with more steep cliffs, while plains tiles will be mostly flat.

Behold, some random heightmaps for tiles! The first three were created with exactly the same parameters, but different seed values. Note, these are NOT rendered ground tiles – this is just a silhouette of the 2D landscape for each tile. The last three are more random tiles, but this time I have tweaked the generation parameters to give much smoother terrain.

This is great so far, but it is still missing something. At the moment, all the tiles start and end at the same height, which is totally boring and unpractical for the game itself. What we need instead is a way to add variety to all their end points while making sure each tile lines up with the ones on either side of it. I still didn’t want to do this by hand though, so I decided to just make another algorithm. This one does exactly the same thing, except instead of telling the program where to render land, it tells each tile how high to go when generating terrain.

This controls the shape of the entire world, and since there is only one of them, it is important to pick a good one. To make it easier on myself, I created a little ‘world viewer’ program that generates these world maps and displays them along with all the parameters used to create it. It also allows me to zoom in and out to inspect certain areas, change parameters on the fly, and drag the map itself around for better viewing. You can see it in action below:

YouTube Preview Image

Next time: putting the tiles together to create one huge map, then picking regions and texturing the tiles so they look like ground instead of weird lines.

This entry was posted in Bonk and tagged , , , . Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*