Sign in to follow this  

Friends living abroad have really laggy connection to me, why?(using raknet, udp)

This topic is 481 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Guys, as I told you probably 100 times by now. I'm making a multiplayer paintball game.

 

I've just finished with setting up the sending of my position and rotation to all other connected clients and I tested it on my PC( I've loaded both a server and a client on my PC ) and when I move forward in the server app, the same forward movement is made on the client app, cool. Everything works perfectly fine.

 

But when I send the client version of my game to a friend of mine who is in another country, he says that my movement is very laggy, and the game is not playable. I'm wondering why the packets are sent so slowly. I'm using RakNet and RakPeerInterface class which is based on UDP, so it's not a TCP problem and I don't know what to do.

 

2nd bonus question:

 

Ok, TCP guarantees the arrival of every packet and while this is good for some applications, it causes slowdown in games, because if one packet is dropped, the router waits for the same packet to be resent and this messes things up, OK.

 

But then in this link here:http://www.raknet.net/raknet/manual/introduction.html     There is this sentence:

"At the lowest level, RakNet's peer to peer class, RakPeerInterface provides a layer over UDP packets that handle these problems transparently, allowing the programmer to focus on the game rather than worrying about the engine."

 

So actually RakNet provides a layer over UDP packets that provides the functions a normal TCP would have. Everything is messed up in my head because of this.

 

Why would someone use UDP and write code to add TCP functionality ( right order, reliable packets ) instead of just using TCP. Of course there should be a very logical reason, and I know I'm missing something. Do you have any suggestions why this may be?  

Edited by codeBoggs

Share this post


Link to post
Share on other sites

Guys, I think I know what the problem is. My game runs on 500 fps when only 2 players are joined( I don't have a map or some graphics or anything, just two running models, 1 for server, 1 for client ). What I do is send my coordinates every frame. So this actually sends my coordinates 500 times every second, so this is really not a good idea to do networking. There must be some other way.

 

EDIT: I could try aggregating the movement, so it could be send with 10 packets per second only. Or I could make some kind of state machine based on inputs. What do you think?

Edited by codeBoggs

Share this post


Link to post
Share on other sites

There are several issues at play here.

 

Firstly, you shouldn't really be running at 500FPS simulation framerate. That's absurd! Most games with any physics will ask for at most 60FPS. You should lock your simulation frequency to something like 60Hz, and render separately to that timestep.

 

Secondly, you can't hope to send data every tick. You'll flood the connection. Running at a reduced transmission rate, and keeping packets small reduces the liklihood of this happening.

 

Thirdly, the speed at which information can travel between two end points is finite and non-zero. At best, it's the speed of light distance, realistically though the path between two nodes is not a geometric minimum, and isn't entirely vacuum (instead copper + fibre). In short, there will be latency, and it's calculable for a ballpark figure.

 

The clients do not need "new" state for each sim tick. You can interpolate between recent states, or extrapolate the latest state to smooth the timestep between two simulation states from the server.

Edited by Angus Hollands

Share this post


Link to post
Share on other sites

Why would someone use UDP and write code to add TCP functionality ( right order, reliable packets ) instead of just using TCP. Of course there should be a very logical reason, and I know I'm missing something. Do you have any suggestions why this may be?  

 

TCP provides multiple features that are useful in different scenarios that aren't all useful to real-time software like games, and can be slower than UDP because of that.

 

Thus, games often take UDP and add ontop of it only the requirements they need. Even in a single game, not every packet needs the same garuntees. In the same game, some packets might need reliability. Others might need correct ordering. Some packets might need both, some might not need either.

 

If you continue reading that same paragraph, you'll see:

RakNet can automatically resend packets that did not arrive.
RakNet can automatically order or sequence packets that arrived out of order, and does so efficiently.
 

"Can" implies that it's optional.  :wink:

 

If you keep reading slightly further, it says:

 

RakNet does not incur overhead for features you do not use.

 

...which is the difference between TCP - where it costs you, regardless of whether you want that feature or not.  :)

 

TCP is great for many purposes, just not real-time applications with large numbers of packets going back and forth.

Share this post


Link to post
Share on other sites

Guys, thanks a lot for the helpful answers. I think I got it.

 

I want to add that, from what I've read, dropped TCP packets are just waited for at the router to be resent again.

 

In UDP, instead of waiting for a dropped packet to be resent again, you can just make 100 copies of the same packet and send them all in case some of them are dropped. You kind of flood the network a little bit, but it's faster than the TCP way of handling dropped packets, which is what is needed in FPS games.

 

