Senior Defense and Procedural Terrain Generation

Senior defense is coming up, and it’s given me the opportunity to look back at all the projects I’ve done over the years at CCNTH. In this post, I’m going to be writing about my Easter Island game, which you can play in your browser at https://nathanlackie.net/easterisland/ (press f to turn on flashlight). I am using this game as my Junior year artifact in my senior defense. It’s fairly unassuming on the surface, but a lot of work went into this game.

One thing I focused on when making this game was procedurally generated terrain. Which, in simpler terms, basically means the shape of the island land wasn’t manually designed by me, but instead is generated by mathematical functions. If you picture an island in your head, you can imagine the shape it would take. How would you model an island with a math function? Well, you can’t use a typical 2D graph like a circle or parabola, you need to use a 3D graph. Imagine a plane, with an X-direction moving left and right, and a Y-direction moving up and down:

You can imagine this being a top-down view of the island. Each point on this plane has an associated X and Y value. We can then make a third axis to this plane perpendicular two both of our existing axis. This looks something like this:

The X and Y inputs represent the position on the island, and the new Z-axis represents the height of the land.

Okay, now that I’ve done my best at explaining a 3D graph, we still need a function that generates the rough shape of an island given these X and Y coordinates. Back to what I said earlier, picture an island in your head. One of the key features of an island is that it’s higher above sea level the closer you get to the center. So we want our function to return higher values the closer we are to the origin of our X/Y plane. To do this, I used the distance formula, which is simply sqrt(x^2+y^2). There’s a problem though, this returns the distance from the origin, so this is precisely the opposite of what I want to achieve, with further values from the center being larger. Luckily, the solution to this is fairly simple, I can just take 1 minus the distance. After smoothing out this distance function using something called smoothstep, we get a 3D graph looking like this:

(made in my Desmos 3D grapher, which is a whole other topic)

As you can see, this takes the very general shape of an island. In real life though, things aren’t perfectly smooth like the 3D graph above. Real terrain has bumps. I used a method called perlin noise, which, to be fully honest, I don’t really understand the functions behind how it’s generated. Luckily for me, Unity has a built-in method for generating Perlin Noise. An example of perlin noise is shown below:

This is a representation of perlin noise, plotted on the X/Y plane mentioned earlier. Black spots are a Z value of zero, white spots are a Z value of one, and gray spots are somewhere in-between. By adding this noise to my height graph, it adds some randomness to the terrain, so it’s not perfectly smooth. This ends up looking something like this: 

As you can see, I had a lot of fun with this project. As I near the end of this blog post, I’m realizing I didn’t write much about Senior defense or any of the other components of the game, but instead just nerded out about terrain generation algorithms. I plan on going into Computer Science as a career, so I chose this project as a senior defense artifact due to how many Computer Science concepts I used in making it. This is the longest blog post I’ve written so far by far, so I hope you found nearly 700 words about video game math interesting.

work in progress

This website is currently under development. Expect bugs and changes to occur. If you have any questions or feedback, tell me in the “Contact me” section at the bottom of the home page.