
Reliable Ordered Messages - adamnemecek
http://gafferongames.com/building-a-game-network-protocol/reliable-ordered-messages/
======
derefr
> Many people will tell you that implementing your own reliable message system
> on top of UDP is foolish.

It _is_ foolish: both SCTP (over UDP) and RTP+RTCP (over UDP) already exist,
and in combination do exactly what the author wants. There are more things in
this world than TCP and "your own custom protocol."

It's almost like the 'network engineers' in gaming have never looked at the
network architecture of a telecom system. Same problems: well-known standard
solutions.

(There _is_ one case where inventing your own transport protocol instead of
reusing the standard ones makes sense: when every higher-level protocol but
one is blocked, forcing you to tunnel over that one protocol. Thus WebRTC. But
now _that 's_ a standard too, so don't reinvent that either!)

~~~
felixgallo
Oh hi! I'm a network engineer! In gaming! I happen to routinely use 'the
network architecture of a telecom system' via erlang so I may be qualified to
answer your post.

RFC 6951 style SCTP-over-UDP is not super widely implemented, so you end up
having to implement it yourself. When you're doing so, you pretty quickly
realize that it's significantly more heavyweight than anything you actually
need for a game (e.g.
[https://tools.ietf.org/html/rfc4960#section-5.1.6](https://tools.ietf.org/html/rfc4960#section-5.1.6)),
while at the same time missing several key facilities, such as knowing
instantly, with every packet received, which of the previous (e.g.) 32 packets
have also been received, and so forth.

RTP has the same problem. There's fields included with every packet (SSRC,
CSRC, others) which are irrelevant to gaming. There's a bunch of libraries,
most of which are total junk. There are end to end compatibility problems
owing to different interpretations of the spec.

This turns out to be a gigantic problem, because gaming network engineers use
all sorts of ridiculous tricks to try to bum every last byte out of their
protocols. For an entertaining afternoon check out
[http://gafferongames.com/2015/03/14/the-networked-physics-
da...](http://gafferongames.com/2015/03/14/the-networked-physics-data-
compression-challenge/).

A _much_ more relevant criticism might be, well why don't you use, e.g.
protobuf rather than invent your own framing system? Because the case of
protobuf -- where you want, essentially, to transmit a purpose designed struct
directly over the wire with no bullshit -- is very much like the case of a
twitch game network protocol and comes pretty close to hand-bummed byte sizes;
close enough that the benefits of using something a bit more extensible and
introspectable might be worth it.

Anyway, in short, you don't know what you're talking about and Glenn is a
national treasure.

~~~
the_angry_angel
> why don't you use, e.g. protobuf

protobuf sounds attractive, but (unless I've missed something in protobuf's
implementation), but out of the box you have 2 issues:

1\. Protobuf doesn't/can't deal with fragmentation - so you'd have to ensure
your protobufs are small enough to fit inside a UDP packet

2\. Without a wrapper you couldn't put multiple small protobufs into a single
UDP packet?

Both things are fixable by wrapping protobuf, but I suppose if you're trying
to get something as small as possible, can you actually just do better by
avoiding protobuf in the first place (I guess the answer is yes?)

~~~
niftich
I understood it as using protobuf's interface definitions as as an integration
point, not necessarily protobuf's exact wire format and everything below it
that comes out-of-the-box (like TCP and below) in the default client.

~~~
felixgallo
I meant everything up to and including protobuf's wire format, but nothing
beyond that, which as you note wouldn't be super great.

------
jephir
There's a lot of talk here about TCP vs UDP vs SCTP vs x protocol.

It's important to keep in mind that this is all optimization. Don't lose sight
of the big picture.

On one RTS we ended up just serializing world state over a TCP socket. If you
can get away with the brute force approach then just do it. Don't optimize
until you have a measurable performance problem.

------
dividuum
Nice blog post. It reminded me a bit about how QuakeWorld did networking over
UDP back in the days. There is a post about it here:
[http://fabiensanglard.net/quakeSource/quakeSourceNetWork.php](http://fabiensanglard.net/quakeSource/quakeSourceNetWork.php).
I remember implementing that myself for a networked version of jump'n'bump
which never got anywhere :-)

~~~
jhasse
Jump'n'bump rocks!

------
caseymarquis
Glad to read anything I can regarding networking applications in practice.

Transmitting between embedded devices and PCs, I've been stuck with either Tcp
or Udp; no other protocols are typically implemented on the embedded side.
I've found sending reliable ordered messages requires implementing something
on top of either protocol. Udp is great for concrete messages, but doesn't
give you ordered reliability, Tcp has the opposite problem where the streaming
nature means you need to wrap messages and occasionally confirm proper receipt
of a message to figure out when old messages can be tossed. The issue with Tcp
being that when the connection breaks down, you don't in practice know exactly
where it broke and if the other side received several completed messages and
acted on them, or if you need to resend.

I'd initially assumed Tcp would cover all my needs. Didn't take much initial
research to figure out that wasn't true.