So from what I gather, UDP is just a very little layer on top of IP and you have more flexibility to add your own functionality, and TCP is a fat protocol that does almost all the stuff for you, which saves you work, but it's not good for realtime apps. Right?

 

And second:

 

Guys, you forgot to answer my first question, which I underestimated because I actually have to choose a proper network model for my game in order to solve the problem with synchronizing the game between players and I got in deep waters here.  As far as I know, multiplayer strategy games send input because commanding large forces actually changes a lot of positions and rotations and if you try to send coordinates for every unit, it's too much packets, better just send input and process it on the other PC.

 

But I have a FPS game, I just have position, rotation, health, and current weapon, this is all the info that needs to be sent. It's really not much if I manage to do it properly.

 

But I want to go step by step here, the first thing is to find a way to send the position and rotation with the best approximation.

 

What is the method used in current FPS games and what is the easiest method a beginner like me should start with? What do you think?

 

I wanted to make a mmorpg, but I can't even send a stupid position for a basic FPS. -_-

Edited by codeBoggs

Share this post


Link to post
Share on other sites

In UDP, instead of waiting for a dropped packet to be resent again, you can just make 100 copies of the same packet and send them all in case some of them are dropped. You kind of flood the network a little bit, but it's faster than the TCP way of handling dropped packets, which is what is needed in FPS games.

 

That's a bad idea. First, you would increase the bandwidth by two orders of magnitudes, which is not just a little bit. Second, today the majority of packet drops are caused by congestion, meaning that not just one but many packets are dropped, so if you send many at the same time you still risk losing them all.

 

Back to the original question, your solution is to not only send position but also velocity (and possibly acceleration, depending on the game), as well as a timestamp. On the other end you will then be able to calculate the expected position at any time from the last known values of these parameters. You can improve this further by using various techniques for interpolation and clock synchronization.

Share this post


Link to post
Share on other sites

But when I send the client version of my game to a friend of mine who is in another country, he says that my movement is very laggy, and the game is not playable. I'm wondering why the packets are sent so slowly. I'm using RakNet and RakPeerInterface class which is based on UDP, so it's not a TCP problem and I don't know what to do.

 

Just to add, latency is generated by multiple factors, like distance between you and your friend, routing, quality of network cables etc. Sure, you can control what to re-send when using UDP, but games often requires some of the messages transferred reliable as well, so you need to implement TCP-like features on top of that - which means more latency.

 

 

What is the method used in current FPS games and what is the easiest method a beginner like me should start with? What do you think?

 

I wanted to make a mmorpg, but I can't even send a stupid position for a basic FPS. -_-

 

I would argue that MMORPG (because of scalability requirements) and FPS (because of strict latency requirements < 100ms) are two most difficult game genres to implement. So if you want to make something simple, I think those are not the type of genres you should be doing as a beginner. But then again, I don't know your background of implementing network games. In any case, I think the dumb client model (similar to Quake) is the easiest to implement at first; you press the button, send input to the server, server calculates/updates the game state and sends response to you and interested receivers which in turn updates their view of the game. Once that is done, you can move on to do something like client-side prediction / interpolation.

Edited by maunovaha

Share this post


Link to post
Share on other sites
Back to the original question, your solution is to not only send position but also velocity (and possibly acceleration, depending on the game), as well as a timestamp. On the other end you will then be able to calculate the expected position at any time from the last known values of these parameters. You can improve this further by using various techniques for interpolation and clock synchronization

Too hard for me. Not impossible, but better to do something simple first.

 

 

In any case, I think the dumb client model (similar to Quake) is the easiest to implement at first; you press the button, send input to the server, server calculates/updates the game state and sends response to you and interested receivers which in turn updates their view of the game. Once that is done, you can move on to do something like client-side prediction.

 

This sounds like a pretty good start. One negative side is that it kind of sucks to press W and wait a century to move because you need to receive position from the server, but I need to start with something, so this is the solution that I need.

 

Internet is a lot faster now than it was in the quake days and I'm only making 1v1 match, that's why I'm pretty sure this dumb client quake style will be sufficient.

 

 Thanks a lot for all the suggestions, guys. 

Edited by codeBoggs

Share this post


Link to post
Share on other sites

 

In any case, I think the dumb client model (similar to Quake) is the easiest to implement at first; you press the button, send input to the server, server calculates/updates the game state and sends response to you and interested receivers which in turn updates their view of the game. Once that is done, you can move on to do something like client-side prediction.

 

