[MUD-Dev] Networking architecture overview
bobbymartin at hotmail.com
Fri Oct 19 02:26:48 New Zealand Daylight Time 2001
> From: "Amanda Walker" <amanda at alfar.com>
> Brian Hook wrote:
>> So I finally called up a friend of mine (John Carmack) that
>> really, really understands real-time networking and asked him to
>> core dump on me how he has implemented his networking. The
>> answer is not what I expected, but it's a damn elegant solution.
>> [...] There are no reliable packets of any kind. In fact, there
>> is only a single packet type -- the client's necessary game
>> state. The server sends sequenced game state updates that are
>> delta compressed from the last acknowledged game state the client
>> received. This "just works".
> This is a wonderfully elegant solution; and by thinking of the
> problem abstractly (i.e., "I need to keep two machines' game state
> in sync") rather than concentrating on the mechanics ("I need a
> reliable sequenced data stream"), he was able to implement only
> the type and degree of reliability he needed. In effect, it's TCP
> at the game state level, rather than the transport level, which is
> extremely cool indeed.
>> So this architecture basically obviates the need to even have a
>> discussion about UDP vs. TCP and unreliable vs. reliable and
>> out-of-order vs. in-order. It's all unreliable UDP delta
>> compressed against the last known state. > Damn that's smooth.
> Yes, indeed. Very smooth. A simple scheme that provides exactly
> the sort and amount of reliability the software needs, with no
> extra fluff. This idea isn't, like, patented or anything, is it?
My first thought when I saw this was "Wow, that's brilliant!!". My
second thought was "Didn't I think about something like this before
and dismiss it without really thinking about it? What an idiot I
Now that I've had some time to digest it, I see two issues with it:
1) You really have to design your "business logic" around it.
Most pieces of data need to know how to update themselves from
pieces like them, replacing some parts with the new data,
accumulating lists of other items, etc. I think this is a fairly
small price to pay.
2) UDP, at least the implementations that I have used, only
supports packet sizes up to about maybe 3k bytes. After that, you
get REALLY bad packet loss. So if your game state gets out of
sync for too long, or if you're just sending a lot of data in the
first place, you end up with UDP packets that are consistently
lost. If you split the packets, then you are back to a situation
of writing a kind of packet assembly and reliability layer on top
of UDP. 2 is a much bigger problem than 1, IMO. If you are sure
that you will never accumulate that much game state to send to the
client in one swoop, then the system sounds fantastic. If you
ever go over that limit, you have to take some special measures to
resync, and I suspect that you will have lag issues occasionally.
One thing that John fails to mention in his description of the
system that I think is important, is that you really shouldn't be
trying to send game state deltas. You just want to send a delta of
the game state the client knows about. So, if I were to implement
this system (and I might ;) I would have a proxy object on the
server that receives the client messages and accumulates them,
merging when possible. The proxy would have to have a version
number that it updates each time it receives a message, and would
have to keep old versions. Then, when it gets a version ack back
from the client, it flushes all versions up to and including the
acked one. Periodically (every time a message is sent to the
proxy?) the proxy would send one (or more, if the data is over 3k)
UDP packet to the client, along with the version number that the
The only real difference there is that we don't send the entire game
state, just the accumulated client state.
I still think it's a brilliant system, just not quite the
oh-my-god-that-solves-everything that it first appears to be.
MUD-Dev mailing list
MUD-Dev at kanga.nu
More information about the MUD-Dev