Hello welcome to our second video where we’re making minecraft a kind of minecraft simulation um using python and peta amlan’s wonderful cena 3d engine apologies for not getting a video um sooner i’ve had some technical issues okay so what we did last time was we installed our cena We’ve created two modules our main module which has our update loop in and creates our first person character sets up the window color things like that and then a mesh terrain module which actually generates this terrain at the moment we’ve just got one chunk here we’ve made It very big let’s see if i can run to the end of it to the edge so we’ve made it 128 blocks by 128 blocks and eventually in a couple of videos time what we’re going to do is um make this a lot smaller but generate in A like a swirl around our player so that it follows wherever the player is walking and so for all intents and purposes our terrain will be infinite so an infinitely procedural or infinite procedurally generated terrain that’s what we’ll do so in this video what we want to do is Firstly so we’re not just walking through blocks we want to be going up and down so we want to sort that out and what we’ll do is when we make each of these blocks we’ll record its x and its z position but also its y position so it’s height And then we can say if there’s if we like move on to this block we can like check is there a block a couple of blocks below us if there is then step down onto it if there’s a block in front of us just one Up step onto it then we’ll have like a step height so we can’t like step on to like six blocks high or anything like that um and we can then yeah refer to our dictionary so that’s where we’re recording all of our block positions to check if there are any blocks there to Step on onto then also what we want to do is create some hills and valleys using purlin noise which you’ve probably heard about that’s where we can put in a seed a seed number and it generates different uh terrains just like in minecraft right let’s get started so i’m going to Use shift q to close down the program there we go and right so in the main module which is just under should be under like 20 lines there we go what we want to do yes in our update function we want to um say something like um Block found have we found a block and we’ll say that’s false to begin with and then later on after we’ve checked to see if there are any blocks to step down onto or up onto we want to say if a block has been found so if that equals true then We’re going to say our subject’s um height so our subject of y our subject position is going to equal and now we’re going to use a lerp function lurk like that so that’s linear interpolation that means if you’re very far away from something move it towards The target very fast and as you get closer slow down so it’s a nice smooth way of of animating some movement and this movement is just stepping up or stepping down um so we’re going to move from or lerp from our subject’s current y position to A target we haven’t made that yet we’ll make that in a moment and then we want to do this at the same time for um any computer or if your computer is running other stuff and it’s going slower it will be multiplied by this number so we’ll say um about six multiplied by Time dot delta time so this delta time is a thing often used in games when you’re inside an update loop and you’re moving something or animating something you want that to happen at the same rate no matter how fast or slow your computer is running at the time and so what Time that delta time does is look at your frame rate and then if you’re if your computer’s like running very slow it’ll make this number higher if your computer is running very slow fast then it will make this number lower so it makes it run the same speed On whatever computer so there we go so that will move our subject to the height we need um but if block found is false or i guess i could just write else we’ve already checked if it’s true up there else our subject’s height will minus equals so we get less and less It will equal what it was before minus um and we’ll say 9.8 that sounds like the earth’s force of gravity like the acceleration under which you fall on the planet earth multiplied by time dot delta time because again we’ll be moving an object in this update loop so We want to smooth it out so it’s the same it looks the same and behaves the same on any computer it’s nice and reliable right so that’s gravity and that’s stepping up or stepping down so let’s just write a little comment so use a hashtag in python we want to write gravity full Um unhappy face or that face whatever that is typo and this one is um step up or down smiley face there we go oh should i do that one okay so at the top of that update loop we’re saying block is found so here we need to actually check The blocks below or above us just in front of us to see if there is a block there so first we need a step height so let’s go maximum of two blocks down or up now we want the height of our player to add on to the target so we’ll say i Think one point eight meters is about six foot so put eight was it eight six my memory seems to say um and then we need uh target will be just the subjects y actually we don’t need to write that in yet we’ll write that later on now we need a For loop so we’ll say 4i in range range i want to go from minus our step height so that’s two down to step so that’s just plus depth so that’s higher and then we can add i onto the subject’s height to be able to step down or step up So we want to say if now what are we actually checking we need to see if there’s a block in this subject’s position but at the moment we haven’t recorded where our blocks are being created so let’s just save our main module at the moment and we’ll go and add a dictionary To our mesh terrain class so here we are in the mesh terrain module here’s our mesh terrain class which we built ourselves and we’re going to add in the initialization function in the constructor function this is where you like create all the properties that you want your object to Have we’re going to say it has a td and that’s done for a terrain dictionary so i’ll just write that in into a comment our terrain dictionary definitely a big smiley face because that’s quite exciting so to make a terrain dictionary a bit like a list Where you would or an array in other languages where you use square brackets to say i want this variable to be a list or an array to make it a dictionary use the braces or curly brackets and what happens inside of here is you’re going to store a key Let’s just call this key a key and then use a colon to give that particular key a value and the value could be 84 it could be banana it could be a boolean true you get the idea we’re going to store probably something that says t for terrain i.e there’s terrain here if We write gap there’s going to be a gap that we’ve mined or the key might not even exist if we’re at a particular position so we’re going to store something that’ll look like the x position 4 a y height of 7 and z will be minus 14. So that’s what our key is going to look like so that means we can build that key to get a value to see if there’s some terrain there if there is it will say t if not not and anyway if we wanted another key and Value we’d put comma and then i can go to a new line let’s say to make it clearer and then the next one would be my x 6 y 55 z minus 14 again something like that and then it would have its value so this one would say t this one might Say gap and so on right you’ll see how that terrain dictionary works in a little while we’re just going to make it or declare it up there so then in the generate block function when we’ve created our block we can then say this dot td now we want to use Square brackets here to build a new key and so we want it to say x plus now we want this x value here but it’s got to be a string if i put that i can’t add a number to a string i’ve got to make x into a string so if i Just write str and then wrap the x around the x with parentheses that will convert that x into a string so now i’m writing x plus that number but as a string and so that’s done but i also want this number i don’t want it to be somehow like 7.8 I wanted it just to be an integer so i’ll just write floor and then again brackets around the x so i’m doing two things first i’m making sure it’s flawed so it’s just an integer number a whole number like one two three or minus seven something like that and then Wrap all of that in a string so it’s a string a character that i can add or concatenate to this other character okay plus and then we want to do the same things for y and z so let’s just copy all of that because i’m in square brackets i can go To a new line oh that’s lined up really nicely and then z and i won’t need the plus on the end so i can take that one off so that needs to be a z that needs to be z this one needs to be y and that needs to be y There we go so now i’ve built the key part so i’m building a new key and then i want a value at that key and i’ll call that t just for terrain is here so after all that let’s just record a little comment and i call it sorry record terrain in dictionary Smiley face done okay so now every time we create a block using generate block we’ve recorded the position and height of that block which means back into the main module so we were in the update loop we were just creating this for loop where we’re checking the heights of Blocks where we’re standing to see if we can step up or step down so if uh let’s get hold of our terrain because our terrain is our mesh terrain object which has the terrain dictionary attached to it so we can say if terrain dot td that’s a terrain dictionary and Now you use the dot get function and then you put in here not square brackets but parentheses the key that you want and you can see if there’s going to be a value there so we’re going to say again it’s going to be a similar thing x plus And now we want our subject’s position so let’s just write our x here so we’re going to say x equals subjects dot x um plus 0.5 the reason i’ve done that let’s just go to our diagram to explain um let me just undo a few things right so let’s say We’re looking down on a block here’s a block now our player actually stands there at the bottom left of it but we want to measure our position here so exactly on it and then it’ll line up with the proper edges as we move across a block So in other words our real position is there but we just want to add halfway along the block to move us to the central position so in other words that’s not 0.5 across the x and then again 0.5 up on the z then we’ll line up with our terrain as we see it Um and because i want this to be an integer i’m going to floor that there and actually i want to wrap it in a string thing because i want it to be a string because we’re building our terrain dictionary key so i’m going to copy all of that Because z is going to be exactly the same except for z equals and then dot z y is going to be a bit different actually because we’re going to have to add this little iterator i to it because we’re checking height so we need to do a bit of an Arithmetic before we make it a string so let’s take off string and we’ll leave 0.5 by the same logic we want to be not at the bottom of the the cube but like halfway through it anyway so we floored that and now we can say the character x plus the the value Of x although that is now a string plus um y the letter plus the value of y oh so now we need to wrap this little bit in a string but we want to do y plus i in there so that will change as we’re going Around our loop it will be y plus minus two then plus minus one then plus zero then plus one then plus two says checking if we can step up or down and that needs to be the last one um character z plus the values there there we go so That will build our terrain sorry our key and we want to say if that equals equals t so if there is some terrain there colon then we’re going to record that height so target remember we’re going to use target down here in our lerp function we’re going to move our player’s Position to the target so i’m going to say target equals this current y that we’re checking um no it’s going to be subject dot y plus oh no we’ve already included the subject here haven’t we so it is just y plus i so the current step up or step down And then we want to add to our target height the actual height of the player so we want to add on how tall the player is as well so we put height there so you can change that 1.86 lower or higher depending on what you want maybe if your character Isn’t like a person but like a little hovercraft it might be a lot lower so you can zip over the terrain and stuff there we go so we’ve recorded that and then we want to say um block found is true and then we can break From the loop so if you write break it will stop checking just break out and then um found block will be true so we’ll do that else we’ll fall down okay right let’s try and run that let’s run that so i’m in my main module so you can’t run Stuff from the mesh terrain module you have to go back to the main module that’s like your base and then run it from there okay oh i look a bit taller so i think it’s working ah we stepped up step down step up sit down step up we’re moving about the Right speed up and down you see how it’s smooth it’s kind of like a little cushion effect so brilliant our terrain is now solid it’s real which is very good so next step let’s make some hills and valleys okay so we’re going to use purlin noise for that so First thing you need to do or i’ve kind of done for you in your project file folder where your main module file is and your mesh terrain file is and your assets folder is and assets has got the terrain dictionary and the block object or the model you need to add this Purlin underscore module file and because the perlin noise module which you can pip install perlin noise um you can go and install that module but for some people it’s not working so anyway to make it easier just download this and put it in your project folder and then things will work and we’re Going to import this in a in a moment right so first after after you’ve got that file in your project folder make a new file and we’re going to write our own class to handle the perlin noise stuff that’s going to be very short class so i’m using visual studio code where i Just need to say that i’m using python and then right let’s save this so this new module we’ll call just purlin so there’s a perlin underscore module which is a separate thing this thing is going to be called just purlin there you go save that so we’re going to write and Now this is going to import that other module so from purlin underscore module i don’t need to do the dot py because python knows we’re going to import from a a python file else you’ll get a an error if you put py on uh from there import and we want to Import another class called purlin noise like that okay right so now we need class and we’ll call our class purlin just a capital p there so our file is called purlin lowercase the class we’ll call capital so we know the difference um that’s a convention a class name just like our mesh terrain It will start with a capital letter just like a cena starts with a capital letter uh in here see app equals capital letters and so on and so forth so back in our purlin file uh we’re going to add so first we need this purlin noise object let’s write this oh no First we need a constructor don’t we deaf underscore underscore init underscore underscore and then this so this keyword or usually in python you’ll see self i i like to use this like other programming languages so that will point to the object that we actually make Which we’ll get used to as we make a few and then we want to say this and we’ll call it our p noise so that’s going to be our purlin noise object which will have a function to create the mountains and things and so that’s going to equal a purlin noise object That’s why we’ve imported that class that object from our purlin underscore module file again that will only work if you’ve got this perlin underscore module file which you can download from the link in description from me put it in there then it will work okay okay right So we’ve done that and actually before that before that we need to add some things so we want to add a seed i’m just going to put my seed number one two three you can change that number as you like and then we need octaves so that’s like how much detail and Difference in the detail you might have on your terrain and we’ll just start with one and then we need the frequency which is how smooth your terrain is so a low number means it’s very jagged if it’s a high number it’ll be nice and smooth So let’s put a fairly high number of 64 and then our amplitude that’s how high or low it can get we’ll put 12. so 12 means it can go up six meters or six units and down six units in terms of a valley or a mountain okay So then we can use those values to change how our purlin noise terrain will appear so we’ll say the seed is this seed number and then i’ll just go into a new line because i’m in brackets in parentheses i should say make that line up so we can all Sleep at night and then i’ll put octaves equals this dot octaves there we go and my bracket right that’s our all of our properties done so now we need a very important function we need to be able to use our purlin object to get a height at a particular position As we generate a block so this is going to be called get height and then remember the first parameter or argument that we need to pass into a class function or a method is for this keyword but then we just need an x and a z um and then we’re going to eventually Return a y so the start of our function we just want to say y equals zero and now we’re going to use our purlin noise so we’ll say um y equals um this dot p noise so that’s our perlin noise object and going to put into square brackets there Um because we’re going to do a little arithmetic here we’re going to write this dot at no we’re going to write x so the x position we passed in divided by this dot frequency comma z divided by this dot frequency there we go so that will look across the the purlin noise function And finally at the very end outside the parentheses you want to multiply that by this dot amplitude so it will return a number less than one or between zero and one and then we want to multiply that up by the the amplitude there or between minus one and one i should say There we go right that should work so we’ve got our purlin noise ready except for all the bugs that might be in there so back to the mesh terrain and in not generate block but in generate terrain instead of y equals a random range we’ll delete that and we’ll almost Delete that we’ll say we want um to get hold of this.perlin that doesn’t exist yet so we need to go make that up here um so let’s do that now so at the top here so we’re in the mesh terrain class and we want we’ll do it underneath our dictionary We’ll say this dot perlin equals and now we can use our our module our class to say well i want a new purlin object now this is red and angry because we haven’t got that imported yet so i’ll just replace this random range which we don’t need anymore We’ll say from perlin so that’s from this file here will import so that’s capital p because we’re importing this class which we’ve just written so now we can use this function get height so go back to my mesh terrain so we’ve imported that so now back where we were Yep this has gone nice and orange that’s working well so we’ve got a purlin object where are we back in generate the terrain we can say y equals this purlin so our object dot get height we just need to pass in there the x and the z Which is going to be x plus k z plus j so x plus k z plus j done right go back to our main module i’ve saved it and then run let’s actually work it won’t work because we’re under half an hour so things will surely go wrong before that it’s loading I should have made the train smaller so it doesn’t take as long oh wow it’s worked we’ve actually got hills and valleys so it doesn’t look it kind of looks in one sense better than minecraft but in another not as good because we’ve not set the blocks at like one unit intervals But it’s all nice and smooth so if you like it like this you can keep it notice how smooth it is so we’ve used 64 for the frequency so if you want a bit more jaggedy put that lower so let’s go and sort some things out Right can i do this in two minutes firstly i’m in the main module let’s just make a sky while we’re here so we’ll change the window color to no pink so we don’t want any red let’s just put 200 red green and then loads of blue still and then we’ll say Indra that’ll be our god of the sky indra equals sky so peta amland has built a default sky object into a cena so you just write capital s for sky object now we’ve got a sky sphere with a texture on but we do want to change its color so we Want the color to equal and we’ll just use the window color which we just made so window dot color there we go so that’ll be a nice blue through there then in the mesh terrain we want this y to be floored like that and then it will floor it to an integer Also what would be really nice to try and do one final thing yeah in generate a block when we generate a block we give it its uvs it’s like texture here at the moment we’re just leaving as a default uh grass block so if i just open up our terrain atlas Our grass block is at the top left so if i scroll to the right we’ve got those if i scroll down we’ve got those so all of these have got an x and a y coordinate but instead of x we say u u and instead Of y we say u v for like vertical so this one is our eight seven this one would be eight no would be um seven seven this one would be six seven so i want something a bit of snow so i want this one so it’s on the same x so it’d be Eight now this one’s eight seven so this one will be one less than that eight six okay so let’s write um if um the height of our block is greater than two then we’ll say uu equals eight and uv equals six right save that go back to main oh It’s 30 minutes maybe i can do it under like 30 seconds oh and i didn’t change the size of our um subset our terrain so it’s very large so take six seconds here we go so what we’re seeing we should see a sky yep we’ve got nice blue sky we should See some nice blocks and we should see biomes essentially by height right let’s just go and fiddle with the purlin noise go back into purlin and let’s just say our octave let’s say we’ve got three of them so we had we should have or maybe should we try four Let’s try four octaves and we should have some more variety in our train by the way fiddle around with the purlin um you’ll notice if you stretch it too much if you don’t have enough frequency then you’ll have some gaps appearing in your terrain oh wow this is looking a bit more varied That’s really nice and we’ve got our snow cap mountains which reminds me of uh christmas it’s almost december here so uh in britain so definitely in a couple of weeks we should make some snow and things like that for a special christmas edition right thank you very much for watching sorry This took a while uh to get out i’ll try and make one very very soon so we can get some infinite terrain and other things happening thank you very much for watching see you next time goodbye Video Information
This video, titled ‘Python Minecraft with Ursina: procedural Perlin Noise terrain and simple biomes – part 2’, was uploaded by Red Hen dev on 2021-11-18 21:27:33. It has garnered 2551 views and 50 likes. The duration of the video is 00:31:54 or 1914 seconds.
We use a dictionary to record block positions so that we can step up and down a solid terrain, use Perlin Noise to create interesting mountain and valley features, and update the sky.
Playlist: https://youtube.com/playlist?list=PLmP1LNMzp97rIbwnGHhjjobHHqWekxy8Y
Code and assets: https://github.com/RedHenDev/ursina_tutorials/tree/main/python_meshCraft_tut_2021
Thanks for watching!