Client-Side Prediction & Packet Loss

Started by
40 comments, last by Heg 11 years, 6 months ago
Hey guys,

I am currently working on my online mode for my Bomberman Clone. I´ve implemented a UDP Layer so far that has some reliability functionality, such as package acknowledgements. I am now implementing the client-side prediction and got a few questions to that.

In all tutorials I´ve read so far, the only things that lets client-side prediction fail are unpredictable events, usually when another player interacts with your player. But what about packet loss? When I move to the right, I can predict the new position pretty easily, but when the command never reaches the server, the new position will be false. Maybe that wouldn´t be such a huge problem, but I´ve got real issues when thinking about planting bombs:

Planting bombs could normally be predicted, since the client knows the rules for planting bombs. You can´t plant bombs when you already planted all of your bombs on the field, or when there is already a bomb at that location. The letter can be a result of the influence of another player, i.e. when someone planted a bomb a tad before you did. This situation would result in the same visual output though, since a bomb is still at the predicted position.

When packets get lost around the bomb planting command, then the prediction would also fail. Maybe the position of the player needed to be corrected, so when he dropped the bomb he actually was at a different location. Another possibility could be that the bomb planted command never reaches the server. I could resend the command, but that would also result in a different bomb location.

Correcting this mistakes could lead to teleporting bombs, which in return could cause trapping yourself. That would be a horrible scenario, since you literally get killed by packet loss. Not predicting bombs on the other hand always results in a bit of unresponsiveness, which is also frustrating. What can I do? Help biggrin.png
Advertisement
My personal approach here would be to just use TCP, timestamp every command and predict everything the way you do. Even with a retransmitted or slightly delayed command here and there, due to the timestamp you will be able to simulate the game "as if" the command reached the server in time. If state updates from the server reach the client to late, so that the prediction is wrong, well, even AAA titles have this problem (the famous shot around the corner lag problem for example). Guess it's unavoidable with today's networking technology.
Hi, thanks for your answer.

I don´t see why TCP would be a better option in this case. My UDP Protocol allows me to detect package loss and the order of my packages by using sequence numbers. This leaves me with the option to resend important data or just ignore less important packages, which were recieved either too late or not at all. What I have in mind here is movement data from other players. If those are missing, they don´t need to be resend, because the client doesn´t care about the old data.

but when the command never reaches the server

You can use a hybrid solution. For player commands (relative seldom, low data volume) you can use TCP to take away the burden of self-implemented reliability and use your UDP stack for the rest.

But I'm not sure if a UDP stack is still necessary for smaller projects nowadays, so Heg has a point here.
you could also use the information from the prediction just to draw the player and wait for the server state packages to draw everything else.
Hm, this tutorial highly stresses that UDP and TCP shouldn´t be used together, since both are using the IP Protocol and therefore are not independend from one another.

Since I already implemented the UDP functionality I could might aswell use it. I could just resend client input that didn´t go through, including a timestamp, so that the server can reproduce the input. That way the server would have to wait for missing input until it can process the client correctly. I think that wouldn´t be too big of a deal, but I am not sure yet.

What do you mean Inferarum? I think you suggest to just draw player positions and let everything else be approved by the server first. In my case that would result in drawing bombs as soon as the server confirms the position, which would result in a slight delay between pushing the button to plant a bomb and the appearence of the bomb. I fear that this would feel to unresponsive though. What do you guys think?
I guess most games have this delay for projectiles emitted by the player
To be honest, it seems that you build a theoretical horrible scenario which is really unlikley to happen, this is just a game not a control program for the mars probe.

When the player places a bomb just display it as placement plan, that is, make it translucent and leave it in this state until you receive the ok from the server. The standard case will take a few ms, even with a packetloss, most players will not recognize the delay. And if an other player just placed a bomb on the same location just one single ms before, remove the translucent marker and play some sound to inform the player about the failed operation.

To be honest, it seems that you build a theoretical horrible scenario which is really unlikley to happen, this is just a game not a control program for the mars probe.

When the player places a bomb just display it as placement plan, that is, make it translucent and leave it in this state until you receive the ok from the server. The standard case will take a few ms, even with a packetloss, most players will not recognize the delay. And if an other player just placed a bomb on the same location just one single ms before, remove the translucent marker and play some sound to inform the player about the failed operation.


lol :D

Yeah you are propably right. I am really creating the worst case scenario, but someone smarter than me once said "what can go wrong, will go wrong". I guess I follow the advice of you two and wait for the response of the server. I´ll test that with different connection speeds and see how it feels. If it feels too unresponsive, I will add some kind of indicator that the command has been registered by the machine.

If it feels too unresponsive, I will add some kind of indicator that the command has been registered by the machine.

You still should send the commands on a reliable channel, your UDP stack fits in here. Just remember the last X send commands + sequence number and the server will send acknowledge messages about the last valid sequence number from time to time (the client can clean up the command queue up to this number). Although the server should send resend-requests when it detects a gap asap.

You can even re-send the same command (unique sequence number) multiple times, using the space left in a UDP for best use and on the server side it doesn't matter at all.

This topic is closed to new replies.

Advertisement