Questions on Network Implementation

So I am going to make a Live Action Networked Game (or at least a template for one) and would like some guidelines for how to implement it in theory.

Here’s what I’ve gotten from the things I’ve read so far -

[i]You have a server with an authoritative game state from some time in the past Si. At set intervals, for any period of time in which it has inputs from all of its clients, it will simulate the game state to a new authoritative state at time Sf, and then send this to all of its clients.

The clients will then revert their game states to Sf, discard all cached inputs before Sf, and then use the remaining ones to interpolate the game state up to time N, the actual current game time. To simulate the other client players, they will simply guess based on the last input given to them.

Whenever the clients update, they will continue to cache inputs for that period of time, and also send their inputs to the server.[/i]

So does that sound about right? Is there anything I can do to improve how a client guesses what the other clients are doing? Or just improve it in general?

Additionally, I am not sure whether or not I should use UDP or TCP. I know UDP is generally faster. However the server always needs to guarantee that it receives every client input, so I do not think UDP all by itself is reliable enough. Would it be worth it to implement some sort of reliability layer on top of UDP, or to just use TCP instead? And if so, what would be the best way to go about this? Is there a good library for Java that handles this kind of thing already?

Thanks in advance.


Interesting discussion, but the first couple of pages are a bit outdated.
For ease of use I would suggest just using TCP. It’s not like it’s that slow.

TCP is 99.99% reliable as far as I know. Its a bit slower because its guaranteed to reach the endpoint. However, datagram sockets(UDP) are just shipped off and never thought about again.

Basic summarization of UDP:
If you are ok with data disappearing forever then use it.

UDP is also great matter order if of doesn’t packets your the

The only thing that’s changed is network speeds. The base issues of UDP vs. TCP are the same now as always.

Ha! I was confused for a while there then I noticed the pun…nicely played :slight_smile:

Having dabbled a bit, some thoughts based on my limited experience…

UDP is good for peer-peer, as you can use UDP punch-thru to get through the NAT in routers. For real-time games, my choice is for each client to maintain a database of objects including position, velocity and last update time. The positions are locally updated based on velocity. When a UDP packet arrives for that object, the position data in that object is adjusted based on the velocity in that incoming object, for the time difference between the server and the client. The local database is then updated with the corrected position and the (unchanged) in-coming velocity.

Measuring Lag is a problem. It’s required for real-time games for lag-compensation. It is possible to measure round-trip delay to a server and use that to lock local time to a common time source. This really needs incoming packets to be time-stamped immediately on receipt, which is a problem if the OS sticks them in a FIFO with a large random delay before the user process gets them. My mileage has varied a bit here. This also pre-disposes that lag is symmetrical upstream and downstream, which is unlikely, particularly if you are using a satellite dish for receive. Anyone know how to do this better?

The problem with UDP comes when you have one-off event data to transmit around. The choice is either to use TCP, or to implement your own guaranteed delivery service over UDP. For a client-server implementation, then TCP works well, and would be my choice for turn based games (non real time). For anything that does peer-peer then it’s a case of grow-your-own on top of UDP, so as to be able to use UDP punch-thru.

Incidentally peer-peer sucks for security. To reduce hacking, all decision logic must be on a server, which tends to mandate a thin client approach. Of course you have to pay for the server bandwidth, so this is more appropriate for play-to-play games. My hobby efforts have focused more on peer-peer with distributed decision making, and limiting server bandwidth to a time server and NAT punch-thru introducer. That way uses less server bandwidth. However a regular keep-alive ping is still required to keep track of game joiners/leavers.

I also had a go at LANplay, using multicasting. That works peer-peer and you don’t have to worry about NAT as you are all on the same segment. No need for lag compensation either. However in these internet gaming days, no one can be arsed to take their computers over to a friends and set up an impromptu net for LANplay, so really it’s more of historical interest.

TCP is for receiving nominally reliable datagrams which are seen in order.

UDP is for everything else since you can build whatever functionality ontop of it.

The best way to choose between them is to use a library which meets your needs.

Flow control. Use TCP.

Riven and I have been having a very interesting time making a networked multiplayer game. We’re about 2.5-3 months in to it, although Riven only started full time maybe 6-7 weeks ago, when we really started solving the problems. I say “problems” but really most of it is “design”; “problems” are what comes when “design” isn’t right :slight_smile:

For the first few weeks I was just mostly prototyping and experimenting with designs on my own with a lot of input from Riven which I kinda ignored so that I could, well, experiment. It turns out though that he was basically right on a number of things.

Firstly, UDP is hard to do. Especially if you’re going to actually do it how you’re meant to do it, which generally involves sending a delta against some known state that we understand the client has. It turns out that keeping track of the known state of a client is quite tricky if you’re never sure exactly what data has been received and when it was received. I eventually solved this problem, using a system very much like the “Quake 3 networking model”, but I have to say, the code was so complex and nasty I did not like the look of it one bit, and it was very hard to maintain and refactor.

So eventually we switched to TCP on Riven’s advice; and it’s worked out much more simple for us, as we now no longer have to worry about out-of-order packets and resending ourselves; instead TCP takes care of that, in the actually rare circumstances in which packets actually get lost these days. All we’ve really got to be careful about is not sending so much data that a backlog starts to grow between server and client that it can never empty. The whole design of the system got a whole lot simpler from this point onwards as a result of the net code being so much easier. We’ve implemented something that looks a bit like half-duplex RMI, but extremely efficiently implemented.

These days over broadband the actual overhead of a TCP packet is almost irrelevant compared to the overall efficiency of the protocol and design itself. The only reason we had for using UDP was that we could implicitly discard stale state and just keep sending deltas versus some known state, however as we discovered that actually making deltas is a massive, massive problem in itself, solved completely simply by using reliable data delivery, TCP was the way to go. Latency is excellent - certainly barely noticeably any different from UDP - and we’re also free to send “big data” without confusion eg. map chunks.

Cas :slight_smile:

One thing to remember is that if you use TCP/IP and send 10 packets, of which packet 1 is lost, then packets 2 through 9 are held up on the stack, while the missing packet 2 is re-requested and re-transmitted. If you send stuff over the internet it goes through a number of IP stacks, any of which can cause lag to a whole series of packets due to a single packet loss. It’s really a horses for courses thing, nether UDP not TCP/IP is better overall.

Packet loss in TCP starts to becomes an issue under severe congestion, but it should also be noted that under those same conditions, packet loss for UDP tends to be catastrophic.

I still prefer using UDP for real time networking though and I used a lot of ideas from this article by Valve.

You wrote a real time networking game with UDP? :persecutioncomplex: not bad.

Well it wasn’t a full featured game, it was just a bunch of players armed with guns. It worked surprisingly well with people from all over the US and Europe! :slight_smile:

Just a question, its probably extrapolation, but what is the best way to send “positions” to a server to make it as much as sync as possible?

This could be very useful code, you know! and… … ::slight_smile: … ;D ::slight_smile:

You cannot send positions from the client to the server simply because you cannot trust the client. You would have to send input data to the server that makes sure they are valid and applies them.

Well, yeah, I got that part, but what would be the most efficient way to get the most synchronized position over a network as possible?