This sounds like a pretty good start. One negative side is that it kind of sucks to press W and wait a century to move because you need to receive position from the server, but I need to start with something, so this is the solution that I need. Thanks a lot for all the suggestions, guys. Dumb client is the way to go for now.

 

 

Yea, I never said that it is the version you should ship with.  :wink: Just start building the easier functionality first, measure/study it. Then decide what you should be doing next to make the game feel more playable. Otherwise, you end up making a system you don't understand and it is hard to debug/fix that later on.

Edited by maunovaha

Share this post


Link to post
Share on other sites

Otherwise, you end up making a system you don't understand and it is hard to debug/fix that later on.

 

True.

 

Yea, I never said that it is the version you should ship with

 

I'm far away from shipping a game. :lol:  I'm just doing a demo in order to torture some game studio with it until they are tired of me and give me the job. ^_^

Share this post


Link to post
Share on other sites

dropped TCP packets are just waited for at the router to be resent again


Routers, in general, do not wait for re-transmission before they forward, because they work at the IP layer, not the TCP layer.
For "reverse NAT servers" this changes, as they play the role of end-points, but when you talk about "router" in general internet parlance, you typically mean the boxes that sit in the middle of the network.

The re-transmission in TCP is entirely handled by the endpoints -- the machine doing the sending, and the machine doing the receiving on the other end.
And if one packet is dropped or delayed, ALL THE PACKETS AFTER THAT PACKET ARE HELD when they are received, waiting for the dropped/delayed packet to be re-sent.
By the time the dropped packet is detected, re-transmitted, and received on the other end, anything that was sent after that is also late, because it's been sitting in the kernel, received by the host, but not delivered to the application, because of the in-order guarantee.

Regarding spraying 100 packets at the same time, that doesn't really help, because the main reason a packet is dropped, is that there is congestion at some node on the network.
Once there is congestion, if the node receives 1 packet from you, or 100 packets from you, they will all be dropped at that time until the congestion recovers.
If you want to try duplication, consuming bandwidth in an attempt at higher robustness, it's much more robust to perhaps include the last 2-3 packets as copies in the next packets you send, so there is some time between each. This will add a bit of overhead, but if you structure your data right, it will RLE compress really well, and thus won't actually consume 200-300% of the bandwidth.
If the network drops three successive packets with a packet-send delay between each, the congestion is likely so bad that you're going to have a bad playing experience no matter what.

Share this post


Link to post
Share on other sites

A bit more on that...

 

You seem to already know some of this, but the nature of the questions means it bears repeating:

 

TCP is stream based.  The protocol makes sure that you get what was sent, in the exact order it was sent.  This is wonderful if you prefer a guarantee that everything arrive in the order it was sent.  If something was dropped on the network the underlying protocol will tell you it isn't ready yet, and it will do its job behind the scenes to request the missing data and ensure that your stream is given to you in the order it was sent.  This isn't necessarily wrong or bad, and if you need a stream based system it can be exactly what you need.

 

UDP is packet based.  The protocol gives you items as fast as they are received, and does not take steps to deal with network hiccups. This is wonderful if you prefer data is available as soon as it arrives.  However, if something was dropped on the network the protocol won't automatically request it for you; if a network hiccup gives you a packet multiple times, twice or three times or twenty times, you'll get copy after copy as they arrive.  This isn't necessarily wrong or bad, and if you want data as soon as it arrives it can be exactly what you need.

 

 

 

Raknet, like many game networking libraries use UDP for their communication and then implement an optional stream-based protocol on top of it.  This way you can specify how you want the data.  If you want the data as fast as it arrives then you can flag it to use that version of their protocol, but in exchange you need your code to deal with missing packets, duplicate packets, and the rest.  If you want your data stream based you can flag it to use that variation of their protocol, but in exchange you need your code to deal with the fact that sometimes the stream will stop after network hiccups and it may cause a delay.

 

 

 

 

Whichever version you end up taking you will need to design in ways to deal with latency and with network hiccups.  There are many tips and tricks out there for dealing with them. Some of them can be masked with simple tricks: an audio cue ("Yes, sir!") or an animation (slight gun lift and trigger pull) can buy you 100-200 milliseconds. For bullets, introducing flight time on the shot can gain you another few hundred milliseconds.  A bullet may travel about 4000 feet per second, so there's another 10 milliseconds of network time.  Dead reckoning and predictions with rewinding and injecting events are more difficult to implement, but they can further reduce the perceived network performance.  You can implement any or all of those things using either stream-based or packet-based networking protocols. 

Share this post


Link to post
Share on other sites

This topic is 481 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this