Minecraft is in a sense an earth simulator with animals oceans mountains trees weather day night cycle etc of course there are some differences on real earth you won’t find floating trees and armless cactus-like suicide bombers sneaking up on you but overall terrain is designed to feel earth-like Have you ever wondered how this terrain is actually generated well i hope so because that’s what i intend to talk about for a while in the caves and cliffs update we radically changed world generation the initial goal was to just add big mountains and improve the cave systems But we ended up changing almost everything to make the world more interesting more varied and more dramatic in the past terrain generation and games was just magic to me i didn’t understand how it works but now i’ve spent a bunch of time working with it and learned a lot And i find it kind of fascinating how you can do really cool things with just some math and a few lines of code first i’d like to talk a bit about size minecraft is big let’s compare with earth earth is a round ball with an area of about half a billion square kilometers A minecraft world is a flat square with a surface that is about three and a half billion square kilometers so about seven times larger than earth and that is only one world every time you start a new game of minecraft you will land in a new world Almost certainly a world that nobody has seen before because there are 18 quintillion different unique worlds that is an 18 with 18 zeros let’s compare this with our galaxy the milky way has about 100 billion planets so if each minecraft world was a planet we would need about 180 million milky ways It’s big minecraft is a digital world though not physical digital worlds take less space but they do take space every minecraft world is a grid of blocks think of it kind of like a rubik’s cube but instead of three times three times three blocks it is 60 million times 60 Million blocks wide times 384 blocks tall a digital representation of a minecraft world is really just a list of which block position contains which type of lock for example dirt here air there water flower etc storing one complete world would require about 97 000 terabytes in comparison the largest disk in the World is about 100 terabytes so that’s not even close to enough space to store world if we were to store all 18 quintillion worlds on disk we would need all hard disk space on earth times 200 trillion or so but yet the minecraft download is only About half a gigabyte how can that be where are those worlds stored well they aren’t stored at all not initially the download doesn’t actually include any worlds at all it contains the code to generate the world and that code is tiny in biological terms you could say that We aren’t shipping a body we are shipping the dna with instructions for making the body when you create a world in minecraft it looks like you are in an existing world that continues beyond the horizon but that is actually a carefully crafted illusion there is nothing beyond the horizon when You move in that direction the world gets created in front of you as you go you can see it happening if you move really fast and the game struggles to keep up this approach is known as procedural terrain generation so how does it work as you may notice as we move around the World is generated in chunks each chunk is a vertical column 16 by 16 wide and 384 blocks high the job of procedural terrain generation is to answer a very specific question what block should we place here it is basically a function we can call it getblock it takes a coordinate Expressed as xyz values and returns a block when generating a chunk we call this function for each position in the chunk so how do we make each chunk fit with its neighbors it is like a giant 3d puzzle where each piece just somehow magically fits seamlessly with each adjacent piece No matter which order we generate them in we’ll get to that chunks are actually generated in steps here is an example i made this chunk wider just to illustrate more clearly the first step is terrain shaping where we determine which blocks are solid and which aren’t basically just placing Stone or air at each position then we calculate which of the air blocks are beneath ocean a river or lakes and fill those with water then we apply a surface layer replacing the top blocks with things like grass sand dirt etc depending on the biome kind of like applying a coat of paint Finally we add features and structures such as trees and oars and villages in this presentation i will focus mostly on the first step terrain shaping how do we procedurally generate terrain that is random but also looks somewhat realistic and interesting let’s start with a very simple example What if we just make it random so the get block function returns stone or air with equal probability this is what we get this is actually procedurally generated terrain not very fun or realistic you can’t even get around in there but it is procedurally generated but let’s tweak it instead of just Random let’s decide that the surface of the world is at y 100 y is the vertical dimension in minecraft so the get block function returns stone for positions below y 100 and air for positions above dead simple but now we actually get a world that you can move around in And if we apply surface decoration we get something like this better than before right but the world is still all flat and boring though no rivers no mountains no oceans all the worlds look the same so our work is not done yet now that we have a surface height we Might as well randomly vary it instead of having it fixed at y100 in this case we say that at each position the surface height is 100 plus a random number between 0 and 19. one thing about the code examples in this talk i’ve simplified the code quite A lot to make it easy to read skipping all performance optimizations things such as interpolation and caching that would be a separate topic anyway now we have a terrain with a random surface height but it looks kind of messed up right there’s no continuity or smoothness to it how can we fix this Sine curves are actually a good model for this here is a graph of sine x it goes up and down smoothly and it continues forever in both directions if we extend it to the left or right each part of the curve fits perfectly with the part before What if we generate our terrain using a sine function here we go surface height is now 100 which is our base terrain height plus sine x times 10. sine x returns a value between negative one and one depending on x position which is the east-west dimension in minecraft We then amplify the result by a factor 10 in order to make the difference more visible in the terrain this is what we get the train is basically a sine curve i’ll make it configurable using two variables frequency and amplitude and using that we can easily get terrain like this Alright so now we have smooth terrain and it moves up and down just like in real life and the code is still very simple let’s make this sine curve apply to the north-south direction the z-dimension as well as east-west this gives us round hills And while we’re at it why not add a sea level let’s define sea level as y 102. so any position that is above the surface height but below sea level should be water cool now we have a procedurally generated world that is starting to look like an actual world and still with very Little code but wait what about the randomness all parts of this world will look the same how do we get randomness without sacrificing smoothness and continuity in 1983 a smart fellow named ken perlin came up with a cool mathematical trick which came to be known as purlin noise Imagine a random field of black and white gray dots kind of like tv static in an old tv set now imagine smoothing it out so each pixel is somewhat similar to the neighboring pixel instead of just a random mess you get something like this like a smudged version The general term for this is gradient noise purlin noise is just one way of achieving it this is an example of 2d purlin noise that is two inputs and one output the inputs in this case are x and y coordinate and the output represents the brightness of the pixel at that position But we could just as well treat this as a height map with white blobs as hills and the black blobs as valleys we could generate terrain based on this here’s an example of 1d perlin noise the x-coordinate is the single input and the y-coordinate is the output This could be a height map in a 2d side-scroller game or it could represent the tree height in different parts of the world or difficulty level or maybe precipitation levels in different parts of the world it’s really up to you how you use the data but the approach is useful for all Kinds of things basically anytime you want smooth randomness let’s put this to work in our get block function i’m not going to get into the internal math of how perlin noise is calculated there are plenty of third-party libraries that do it for you so you don’t really need to know So i’ll just assume that we have a purlin noise object as a helper the code is really simple we sample the noise at the given x z coordinate which will give a value between negative one and one we amplify it again by a factor 20 And add it to the base terrain height of 100 so now the terrain height varies smoothly between y 80 and y 120 check it out pretty smooth eh i can keep going in any direction and the world will be generated procedurally in front of me and it all fits together really nicely For further variation we can apply a neat trick called octaves let’s use the sine curve as an example again let’s pretend this is a purlin noise graph and the y-axis is the terrain height so we have a valley over here to the left and a hill to the right okay now Let’s make a second curve this one with a higher frequency and a lower amplitude i’m going to call it y2 let’s say that also represents terrain height so let’s add them together y1 plus y2 and we get this at a large scale we still have a valley And a hill but on a smaller scale kind of overlaid on top we get some up and down terrain happening within the valley and on the hill just like in reality let’s add a third octave again with higher frequency and lower amplitude and add it all together now the terrain gets even more Interesting and varied while still maintaining the high level valley and hill shape and remember this is just a sine curve there’s no randomness here even this is what it looks like with actual purlin noise one octave two octaves and three octaves we could of course tune the frequency And amplitude of each octave but a good simple default is that each higher octave has double the frequency and half the amplitude all right back to the code i’ve now adjusted the purlin noise class so that it takes the number of octaves as a parameter that’s it Internally it does exactly what i showed you so when i call sample 2d of x and z it is actually doing four samples and adding them together as i showed with a sine curve the result looks like this much more interesting much more realistic and the code is still simple the only Cost is performance because more octaves means the computer needs to work harder there are ways to optimize that but i won’t talk about that here let’s decorate this a bit adding water and surface decoration and trees it looks pretty cool right i find it amazing how far you can get With just a few lines of code when generating terrain in this way however there’s still something missing as we move around in this world it initially looks really nice but after a while it starts getting pretty repetitive the terrain is random and somewhat natural looking yeah but missing more dramatic real-life Features like cliffs river valleys plateaus mountain ridges where is the drama right how can we make those kinds of things happen while still maintaining the smooth randomness an example earlier we applied a noise transformation when calculating the terrain height at a given position we sampled the purlin Noise at that spot to get a value between negative one and one and then we transformed the value by multiplying by 20 and adding a hundred the result is a surface y in this case between 80 and 119 to make more interesting terrain we wanted to enable more advanced Transformations without making the code really complicated and we ended up using spline points for that i’ll show an example let’s give our noise field a name continentalness each part of the world has a value of continentalness it varies from negative one to one the purpose of spline points is to Define how continentalness influences terrain height for starters i’ll add two spline points the first point says at continental negative one the terrain height is one hundred the second point says at continentalness one the terrain height is still one hundred using these two points the system will use spline interpolation To figure out the terrain height at all different values for continentalness and that’s just a fancy way of saying it will fit a curve to those points in this case the result is a straight line terrain height is always 100 regardless of continentalness we have effectively created a flat terrain But using this approach we can now easily start shaping the terrain by simply adding or moving spline points let’s say that a noise value of -1 means terrain height 50 and a noise value of 1 means terrain height 150. fitting a curve to these points gives us a direct relationship high Continentalness means high elevation and vice versa in effect this means continentalness noise directly represents the height of the terrain kind of like where we were before um again not very exciting where is the dramatic terrain we’re looking for well okay let’s spice it up here we say that as continentalness goes From negative 1 to 0.3 terrain height goes from 50 to 100. a pretty gradual change but then in this small span from 0.3 to 0.4 terrain height shoots up to 150 which is a very sudden increase and then beyond 0.4 terrain height stays at 150. this tiny change of just a few numbers Gives us a terrain that is completely different from before with steep dramatic cliffs and plateaus on top pretty cool right to add even more variation we actually use three different noises to control terrain height not just one we call them continentalness erosion and pv or peaks and valleys Each with its own configuration of amplitudes and octaves as you can see here in the picture they look quite different as you travel the world each position has values for each of these noises they are normally not visible to the player but if you’re curious you can see them In the job edition of the game by pressing f3 in a single player world so this is basically how we do it this is how we generate the world we’ve configured a bunch of spline points describing how these noises should influence terrain shape for example steep mountain ridges form Where pv noise is high continentalness is high and erosion is low when erosion is high the landscape is generally flat regardless of the other noises we’ve spent a lot of time fine-tuning these spline points to get just the right mix of terrain types but the nice thing is that the code is Actually quite simple and consistent just a bunch of spline points here’s an example a relief map where you can see rivers and lakes and mountain ridges and all kinds of different types of terrain this system is very flexible it allows us to make dramatic changes to the train by Changing just a few numbers here and there and sometimes with very unexpected results when we add biomes and surface decoration and features it gets even more varied and interesting when working on this i felt kind of like slotty bart fast a planet designer and hitchhiker’s guide to the galaxy Especially when working on on the fjords okay i admit i’ve oversimplified things a bit the stuff i’ve talked about so far is used to calculate the overall terrain height but when it comes to the detailed shape of the terrain that is actually done using 3d noise bear with me i’ll try to explain The problem with 2d noise is that you can’t get overhangs and super weird random terrain the kind of terrain that minecraft is famous for so what is 3d noise then how does that help us create super weird random terrain that minecraft is famous for well 3d noise just means a purlin noise Function that takes three inputs and gives one output in our case the three inputs are x y and z coordinate and output is something that we call density so each block position has a density value from negative one to one you can’t see it anywhere in the game Because it is used to calculate the terrain shape and then it is thrown away um because it is a purlin noise the values change gradually not suddenly so what happens if we treat positive density as solid and negative density as air you get a very strange but interesting World like this some kind of crazy swiss cheese cave world now let’s apply a height bias density is decreased the higher we go and increased the lower we go and there’s a center point say at y100 where density is left unchanged this effectively squashes the terrain When we are high enough above y 100 density will always be negative and hence there will only be air and when we are deep enough below y 100 density will always be positive and hence there will only be stone this is how the base terrain generation is calculated in minecraft it is Controlled by two parameters squashing factor and height offset if squashing factor is high we get flat terrain and if it is low we get fractured crazy looking terrain or even hanging blocks height offset moves the whole terrain up or down so that is the base terrain elevation both squashing factor and terrain Elevation are configured via terrain shaping the thing i showed earlier where spline points are defined based on continentalness erosion and peaks and valleys so if you see some crazy looking terrain in minecraft that is because squashing factor is low thus exposing the 3d noise 3d noise is also used to generate the New cave systems we use the same basic approach giving each block position a density value i’ll illustrate it using 2d here’s a noise field again like the tv static but smoothed out right if we decide that white is air and black is stone then this already gives us cool looking caves We thought this looked kind of like swiss cheese so so we call these caves uh cheese caves they typically generate large caverns like this and the size and shape of them can vary quite a lot to create long tunnels we apply another variant of the approach Instead of saying that white is air and black is stone we say that the border between white and black is air and the rest is stone this gives us long spaghetti-like tunnel systems so we call these spaghetti caves it is slightly different in 3d but you get the general idea These tunnels can get very long we combine these two approaches to generate interesting cave systems with a ton of variation in size and shape in fact i still get surprised quite often by the caves i find even though i’ve worked so much on this okay i’ve talked a lot about terrain Shaping and i’m going to wrap it up by talking a bit about biomes a minecraft world is divided into distinct biomes such as jungle or desert or forest think of the biome as a thin layer of material on top of the underlying terrain shape for example a jungle bio Will add a bunch of jungle vegetation to the train and a desert will add a bunch of sand biomes also control which types of creatures and features appear there for example desert temples can only appear in deserts while igloos appear only in snowy biomes such as snowy plains Biomes have a major impact on gameplay experience here’s an example of the same terrain shape with desert meadows grove badlands swamp and jungle they look completely different so one important part of terrain generation is determining which biome to place at which position in the world and how do we do that Well guess what more pearl and noise of course biome placement is done based on the three noise fields i already mentioned plus two more temperature and humidity so each point in the world has separate independent values for continentalness erosion peaks and valleys temperature and humidity and the values change gradually as you Move around the combination of values at each position of course determines which biome is there and we configure that through a bunch of tables i’ll show an example this configuration table is applied when peaks and valley’s noise is high that means we’re potentially on a ridge or peak To make biome configuration a bit simpler we’ve taken the different noises and split the values into specific ranges so erosion index 0 represents all erosion values from negative 1 to negative 0.78 for example and we kind of sliced up the value space in this way so let’s say continentalness is high and Erosion is low this means we should use a peak biome the specific peak biome in turn depends on the temperature noise in this case temperature was low so we ended up with jagged peaks a bit further off we find a place with high value for peaks and valleys So we are still on the same table but over here continentalness is low and erosion is somewhere in the middle so this tells us we should pick a middle biome and what is that well that in turn depends on temperature and humidity which is configured in this table over here So we look at that and in this case humidity is high and temperature is high so we’re in a hot humid area and therefore we pick jungle unless weirdness is positive in which case we pick bamboo jungle instead um weirdness is yet another noise that i haven’t talked about but never mind that For now anyway long story short we use a bunch of configuration tables like this to specify which biomes should apply to which combinations of these noises and when doing so we take into account the terrain shape the desired biome size and rarity and also which biomes make Sense to place next to each other a lot of tinkering around for example we try to keep warm biomes like desert and badlands close to each other and not directly neighbor cold biomes such as taiga configuring this is actually quite tricky because it is effectively a five-dimensional matrix that we are Trying to put stuff into that means each cell has up to 10 potential neighbors to take into account trying to understand this can be a bit mind-bending it took me quite a long time to be honest but if you want to you can pause and stare at this drawing until you either Understand or go insane okay let’s wrap this up so what are the takeaways from this talk well surprise there are none or more like it’s up to you i won’t serve you any specific learnings or takeaways i learned a lot when working with this stuff and um i hope you found that interesting And even if you don’t play minecraft yourself maybe you have friends or kids who do and now you can impress them with your vast and deep understanding of how things work behind the scenes thanks for watching Video Information
This video, titled ‘Minecraft terrain generation in a nutshell’, was uploaded by Henrik Kniberg on 2022-02-06 21:59:11. It has garnered 113565 views and 9478 likes. The duration of the video is 00:25:49 or 1549 seconds.
In the Caves & Cliffs update we radically changed Minecraft terrain generation, rewriting large parts of it from the ground up. This video summarizes how this actually works, how simple math and code can be used to generate interesting, beautiful, and dramatic terrain.
00:00 Intro 1:14 Size 3:11 Procedural terrain generation 8:47 Perlin noise 13:04 Terrain shaping 17:37 3d noise 20:10 Cave generation 21:27 Biomes 25:13 Wrapup
Intro and outtro music: Some homemade music I had lying around. If you enjoy you can find more here: https://open.spotify.com/album/0jr9Z7FQP5kpRZWoLDD9ZD