Godot Multiplayer Tutorial - Extrapolation | Godot Dedicated Server #13

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
in this 13th part of the multiplayer series let's hope it doesn't bring bad luck we're gonna have a look at extrapolation when you don't have a future state to interpolate to in the last episode we had a look at interpolation and how by rendering a hundred milliseconds in the past we get both a past and future world state between which we can interplay and smooth out the movement in our multiplayer games now this assumes that the internet is on our side but the internet doesn't always abide by our will and there can be situations a hanging connection or several packets lost in a row in which case you actually don't have a future world state even though you were rendering in the past that situation looks a little bit like this we rendered 100 milliseconds in the past indicated by the green we need to render the world at 10 185 but we've only received world packets up to 10 15 only the packets in the past now interpolation doesn't work anymore at this point because we don't have a future world state what we can do is extrapolation and that's what this tutorial is about with extrapolation we take the two latest world states which of course are both going to be in the past these two world states contain enough data for us to calculate both the rotation and speed of every single entity that are in those world states npcs mobs players you name it now with that speed and rotation we can then compare the time between those two world states with the time between the render time and the latest world state to do an estimated calculation where all those entities are going to end up if they kept moving in the same direction now of course that's a big assumption right there that everything keeps moving in the same direction and of course we're going to create small deviations if players mobs or npcs made turns during those couple of milliseconds however as future world states are gonna keep coming in from the server we are slowly adjusting all those movements and as soon as we have a future packet again we immediately fix everything and we're back on track this way the movement keeps smooth and the player doesn't experience the lag spike that he would otherwise experience now with that said let's code it into the game there's only a couple of small changes that we have to make and add a couple of lines so this will be short tutorial and you'll be back working on your project in no time the first line i want you to focus on this line right here it's actually not code this is the expected outcome of the world state buffer before we start interpolating i've shown you this in the previous tutorial on interpolation so we have these two lines right here and these two lines make sure that the world state buffer which collects all the world states that the player receives is going to have the same format so that when we are interpolating all these uh buffer references are always going to be the correct states that we need to be referencing in order for that movement to stay smooth now as i've shown you in the previous tutorial the outcome or the expected outcome is past world state future we'll say future further in the future world states however i've just shown you that for extrapolation what we're coding in this tutorial we need two past real states and the current code doesn't allow or accommodate that so we need to change the um the code the existing code of the interpolation functions to account for also a past past world state so with that deleted you understand the concept of the changes that we're going to be making actually i've already made i'll go over what those changes exactly are they start on line 34. before we were referring referencing index number one in the world state buffer because that would be the second index in the array and we wanted the second index to be the future world state but now we want the third index to be the future world state so i've upgraded this from a 1 to a 2. that also means that in all the rest of the code we have to make sure that we up all the world state index references up by one so this used to be zero this used to be a one this used to be a one and this used to be a zero used to be a zero it used to be a one used to be a one so you have to upgrade all those index references with one to make sure that the interpolation function still works the same even though we have an extra pass world state in the world state buffer now with that said we have an extra line of code here on line number 36 and that is a new line of code we're going to be checking on top of the code from the previous tutorial if the world state buffer size is bigger than 2 because if it's bigger than 2 that must have meant that the render time was not bigger than we'll say buffer 2 because this delete has not triggered so if we have more than 2 in the world state buffer it means we have free if we have free it means we have a future world state if we have a future world state we want to be interpolated however if we are not having more than two so we have two or less that is the moment that we can determine whether we need to extrapolate or not there's only going to be one situation in which we do not want to extrapolate and that is is the render time is bigger than the world state buffer timestamp on array index number one this is the case when a player logs in for the first time the first world states are received those are all future world states but the buffer is not big enough for us to start trimming because we don't simply hit the well we'll say buffer sizes bigger than two yet so to make sure that we're not going to be extrapolating future world state which we shouldn't be extrapolating at all we are going to make sure that the render time is bigger than the world state buffer one timestamp and only then we know that we have two uh past world states loaded into the buffer and apparently not a third world state in the future because otherwise this line of code would hit so now that we know that we need to extrapolate code looks pretty similar to the interpolation part we again have an interpolation factor and an extrapolation factor we are going to go over all the players in which we do a couple of checks to make sure that we don't have to exclude anything exactly the same as here we again make sure that that node is available among the nodes on the map so that that player is already known we define a new position and we push that towards the player which we do right here the only difference is that the extrapolation factor is a slightly different calculation and we also have this position delta right here that we need to calculate because we cannot learn because we don't have enough data to learn so let's start with the differences we start with the extrapolation factor the extrapolation factor is exactly the same function as the interpolation factor the only difference is that we deduct one at the end we do that because we do not want to include the time that has passed between both past world states as that time has already been accounted for then what we also do with the position delta is we take the position of the pass world state and we deduct it with the position in the past past world state then the new position is going to be the latest known position that we know is is true which will be the player position in world state number one that is the most recent past and then we add the position delta multiplied by the extrapolation factor and push that to the move player now regretfully i cannot demonstrate to you how this works in this project because i cannot determine when a packet is lost that's what the internet decides i can however show you in a separate script how this function works so you can better conceptualize it understand it and understand how your own game is going to work after i've done that demonstration i'll also fix the new spawn new player function we got right here as that has basically broken since we are now buffering or buffering yeah buffering and rendering 100 milliseconds in the past so let's first really quickly go over that other script here i have two states or two dummy states and a future render time so we have two positions of a past past world state and the past world state the two time stems that accompany those two states and we have a render time 25 milliseconds further in the future than the latest world state that we have received here we have that extrapolation factor position delta and new position exactly the same variable names as you just saw on the real project on the code here also we're putting that minus one in here so if i play this you can see how this is actually going to work for us now zoom in a little bit i can just close this i'll zoom in a little bit on the bottom there so the extrapolation factor is basically expected to be 0.5 as it shows there because we have 25 milliseconds since the latest world state but the time between the two layer world states of the past are 50 milliseconds so that means that whatever delta happened between those two timestamps we have to multiply it by 0.5 in order to get the right position so that's how you see that extrapolation factor work and the position delta is of course going to be a vector 50 by 50. that's not really magic the new position is the all positions that will be 150 by 150 with the difference in position multiplied by that extrapolation factor which of course would become a vector 0 25 by 25. now add the two together and now the player is going to be rendered at 175 175 exactly where we would expect him to be if he were keep moving with the same speed in the same direction so that's how that works let's quickly go back to the spawn new player make sure that is fixed there's one line of code and i'll leave you to it so we're back on the project to fix that spawn player or despawn player i should say the problem we're having with the current code is this line right here what happens is because we are rendering 100 milliseconds in the past the moment a disconnecting player is signaled to the other players to despawn that player among the other players that are still in the game the interpolation function hasn't finished processing all future world states some of which will still contain a player state of that player that has just disconnected and because of that the code is simply going to recognize hey i don't have that player so he must be new that's how the code interprets it and he spawns a new player even though that is actually a disconnected player so you see the player disappear for a couple of milliseconds and then reappear again that's of course not what we want so quick fix for this is simply in the despawn function we got on the top here to yield for 200 milliseconds that way all the future states that still have to be processed that that player might still be in are all in the past we don't have those anymore and the function can continue as normal player states despawned now i would suggest this method only for crashed players for normal logging off players what i would advise as with most mmo rpgs that you implement a 5 or 10 second timer if the player moves or does any action during the timer the disconnecting timer automatically stops again and while that timer is running to turn off the physics process engine for that player so it doesn't continue to send any packets anymore and as it's not sending any packets when that player has graciously logged off there's no future player states um that the other players still have to process so that respawn doesn't happen either that would be the let's say the clean the right way to disconnect a player i'm not going to demonstrate to you as i don't have a whole game menu and all the other stuff but something that's pretty easy to implement and you can keep this line of code for crash players that was it for today guys hope you like it if you did smash that like button hit subscribe don't forget that little bell icon to make sure that you don't miss out on the next tutorial in this multiplayer series now pretty much we have all our movements now coded into the server and the client and i think the next big challenge for our multiplayer series is how we can make sure that things entities npcs and mobs don't live client-side but actually live server-side i've shown you demonstrated to you in a previous tutorial that the both players that we are connecting can still independently from each other kill the wear there that's on the map but of course if one player kills it we wanted to see that as well for the other player and the damage that one player does should also count for the health bar that the other player sees on that where there to make sure that you know things are multiplayer and not sort of weird dimensional single player while you see each other so that's pretty much going to be up for the next couple of tutorials probably have to spend two or three on that and i think that is going to be becoming pretty close to concluding this entire series so pretty excited to finish this all up i hope you are too see in the next tutorial until then keep on gaming keep on coding see you later guys
Info
Channel: Game Development Center
Views: 3,231
Rating: undefined out of 5
Keywords: Godot Syncing Players, Godot Multiplayer Syncing Players, Godot Multiplayer Players Move, Godot Multiplayer Moving Players, Godot Multiplayer Tutorial, Godot Multiplayer Syncing, Godot Multiplayer Extrapolation, Godot Extrapolation, Godot Network, Godot Networking, Godot Dedicated Server, Godot Multiplayer Server, How to make a multiplayer game, Godot MMO, Godot Beginner Tutorial, Godot 2d Tutorial, Godot Tutorial, Godot
Id: XGyrKmOxLcc
Channel Id: undefined
Length: 13min 1sec (781 seconds)
Published: Sun Dec 13 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.