How to make a Multiplayer Game in Godot

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

Great tutorial, and it's just what I needed. Thank you very much sir!

👍︎︎ 2 👤︎︎ u/Nanox19435 📅︎︎ Sep 28 2020 🗫︎ replies
Captions
hello disciples of thought do you want to create a sophisticated multiplayer online game no fear not there's no use for unreal or unity when this marvelous perfection exists from registering to logging in to searching a match we will see the real deal in one episode i won't waste your time any further inject coffee directly into your bloodstream and enjoy the galaxy brain insanity that is network programming in this project i created simple 2d rpg controls to fight someone in this arena i can walk and shoot high quality aaa games the flow of the application starts with a permanent connection then the user will register or log in then queue up for a match and once another player has been found a game instance will be started both the client and the server simulate the physics world while the server takes care of critically exploitable stuff like shooting killing and collecting items a lot of tutorials show the most naive approach of synchronizing movement where a variable just gets set across all connections then they lurp it and call it a day but it isn't so easy when a packet gets lost and the user runs around a corner you have a big problem the approach i'm showing is far from good but it will at least get you started at getting a broader understanding of what's supposed to happen since packets might get lost you have to interpolate between the values so the player doesn't spam your forums and will keep paying for those sweet sweet fifa coins consider the following your client spams packets 60 times a second and your server processes everything 20 times a second the server takes the position updates and stores the latest ones before it packs a snapshot of the entire world state and its entities this snapshot is then sent to all connected clients but some people have great internet connections where some packets choose the wrong path in life to prevent players from role playing deal we have to interpolate between the snapshots we have on this timeline you can see the snapshots in 50 millisecond intervals coming from the server the client time is way ahead of the latest snapshot and to prevent this we offset it by about 100 milliseconds to have a client rendering time you can see that the point is now between the oldest and second oldest snapshot that means we interpolate between those two positions using the current time we are at when this is implemented you can see that the user is moving around if i introduce latency you can see the delay if i introduce packet loss you can see a slight choppiness for the sake of smoothing it out i interpolate even stronger and show you how little you notice from the other user's network delays but what happens when you lose a lot of packets and can't interpolate any further that's where you either stand still or extrapolate to the next position you predict from the last position delta time and velocity you can't predict if a player makes sudden turns but as soon as a new snapshot arrives you will reset every position anyway every other command will take place as a reliable remote procedure call you might ask yourself what if my player starts shooting and hits someone with that 100 milliseconds delay of rendering wouldn't a high ping cause even further delays well that is true the server will do something called lag compensation the server keeps track of the world state with a snapshot history then it will revert the physics world back in time to this state and will check if you were able to hit the enemy at that time frame if the server agrees it will notify every client and they will see a delayed hit in games like counter-strike and call of duty the strength of this process can cause dying around a corner or dying to shots that look like they came after you shot but on the server the other client was shooting before you besides that if you want to distrust the client even further the server will only receive input instead of positions and will simulate the movements in its view at the physics world your client will still have the regular input and client side prediction but if the server disagrees with your client's position you will experience rubber banding which is the correction of the client's position to that of the simulated client on the server let's get our hands dirty really quick so you know what the code behind looks like the project is organized in assets scenes auto loads services and types in debug and testing i have built a script that i launched with a second parameter that tells it to spawn two instances of godot including a third instance which will be the server this approach makes everything quicker and easier i can highly recommend it autoloads and services are single globally accessible instances that have the advantage of being always on top in the tree hierarchy with them nothing can go wrong plus you offend a lot of people who hate singletons so that makes it even better beginners are usually confused that the note not found error messages or they access control errors when a scene is loading too slowly on one client with this approach you have direct influence when you can't find a node you can even choose to create it on the fly as you detect it's missing within every service there are types which hold variables and do actions that don't belong in services writing a user profile to the disk or holding lobby information and spawning the game instance are examples of that the first thing we look at is the network manager this one runs first and connects us to the online services nothing else happens on that layer if we get disconnected the network manager runs a loop and tries to reconnect in an interval i have also built a nice little notification system where you can push messages in a queue and they get displayed so the user knows what the hell your spaghetti code does next up is the auth service a user will send name and password during login or registration and will then receive a token for an auto login next time the user launches the game the service keeps track of who is logged in to prevent hitting the disk every time users who haven't been connected in over 30 seconds will be saved to the disk and then be removed from this dictionary a very important detail is hashing the password if you hash it one way nobody not even you know what the password is but the algorithm will produce the same character sequence that you can compare with it for authorization i keep the lobby service as simple as possible to get the message across this one waits for players to be in a queue and then the service will put them into a game instance you can build a more complex lobby system that supports groups per lobby properties and small scale user management by extending the lobby class and syncing every ui action or you cannot do that now to the fun part with a small inheritance chain i introduced unnecessary layers of complexity that contribute absolutely nothing to the project but confuse the hell out of everyone where either the client or server provide logic for the programmer to make use of instantiating destroying or synchronizing variables happens centralized and every data point is being recorded and stored this has to be done because a new user could connect and would then need the entire world state including dynamic variables keeping track of that produces a lot of bugs so this is convenient it also allows you to go back in time if you plan to add a timestamp to understand why your code fails in general the client only executes what the server is broadcasting so here's the most important part for the snapshots what you see is the client-side prediction of all entities within a snapshot if we have a snapshot we discard the old ones that are over 150 milliseconds behind then we loop over every entity calculate the target rendering time and finally but with the actual object in the world that's it you can interpolate a lot of disgusting things with this method usually when you have a big world you divide it into chunks you keep track of chunks the user has loaded and then partitioned the snapshots according to these chunks however you can also create individual snapshots for each client to save more bandwidth i often ask myself how battle royale games handle the amount of players when you scope in they're even visible across kilometers anyway on the highest layer i implement the gameplay logic this starts with a ready call which will spawn the player the server gives the new user the track changes to replicate the instantiation call will execute on every connected client by default inside the player script i move around and then feed that information to an animation tree don't you ever skip the animation tree the animation tree is super simple inside the blend space i keyframed all four directions with animations the time scale note will make the animation run faster or slower depending on my movement speed finally these few lines will synchronize anything i want to interpolate when i want to shoot i reliably inform the server the server will then spawn a bullet across all connected clients the bullet itself will always override its current position inside the latest server side snapshot once the hit is registered damage will be dealt the bullet will be destroyed and the player might die if one user has died two times the game will end and i return back into the main menu you might ask yourself how can i instantiate so many game instances inside the tree without getting interferences with the physics in between for that i use a separate scene where the root node is a viewport with its own simulated physics world when you export your game you deploy it to a server with a script open the necessary ports and run it as a service now that we have inspected the code behind i want to show you other networking models the one i implemented is the dedicated server where most cheating is almost impossible besides client-side wallhacks and aimbots some games use a networking technique that is falsely called peer-to-peer by many people peer-to-peer means every peer connects to every other peer what they mean is called listen server where one client is hosting the instance on their private network that others connect to it is like a dedicated server but the host as a client can cheat and have an unstable connection that means flawless playing is a matter of luck but it is very cheap for the developer and a viable solution for casual games the host can also just drop out and cause a host migration where the new host will be chosen real peer-to-peer is a massive nightmare you saw how much stuff is happening when you just want to synchronize a client with a server and then make sense of everything server side in peer-to-peer there is no host or server each client spams packets to the other clients or worse there's some complex routing happening technically each pier has to wait for the snapshot of all other peers before the next few frames can be rendered lag free although this sounds terrible it can be used for slow turn based card games where the good part is that every peer checks if nobody is cheating but even that makes little sense just use a listen server instead that's all i hope you learned something and had a fun time watching this
Info
Channel: NovemberDev
Views: 7,729
Rating: undefined out of 5
Keywords: Unity, Godot, GameDev, Unreal, Multiplayer, Gamedevelopment, Networking
Id: Gx--b6kbZfs
Channel Id: undefined
Length: 11min 2sec (662 seconds)
Published: Sun Sep 27 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.