Let's Code A Multiplayer Voxel Game in C++ - The Engine

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
the last time I tried me think voxer game-related was just over two years ago when I tried to make minecraft in one week but all that project really was was a wall generator where you were able to place and remove blocks you know there was no actual gameplay so I've been wanting to just revisit this project so I could actually implement these things that I've always wanted to add to it for example mod support actual gameplay and most importantly of all multiplayer some of these things I haven't really done much worth before so a four might be interesting to sort of take you along with me as I try to build a voxel game from the ground up and the entire things can be open-source and get hot so feel free to take a look all contrary if you want to so anyways let's make a voxel game start with literally an empty window the first thing I wanted to do was to get something drawn onto it and to do this I'm using OpenGL an API that allows your program to interactive the GPU how this works just to get something drawing is first of all you have to define the vertex coordinates of some shape such as this rectangle here and install these coordinates into an array and then using a bunch of opengl functions you can then send this data to the GPU and once it's there using some more cost to OpenGL you can finally draw the what's gonna be drawn is just a shaper those exact coordinates and there's nothing that can be done with this like you can't move it around or anything in order to do this a thing called shaders can be used these are just little programs written in something called the OpenGL shading language and around each time you draw something using OpenGL in the most basic of cases these are split into two parts vertex shaders and fragment shaders the vertex shader is what is used to apply transformations to every single believer not a vertex of a scene for example translation and rotation and after this the fragment shader is run which goes into pixels in between the vertices using either a color or texture for example here I'm using the vertex shader to move the rectangle to the left and then I'm using the fragment shader to color it in this might seem weirdly primitive but drawing something and applying a shader to it is actually all that is needed to implement a first-person camera view the first step of doing this is taking the current 2d rendering we have and instead making it so that a renders in 3d this is done in the vertex shader where you take the position of the player and also the positions of an object's vertices in the world and do some weird matrix maps to map them between different coordinate systems eventually the objects in question will have its vertices map from the 3d world positions to the 2d coordinates of your screen making it appear 3d the next step is taking player Rampur and making it so it changes where the world is being rendered from for mouse input it means reading the position of it within the window each frame and then rotating the camera accordingly this can be seen working with the code here with keyboard input a yes a little bit more interesting let's just say this is a top-down perspective of the world and the player is pressing W to move forwards as the world is in 3d there is a possible x y&z plane for the player to move and so in its calculate how much they move in each direction this can be done using trigonometry where the players movement vector can be visualized using this triangle using the players Y vertiginous theta the width and height of this triangle can be calculated using the trigonometric equations after applying them the trade was width is how much the player should prove in the x-direction and the trunk was height is how much the player should move in the same direction and adding these numbers to the players position makes them go forwards with the first person camera done I felt was a good time to implement basic networking and multiplayer support this is done using sockets which endpoints for sending and receiving messages over some networks such as the Internet so the first step of adding multiplayer is making it so the client is able to actually connect the server on the client side this means creating packet and mark me as a connection request and then sending that over to the server the server will then check this here there's any rooms this climb and if there is then some basic information about them is stored into an array such as their IP address in response the server will send back to the client the array index of where the information is stored or which is considered the client ID this client ID can be used for future messages from this client the server which will tell the server who sent the message for example if the client wishes to disconnect it you can create a packet market as a disconnect request and then add the client ID to it when the server receives a packet it can look at the client ID and then remove the corresponding information about that clone from the array which then freeze it for future connections this could be seen working here when I run the server and the clients you can see it can all turns up the messages are being passed between them like the connection requests and other players joining and leaving the game the only downside this current system is that there's no authorization and so it's incredibly insecure for example there's nothing stopping client 1 sending a disconnect request saying that is actually client 2 because there's no way to tell which client this message came from but for now I just want something that works and so authentic eating these messages is a task for another time anyways the next step of adding multiplayer is making it so players are able to see the other players are smoothing around to do this I can store a list of positions on both the server and the client corresponding to the positions of entities in the world which includes flares so them every frame of the game each client can send their player position to the server along with the client ID the server can use the client ID as an index of the entity array setting its new position this array index of the entity array can be considered the entity's ID number so if every tick of the server for each entity it can broadcast the entity ID along with its position to every client finally using the entity IDs with its positions the clients can update their own entity array to be synchronized with these servers entity array with this implement hood each client now knows the positions of all the other players in the world and so you can render something out these physicians and watch them as they move around in other words the game now has basic multiplayer support at this point we now have the ability to render stuff control a first-person camera and also send messages between the client and the server over a network so now it's time to implement probably the most important part of any blocky building game and that is the actual Foxley world itself for now this just means solving a couple of problems first of all we need some way to actually store the data for about the port in memory and in secondly there needs to be a way to actually renderer and while doing both these things also needs to be very efficient to update for example when the player breaks or places blocks they should do this straightaway before any delay as this would be a poor gameplay experience these problems can be solved by splitting the world into chunks me they're often stirring the bulldozer in one massive array or something the power is stored in much smaller sections in our case this will be a fake CQB area of blocks but what is blocked in terms of how it's stored for now in our case this will be a one byte number where a number corresponds to a block title for example zero could be air one could be grass and two could be a dirt block by doing it this way it means that each chunk strung their own array of blocks is around 30 kilobytes in size meaning that we can straw a lot of them without taking up too much memory so that's how the store blocks but how did we draw them the obvious but silly approach will be to loop through all the block positions in the chunk move a cube to that position and then draw every single block individually although this works it would be very inefficient as it would mean doing over 30,000 juror calls pair chunk on top of this as you can see most blocks being rendered would actually be inside to the chunk meaning the player wouldn't see them anyway there is a much better way though and that's a generate a single mesh of blocks per chunk adding area the block phrases are actually exposed to it not only would this mean just one draw cool head chunk but also a lot less to render as the block faces inside of the chunk would not get drawn like they were before - Jarrett this mesh given a chunk you look at every single block in it and then for each one you look at its neighboring blocks if the neighboring block is transparent like an air block or a water block then you add those vertex coordinates for that block face to an array for example take these four blocks er as you can see some fabric faces which type cloud and red are neighbouring other sort of blocks and so these faces would not gathered into the mesh on the other hand the other block faces which are colored and blue are actually exposed as in not facing any solid blocks meaning these faces would actually get added into the final finish and what you're left with is sort of a shell around the chunk which can then be rendered the problem of this approach is that it can very pretty slow to generate this geometry which is one of the main reasons that the world is split the chunks as generation this measure in the entire world were taken very long time but doing it for just a single chunk is much quicker although this approach works perfectly fine for most cases is actually very far from optimal while the number of draw calls is very small the amount of croisé being rendered pared roll-call is very high with algorithms like greedy measures this could be very much improved but for now it's working fine so there's no need for that kind of thing just yet anyways right now all of this world stuff is being done entirely on the client-side but the end goal of this project is to have a multiplayer boxer game this means that the world should be created and updated on the server sending chunk data to the currently connected clients which would allow the players to see and modify the same world as networking is pretty new to me I wasn't a hunch percent sure how to approach this so I wanted something that just about works for now and that is the server stores a map of chunks and clients sent across the server asking for chunks at certain positions the server will then generate some terrain for that chunk if it doesn't exist yet and then send it over to them this would allow the client to generate mesh data for the chunk and then render it and while doing this also needs to be reliable because if a client doesn't receive the world data for a so impatient then they you cannot render anything there and so there's going to be holes in the world to get around this I'm using a library hood ena for networking which allows for reliable UDP sockets meaning that once the server sends data you can be pretty sure that the client actually perceives it and so hopefully they're going to be no hollows little chunk arizo ever so anyways after all this class able to receive the same wall data and play around in the same world and so I'm pretty happy with this prototype multiplayer voxel game engine thing but there's still a long way to go in the lot to do such as being able to actually break in place blocks but that's going to be a job for the next episode also as mentioned at the start of the video the entire thing is open source on github so for free to look at the code deliver and contribute to the project if you want to but before you finish quick shout out my current patrons so thank you killer crazy man Nick Brown Hayden Dan twitchit Tim if you Givens benjamin mark a dirt timur Schroeder alan fernandez michael Kurush lucas dan berger and neil Blakeley Mona thank you all for the support so anyways once again thank you for watching and I'll see you all next time
Info
Channel: Hopson
Views: 182,504
Rating: undefined out of 5
Keywords: Unity, Unreal, Engine, MineCraft, How, To, Tutorial, C++, SFML, Programming, Game, Dev, Sky, does, minecraft, pewdiepie, Multithreaded, tut, how, to, make, games, android, ios, apple, lwjgl, java, C#, rust, language, do, learn, program, game, for
Id: 4Rg1RriQZ9Q
Channel Id: undefined
Length: 10min 46sec (646 seconds)
Published: Fri Dec 20 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.