Hey what’s up guys my name is ashana welcome back to another code review the series in which you guys send me your code and i take a look at it the last two episodes we’ve been looking at c sharp code so i thought i would bring it Back to c plus for this episode here today we are going to be looking at a minecraft clone can you believe we still haven’t done this to be completely honest i actually have to go back and check that we haven’t done a minecraft clone yet just because it feels like Something that would have come up by now but i think we were just too busy looking at ray traces that people were sending in speaking of which i have a new ray tracing series the link will be up there if you are interested in learning about ray tracing and how to Actually maybe write some decently performing code i like the stuff we’ve been looking at in this series sorry then definitely check out that series but anyway minecraft so east van horvath probably butchering that name has sent in a minecraft clone in opengl called gl craft very clever dear cherno Please review my project see this is this is how you start a code review email i want to learn how video games work and how to create one so i recreated a very basic version of minecraft i’m isti a 20 years old university student it was a great Experience to create a game from scratch i learned a lot i watched a lot of shouno videos for help in his prayer like how he calls them turner video not your videos i watched a lot of journal videos for help and inspiration i even checked out the hazel 2d source to see how Something should be implemented but i did not copy paste anything i promise i don’t know if this is a reference to like that bloom shader that someone just outright copied and pasted but whatever there are only two types of programmers those who steal other people’s code and Those who lie about it i don’t think a single program is possibly the first programmer in existence has probably gone through their lives without actually just you know stealing stealing a piece of someone’s code just you know under the table while no one notices but anyway it looks like this person has Probably just been you know used it for kind of inspiration and maybe like design guidance or something like that i didn’t create a proper engine for the game because i think that the architecture that i created was sufficient for the game that i had in mind Okay i think from reading this might be a good idea to kind of focus on the architecture of this actual code and talk a little bit about what it’s like to actually architect a game instead of architecting an engine because these days everything is built on game engines Right like most games that come out obviously like they’re not just like one-off kind of let’s open up you know c plus plus and just write a game and the game contains the engine ish it’s not really the engine you just write a game in c plus plus without using some kind Of engine like most games that come out these days are not made from scratch in the sense that they are made using tools that already exist even if that tool was specifically made to make a game so for that reason i’m actually really interested to take a look at this and see How this kind of game has been made because it’s a very different decision when you’re riding an engine and you’re trying to make everything generic and abstract like all of the kind of core components away but then when you’re making a game you can be a a lot more kind of free With like writing specific code instead of generic code which in a lot of cases is really good but also even if you aren’t writing an engine i think that there has to be obviously some kind of balance between like writing opengl code like i don’t know gl draw elements or something in Places where nothing involving the renderer should be there at all right so you can still obviously make the mistake of coupling code and like intertwining code in places that where it shouldn’t be and just because you are actually architecting you know your software well doesn’t necessarily mean that you’re Trying to abstract it into an engine so anyway this will be interesting to take a look at a house there’s a there’s a distinct lack of ambient occlusion here which makes me upset thanks i’ll check it out i love these suggestions all right i’m just skimming through the repository Here link will be in the description below if you guys want to check out this project for yourselves as well building the project how to build in c line we’re not going to be using sant lan how to build it using so okay so cmake will build it using cmake i guess chunks Are hollow on the inside so most of the blocks that are not visible are not sent to the gpu that’s very very important if you’re making a minecraft game otherwise there’s just too much data to render and almost none of it is actually even needed each vertex in a chunk is only Four bytes long to make the game as memory efficient as possible on the gpu side every each of each vertex in a chunk is only four bytes oh okay so i i expect this means that he’s packed the data because like you know if you’re drawing everything and everything is like a one By one meter block you don’t really need like you know to store everything in maximum kind of precision because you know that you’re going to be rendering you know triangles in a certain format and they’re essentially going to be laid out in this kind of voxel grid so a good Example is like traditionally if you have like a 3d model you might want to have like you know three floats xyz representing like a vertex right and so three floats would be 12 bytes and that would just be a single vertex and so if we were in fact drawing like a cube we Would obviously need like eight unique vertex positions and if we factor in like normals we might end up with like 24 different vertices however technically speaking if all we’re drawing is an actual like cube and the whole world is made up of cubes all we really need to know is like the integer Coordinate of that cube which could be encoded in a number of ways it could be local to chunk space as well if you wanted it to be i guess that would mean that you didn’t have to store very large numbers i mean you could literally you could probably get away with making i Mean entertain this idea if you will if it’s local to chunk space and chunks are like 16 by 16 then you really only need like four bits to to encode that chunk coordinate because four bits gets you like zero to 15 and that can be like the Index so four for four so you basically end up going from like 12 bytes to 12 bits worth of data to represent just that one vertex but the vertex like the cube is the cube is such a predictable shape that you don’t really need to like store all of the individual vertices you Could just send that one chord into the gpu and then expand it using like a mesh shader or i mean it doesn’t even have to be that complicated you could just expand it in the vertex shader i suspect that’s what that means so that’s interesting i think we can definitely Take a look at that although i did promise architecture in this video is has to be a finite length unfortunately so we’ll see how far we get okay and libraries use fast noise light for terrain generation okay fast noise yep so it’s just like a purlin slash other noise kind of generation algorithms Packed into there glad for loading open okay so yeah opengl yeah glad glf wglm pretty standard i’m going load png which i haven’t heard of i wonder why you used this instead of just stp image i guess maybe this is a bit lighter because it’s only png or something but Um maybe it’s faster because stp image is not the fastest thing anyway whatever let’s get into the project okay so what i’ve done is i’ve just cloned it using git of course and then just built the project files using cmake and here we go fail to open file default.chelsea great Start but it seems to work let’s take a look at this oh okay i’m gooey um oh okay so escape locks the mouse or i guess brings up the menu and also unlocks it okay cool yeah i mean look this is working and i didn’t even have Any problems getting it to build so that’s nice okay we’ve got the block outline mouse feels very like sensitive um well place to remove blocks seems to work let me just dig a tunnel okay so you can just fly through and yep you can see that none of the back faces Are being rendered and no blocks that are actually not visible right so invisible blocks are not being rendered at all okay i guess this is how we select blocks to play so we can just like there we go we just have to go to this And select it very cool ui very uh very high tech um uh okay are the speed of this well the lighting is kind of interesting because it’s not very smooth it’s just like it’s as if there’s like a few different states of lighting that’s interesting enable physics i like how it’s in quotes Physics yeah i guess it’s a bit not really correct physics or something okay so let’s see if we can okay i’m stuck the physics are beautiful i can’t unfortunately i can’t hold space to jump it’s very annoying it’s so fast i made it very fast Cool i mean yeah it seems to work i’d love to just be able to uh let’s disable physics um it’d be cool if we could like fly faster but i can’t seem to get that to work because i’m interested in like just flying really really fast and seeing like how well the terrain Generator can can keep up with that maybe we’ll anyway i’m gonna try and not turn this into like an optimization series and like explain how i would do this better because that’s whatever all right so digging into the code let’s see what we’ve got so looking at the Projects here so you’ve separated out every sub-module into separate kind of things here which is good i guess um oh wow look pantry is quite big that’s interesting stb image is all kind of in a header file but i feel like all of the codecs are like the size of all This codes this is interesting i’ve never looked at this library before but yeah interesting oh well maybe it is maybe it’s nice and fast though um okay anyway so all these older models are here but i don’t like the fact that this is called main like why is this called main Like he could have at least called this like jailcraft or something but it’s just called main i mean i guess it makes sense in a way it’s kind of it makes it easy for me to find but um yeah i’d probably name it something a bit more sensible and then We’ve got all this stuff here where are like your header files let me just switch to all to this mode oh they’re just here where are all of the header files where are they this is super weird so they’re all here in source they are in fact next To everything well yeah these are going to be all linked because it’s a cmake project which means none of these are probably even relative to yeah so they’re not actually here they’re back at directory inside source but why the header file’s not showing up that’s like super annoying you can’t see The header files here i don’t know man what’s going on what’s going on bro like you need to see a header file alright main.cpp cool let’s let’s start kind of taking a look at all of this architecture okay default.glc so that was probably the save file that it Failed to load in the very beginning when it actually tried to i guess load the save file and it didn’t find it sure so that’s kind of the save path and then we try and load this and then we do application instance to get the app um Okay cool so you’re kind of using like a singleton approach here uh i wouldn’t do this because it doesn’t seem like it’s necessary i also don’t really like the fact that this is just kind of so you’ve made like a static application it’s tight it’s tied to this kind of It’s like a local static thing which means that the first time this runs it will actually instantiate it and like i don’t know i use this for like basically i only use this approach of creating objects for like debug utils that i want to like lazy lazy load or lazy Initialize kind of like this application is such a like important part of your application that like i like why not you know just kind of create it here like the thing is even if you do it this way there’s nothing to stop you from like you know Using this as a singleton still right like you could for example in the constructor just store like you know so in the constructor over here we could have like a static application you know s instance or something which we could initialize to null and then when the constructor Actually gets called the first time then we could set it to like this i hate this clang format thing destroying everything but anyway so you can just set it to like this right and then that way obviously you could return that inside your instance function or whatever I i don’t know i just don’t i just this doesn’t sit well with me and i guess the reason is that i just think that such an important part of your project should it should be clearly defined where it actually gets created because the thing is like again you’re not doing Much in your application so it’s probably okay it’s probably not a huge deal and to be honest you’ll probably hear me say that a lot about all this stuff because i’m just picturing like when obviously when i see like application and this is like the whole application and you run it here right Like i’m kind of in my head i’m comparing it to maybe like a game engine like hazel or something right and so obviously like the application class there is going to be a lot bigger and heavier and more important than your application class which doesn’t even Seem to do much stuff in the constructor however it’s still something that like i would kind of like from a design point of view it would be nice to be able to kind of create it explicitly instead of having this kind of lazy load situation where whoever happens to call instance first It gets created then and also it’s not like it’s not really clear because that’s the other thing right if you if you’re making it this way it’s really not clear at all when the application destructor will get called and when the application gets shut down because this effectively is a static Variable which means during like static shutdown or whatever that’s when it would destroy it which is basically going to be like at the end of the main function right but but in no predictable order now if we quickly compare this to hazel just for reference then you can see that Like in the main function it’s extremely explicit when the app gets created when the app gets run and when the app gets deleted right this is all very very explicit because it’s such a major part that you really want to be clear with like okay it gets created here and i should Initialize everything it gets destroyed here and everything should be shut down so that’s just something that i would have liked to have seen here okay whatever so we create it we set the scene to whatever the safe path is i’m assuming if that doesn’t in fact like if It doesn’t load or anything because it can’t because a safe path isn’t a thing make shed persistence what on earth is this persistence what is this persistence i guess this is supposed to be something that what persists commit chunk and then it stores the chunk persistence what What an interesting class name now one thing that i don’t really like about this okay so from a code style point of view i would rewrite this class pretty much entirely like literally i think it would be faster if i just would show you how i would how i would write it so First of all okay so let’s not change the functionality step one what i would do is i would move this stuff which is implicitly private right we can’t tell it’s private like there’s no private label here because it’s a class which means that if you don’t specify a label It’s private by default i always specify a label though because that just adds readability right so that you can actually see the visibility of your variables and also because to be honest it’s like a bit of a magic thing magic in the sense that like well if you don’t Specify a label then it’s obviously implicitly private just like it would be public if it was a struct but then as soon as you specify a label then obviously everything is is public under this label so it’s kind of like a weird state where if you don’t Do anything if you don’t touch it then it’s going to be private so i don’t really like that so what i would do is i would always add a label but also i would move this and store it down here why because usually when you look at a class And this is probably like the kind of game engine slash like api maybe developer in me saying this but i like to look at a class and see what its api lets me do which obviously is the public contents of that class right so stuff that is private is kind of an Implementation detail you could say because i don’t like to use this class i just need to know what functions i can call basically right or what data it contains if that data is public how it works internally and what it stores and whatever other private functions it might call itself that is Completely meaningless to me because i only care about what i can actually use that’s why i personally like to start a class with the public methods variables whatever you have an explicit constructor up here i noticed that you’ve you’ve been making a lot of constructors explicit like scene i Noticed also had an explicit constructor don’t exactly know why that is i wouldn’t make a constructor explicit unless it was like maybe some kind of math type or something that like i really i mean math type is actually a good example of implicit constructors and why you would Want them right but in general like if there was like a reason to make it explicit meaning that like there was some kind of you know implicit conversion that is common and that was messing something up or it was like i don’t know it’s it’s not very common to Be honest that i’ve had to use explicit but implicit constructors can just simplify code a lot and for those who don’t know what an explicit constructor is it basically means that you can’t implicitly construct this object by simply specifying this type whereas to me like that word specifically means Like there’s a reason that i’ve marked this as explicit because it was raw and it was messing with some other types that i didn’t want to touch or something like that okay then we have commit chunk get chunk so i don’t like the fact that again this destructor it’s down here i Like to neatly have my constructors and destructors all in the same place right all in one place at the beginning constructors obviously construct the object i would have like a copy constructor here if i needed it you know i would have a move constructor here if I needed it all of the constructors are in one place and the destructor follows them let’s move on to some of the other source files abb uh access plan okay so i’m assuming there’s gonna be quite a bit of math stuff there has to be right because obviously you have to well for One you have to place and remove blocks right so there’s a ray class here then we have these axis planes so what on earth is this axis plane playing normal right position right direction access point okay playing normal calculate offset direction so a whole bunch of math here intersect Dot play normal ray direction so this is like kind of like a plane equation i’m assuming that’s why you got the plane plane normal and then this is going to return i guess the distance of intersection on there by the way if this kind of math is confusing to you then Like there’s no reason that it has to be confusing you can just learn all about it if you head over to brilliant those of you don’t know brilliant is an amazing website filled with really really good courses on various stem topics and i particularly love their math courses unlike other course Websites brilliance courses are extremely interactive and engaging they quiz you they ask you questions about certain things to make sure that you’re actually learning stuff they give you like these sliders that you can play with and just heaps of like interactive controls so that you can visualize what You’re learning better and to be honest that’s how i learn best visually and by practice aside from math brilliant also has a lot of really good computer science courses on topics such as data structures and the best thing is that you can get started with brilliant for Free just go to my link in the description below and check out their amazing classes for yourselves and if you like them brilliant have been amazing enough to offer the first 200 subscribers who sign up using my link in the description below 20 off an annual membership huge thank you to brilliant For sponsoring this video alright so taking a look at the ray class what seems to be happening here is that you have a constructor not explicit that’s good which takes in a position a direction and the world and the reach which i’m assuming is like the maximum distance of the ray This is kind of an interesting design and it’s a little bit weird to me because like array in my mind just represents like literally a mathematical like equation right like you’re casting a ray into the world and you’re seeing what it hits to me that’s like a problem to do with Numbers you’re literally doing some calculating whereas what you’re doing is you’re actually passing in the world and so this is extremely specific to this world right so it has to actually i guess use the context of this world to figure out what blocks you can actually hit and and what you’re intersecting with And then you can see that it’s even tied to like certain things like air right so if it if it if it hits the air then obviously that’s not a valid block to hit so we’re not going to set successful to true and all of this stuff this is Actually a really good example of being super specific to suit your needs and in my opinion this is a little bit too far but if you think about it like array class could be like the most generic thing ever right it’s just as i mentioned it’s just a mathematical set Of numbers right and then you can do whatever you want with it maybe you have a ray versus abb collision test and that abb maybe is in world space and so you need to maybe transform it into raised local space or rain to world space or whatever right you do all of that Conversion kind of as you need it however it could be as specific as this where you literally like when you construct a ray it immediately actually does the math in your specific world knowing all about your specific block types now why is this a bad thing well it’s not exactly a Bad thing but the reason why it’s a bit weird is because what happens when for this same game not saying you’re building an engine here but for this same game you want to like open a door maybe you add some kind of like attacking feature and if you’re pointing Like towards a mob or an enemy of some sort you cast out a ray to see if you hit them and that’s going to trigger something like how exactly are you going to you know adapt this red class to deal with all these cases the constructor Here is just going to keep growing it’s also extremely tightly tied to just being used for specific blocks and the class itself just simply can contains like successful and hit target which i guess is like i don’t know if this is the position of the block or the position of the ray hit On the block but then you’ve got obviously blocked data which is like what kind of block it hits and then like neighbor information like this is this is all it’s such a specific use case like at the very least i would just simply construct a ray you know like This but then be like maybe make like a cast function or something and that way you could have like several different functions for specific use cases in your game but like doing it in the constructor like this like it’s it’s too narrow you know it just it just it has one function And that’s it and again as this inevitably grows you would have to refactor it anyway now the other the other thing that i think is important to note here is that when i construct an object i don’t generally like it depends what objective it is if it’s like an application Class instance or like a scene class right maybe i expect that constructor to be somewhat heavy but if it’s like you know array i don’t expect a ray constructor or any math type really to be heavy right because i’m just constructing a little object maybe i can reuse it later so for Example if i want to cast a bunch of rays or i just have like one ray that permanently looks forward where the camera is facing and i can kind of construct that but then i want to repeatedly cast it i guess what i’m getting at is i just wouldn’t expect the Constructor to cast the ray like simple as that the other thing is like again casting like the actual so array mathematically that representation of like having kind of like an origin and direction like that’s all fine but when you start bringing the world into it you Know to me like casting a ray is something that is it’s it’s tied to the world if you think about it isn’t it because if you just have a ray and then you’re trying to cast this ray and then obviously like where are you casting it into like You’re not casting it into the void like you’re you exist within an environment you draw this line within that environment like here we are we’re in a box you know where the player over here and then what do we do we cast this ray so where is this ray being cast this ray Is being cast and potentially hits like a block within this kind of environment right within this box so this box is in fact the world now how you’ve achieved this effectively is by creating this ray and then passing the world into the actual ray class so that you then know like what objects Is exist within that world or what blocks exist within that world so that you can do your kind of collision test now to me this is just such a backwards way of thinking about it because to me a ray just represents this line you know block represents a block you know player Represents a player they all exist within the world so i would put that raycast function in the world class now we can get really deep here honestly i could spend hours talking about like object oriented programming and like what to put into what class but at the End of the day like i think you need to stop thinking of things as classes and start thinking of things as functions it doesn’t even matter really what class it’s in the reason why i would put it into the world is because the world it has that context it owns the blocks in The world the player exists within the world therefore if i mathematically shoot a ray in the world it has all of that necessary context to actually see what the ray hits and where whereas what you’ve done here is you’re basically shoving that context down the ray’s throat because it needs all of This extra data in order to actually figure out what on earth it’s hitting and what block type stuff is and all that stuff this this this actually wouldn’t even be that that much of a tightly kind of coupled function or whatever if it existed inside the world Class so yeah like as far as this goes just think of operations such as these as just like a function try and break down this project in a way just into its mathematical roots of like i have a ray and i need to do a bunch of math on it To see whether or not it hits certain blocks and which blocks and how i can manipulate them and whatever else think of that as a function think about the inputs into that function so in other words stuff like the world the ray anything else and think about your Expected output of the function right think of it literally in the most basic terms possible because at the end of the day what you’re doing is you’re making your cpu execute this kind of function that is going to take some kind of input to crunch some numbers generate an Output that basically says hey this was successful as you were putting it which basically means i hit something and here is the associated data that you might need such as like which block you hit and then once you’ve kind of gone through that in your mind and you know Exactly what you’re doing then you can think about like where does this belong within my code because again like i mean maybe you had a great reason for this i’m just not seeing it and that’s totally fine but to me this just looks like you just you’re just maybe Struggling a little bit with deciding where code kind of should be and i guess like how a good way to dress it up is and to be honest that’s like another huge issue that i notice a lot with people who are both learning programming but also kind of maybe get a little bit Too tight tied down into like the object oriented paradigm and that is the fact that like the name of the class begins to in a way imply certain behaviors and in your in your mind perhaps you’re trying to like assign certain behaviors to certain classes if you stop thinking in That kind of object-oriented way where you have like a class for each of your like i don’t know high-level nouns in your like story that is in your uml diagram and all that absolute rubbish that people say mostly like corporate managers and universities maybe and you start thinking a little Bit more about like the data and what actually needs to be done and try and simplify that as much as possible then i think that you you probably will come up with better ways to sort some of this stuff out now moving on here uh as usual i Think we’re running out of time but let’s just let’s just like click on some random files and see what i can find here okay so the scene class is something that we use to kind of control like the game logic because there’s also a world class so this kind of seems a Little bit confusing to me but i think i kind of get your drift where the world kind of contains like the world generator and i’m assuming all of the actual world data or maybe that’s inside the world generator and let’s just see it and noise sure But um i guess all of the actual so where are the chunks stored uh up here chunks right so you have our map of ivec2 which i guess is an is it just an xy kind of coordinate for that chunk because the chunks kind of are two-dimensional in the sense that like These aren’t blocks these are chunks right and then uh we have a ref to a chunk okay so that’s a heap allocated object there and then we have hashvec2 which is just a particular hash that you use for that on ordered map for your um for your ivec 2 Sure so the world class again is is is the thing that specifically uh stores all of your chunks whereas scene is kind of like your game manager and then from there obviously we call update that updates the player the world all of that kind of stuff i’m just gonna Briefly look through all of this stuff what is going on here bro if key equals 87 or k equals 265 why are you using integers for all this stuff damn this took a turn so you’re using gel of w which actually comes with constants for all these things right so Like gl of w key i don’t know w for example now if for whatever reason maybe you don’t want to include gl of w in here and perhaps that’s why you’re doing this then that’s absolutely not a reason at all because what i would do is i would just take You know all of this stuff copy it basically put it into a header file inside your actual project called like i don’t know key codes and then reference those because this is just wild having comments here for like you know for for just random numbers basically that map To key codes like that’s intense this kind of like threw me off like i don’t know this is this is weird because you know all of your other code just seems so much kind of you know above this level where we’re still doing this stuff now Then what you do okay so you have action action equals one so set is camera moving forward and then we forward dot is moving equals is moving forward is a movement direction which an is an is moving followed by direction oh my goodness what is going on here bro You really need like a camera tutorial or like a movement tutorial or something this is intense you know i always say that before you google something you know if you have the time it’s nice to try and implement it yourself and i mean back when i first started Programming i used to go crazy with i used to just i guess force myself to come up with my own personal implementation and and solution to all of these various problems and some of the solutions i came up with back when i was like in high school and had a few months of Programming experience they were whack they were ridiculous but it was cool because i was able to actually solve the problem myself and yes i did it in a garbage way but i did it myself and i think that’s an important step to learning so if that’s what’s going on Here then cool i’m glad you tried this yourself now let’s talk about why this is weird and what i would do instead so first of all what you probably should do what you are doing actually is you have a bunch of predefined vectors right so this is like the forward Direction which seems to be on the x-axis then we have backwards right which is the negative kind of x-axis and all this stuff you also have boolean states for all of these which again is a little bit weird but i can maybe see why you’re doing this i’m assuming it’s Because you can move say forward and left and up at the same time and so that’s why you kind of have these states here so that you can check to see which way you’re moving but again i don’t know i just don’t know why this is happening Because what you could do is you could just have something like extremely simple here such as like i don’t know my velocity and we could like just initialize that to zero or whatever and then obviously if we move forward then all we have to do is say That like we’re going to move in whatever we decide like a forward direction is which could be like i guess you were using one at the very end if we wanted to make sure that you know we were moving like so let’s say we go left which uh left was Sure on the z axis apparently um if we did something like that then like oh no we’re moving too fast or whatever you could always if you wanted to take this and like normalize it in the end or something make sure it’s universal that way your Speed really is one no matter how many directions you’re holding not that this is a good way to write like an fps camera in general because you would want to probably move in the direction of the rotation of the orientation which i’m assuming you do anyway because obviously That was working but i guess this is just like kind of like where is your intention to move is it forward if so then set that to true whatever but again kind of ridiculous i would just do the calculating actually here and then just like basically be like camera dot set Velocity and again it doesn’t matter if we’re moving up or down or left or right or whatever because we know which way we’re moving we have that kind of mathematical vector instead of this kind of like logic kind of state tree which is kind of what you’ve created here the Other thing is again like just like with these weird numbers code is supposed to be self documenting you want to document the code as much as possible meaning that when you have something like this instead of repeating this this many times action equals one clearly means that the key is pressed so Just make a boolean called key pressed and just set it equal to action equals one we could just rename this to like is pressed or whatever and then that way it’s just like is are we moving is is pressed and i mean you could make it Even less and bigger than that i mean we have ears moving so you could even set this to is moving and then that way obviously we would you know have his moving here instead of action equals one right like what does that mean and i know what it means but i’m just i’m Saying that it could mean so much more if you just simply name this variable just like you should name your key codes or use like the predefined definitions for them now because this is a gaming engine it’s interesting to see like world render for example specifically Using like opengl code like oh that just feels so so weird to me but like again that’s totally fine because this whole like the opengl is basically being used as the render api for this game you know so it’s totally normal to have stuff like this even though You know of course the engine developer inside me wants to abstract this away make it generic make it so that we can implement any render api if we want to maybe put this at least into a renderer class or something so that it’s like we can specifically call stuff like Renderer you know enable blending or whatever if we’re not creating pipelines and specific other things but totally fine now the last thing i kind of want to look at is i guess maybe block vertex or something so because because you mentioned that see this is why it’s weird right you mentioned you Were doing cool like vertex packing stuff and yet you’ve got like this stuff this is why it’s so so interesting to me like it’s just weird okay so i found the shaders for uh drawing the actual blocks and everything and we’ve got default.default.frag here so we’ve got The vertex shader here which is quite quite large and so what it’s doing is it’s actually taking in a single attribute right just one uint a single unit so we have four bytes here and from there you can see that we’re extracting all of the information that We actually need such as the xz position of the block uv coordinates flags all of that stuff by just simply extracting bytes from that vertex data right so you can see like extract byte over here it’s going to basically isolate a specific but add a specific offset this is i Don’t know why you’ve done it this way this is actually kind of funny i would just do like i would just you know move it by the offset first and then just ended by ff and sure ffu unsigned there’s no need to like shift this all The way up mask it out and then shift it back the other way because if you’re shifting something right then the the rightmost stuff that already existed there is going to just drop off anyway but anyway so we’re extracting these specific bytes so again exit position is Just going to be i guess a value between 0 and 255 same with uv coordinates same with flags flags are just containing things like whether or not it’s animated and then we have according to certain flags and some other stuff that we’re extracting so the y position here has Its own so the first kind of byte i guess is the y position then the second byte is the xz position which i’m assuming yeah is stored kind of occupying just four bits so between 0 and 15 for both of those things so that Way we kind of we just do some kind of bit masking and stuff to actually get the real xyz position which we then use as our vertex position which eventually gets multiplied by the model v projection matrix so basically again instead of actually having like layer location called zero blah blah in vec3 You know vertex position and this obviously right would occupy 12 bytes of memory because we have three floats each float is four bytes this whole thing occupies four bytes of memory and it doesn’t just contain enough data for us to actually piece together this vertex position it also contains the uv Coordinates which would be another like eight bytes right because that would be a vector and also any other flags that we might actually use so obviously this is a huge saving i mean just these two together without the flags are 20 bytes of memory whereas this is a five times Reduction because it’s only four bytes so that’s what he was talking about in terms of like just being a little bit smarter with the way that these this kind of vertex data inside the vertex buffer is actually packed so yeah kind of cool now of course you could go a Little bit more advanced like you i mean you ultimately don’t even need a vertex buffer you could just have like some kind of storage buffer and then maybe like that could be written out by by a compute shader which will automatically generate the actual terrain mesh for you You could really expand this obviously but it’s pretty cool obviously seeing something that isn’t just like at your standard like in vec 3 position and then it’s just kind of a waste for a voxel game like this where everything is so simplified ah this is really making me Want to make like my own minecraft clone and then over here in the fragment shader we’re able to like do the same thing kind of with the vertex uv now the vertex uv is actually interesting because the the actual like texture itself obviously this is ultimately like A sprite sheet we have a coordinate of something that we want to access right within that that atlas that texture atlas so we can divide it by 16 because one two three four five six seven eight nine we’ve got 16 of these here and then obviously like the vertex uvs are also Kind of going to be predictable because it’s all just arranged in a grid so everything’s really super easy when you’re dealing with voxels and tiles like this and uh you know this guy’s code has certainly taken advantage of that which is awesome to see so yeah overall a Really cool project i enjoyed looking at it some questionable things and obviously like the architecture i would kind of give a little bit more thought to i didn’t take a look at the performance of this at all and to be honest i’m kind of glad i didn’t not Because i think it’s bad or it’s slow or whatever just because i feel like that’s what that’s what these code reviews inevitably become anyway thank you guys for watching this video if you enjoyed it please don’t forget to hit the like button below if you want me to take a Look at your code in the next episode of this code review series and send it into channelreview gmail.com that email address and some instructions will be in the description below overall a really cool project i enjoyed looking at it some interesting like decisions when it comes to architecture that i think you Could improve but otherwise it was pretty good and the vertex packing stuff you did is is definitely cool as well also don’t forget to take a look at brilliant using the link below and i will see you guys next time goodbye You Video Information
This video, titled ‘Minecraft Clone in C++ // Code Review’, was uploaded by The Cherno on 2022-05-14 11:45:02. It has garnered 234795 views and 6630 likes. The duration of the video is 00:40:29 or 2429 seconds.
Visit https://brilliant.org/TheCherno to get started learning STEM for free, and the first 200 people will get 20% off their annual premium subscription.
Patreon ► https://patreon.com/thecherno Instagram ► https://instagram.com/thecherno Twitter ► https://twitter.com/thecherno Discord ► https://discord.gg/thecherno
Code ► https://github.com/Isti01/glCraft
Send an email to [email protected] with your source code, a brief explanation, and what you need help with/want me to review and you could be in the next episode of my Code Review series! Also let me know if you would like to remain anonymous.
Chapters: —————- 0:00 – What we’re looking at today 6:55 – Playing the game 8:55 – Project structure and initial thoughts 10:30 – Local static singleton 14:10 – How to organize a class (my style) 17:43 – The math 19:22 – Ray casting and how I would change it 23:55 – Designing code structure 28:08 – Other notes 29:23 – Some weirdness and how to write clear code 35:22 – Vertex packing and shaders
This video is sponsored by Brilliant.
#CodeReview