glob2-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Networking (was Re: [glob2-devel] Glob2 salvage proposal)


From: Andrew Sayers
Subject: Networking (was Re: [glob2-devel] Glob2 salvage proposal)
Date: Mon, 24 Oct 2005 17:38:23 +0100
User-agent: Mutt/1.5.11

I said that I was going to have a long think about networking, and here
are my first ideas:

*** Synchronisation/portability

I've not checked that this will work yet, but I think that we can put
some safeguards in the code to ensure that only portable code is used.
My current plan is to do this by requiring every Glob2 class to be
declared inside the "Glob2" namespace (which is only good practice
anyway).  Then we can define:

namespace Glob2
{
        typedef int nonportable_int;
        typedef void int;
        // same thing for short, long, signed and unsigned ints, floats
        // and doubles

        Uint32 rand() { return syncRand(); };
        Uint32 random() { return syncRand(); };
}

These would have to be put in a standard header that all files include -
I'm thinking of using <GAGSys.h> - what is its current job, and could it
stand to be included in every file?

*** Latency

For those that don't know, latency is the amount of time between the
moment a message is sent and the moment it is received.  For example,
this message was sent at about 5pm on Monday.  If it arrives in your
inbox at 7pm, the message has a latency of 2 hours.

The only important issue of latency in Glob2 is the amount of time taken
between the moment you send an order, and the moment the order is
received.  It's more useful to talk about latencies in ticks rather than
seconds: if it takes 10 ticks between me sending an order and the order
being received, that's twice as frustrating as if it takes 5 ticks.

Latency is most important in network games, where you need to send an
order post-dated by several ticks so that you can be sure your order
arrives without causing the game to run too slowly.

Currently, ticks are hard-wired to last for 40 milliseconds, but it
occurs to me that we can reduce the perceived latency of a game by
making ticks last longer.  This would be a very big change, but would
have some important benefits:

* Players could set the game to run faster or slower, to their taste.
* The game could automatically adjust if it consistently uses too much
  processor time.  This would reduce the "jerky" nature of the game on
  an overloaded computer.

In fact, slowing ticks down already occurs when the processor is
overloaded, and NetGame.h talks about the "delay" on orders as a way of
speeding up and slowing down ticks to compensate for slow computers.

*** Mid-game communication

I've got the start of an idea for how mid-game communication would work.
At the moment, there are still a lot of grey areas (I'm ignoring latency
for example, because of the discussion above).  I'm trying to base my
proposal loosely on the OSI model (http://en.wikipedia.org/wiki/OSI_Model)
because we really need a properly layered stack if we want to avoid
another messy implementation.  Here are the ideas I have at the moment:

** Presentation layer

Commands from the player are serialised into orders, and sent down to
the layer below.  Every 40 milliseconds, this layer attempts to
retrieve the next tick's worth of orders from the layer below.  If it
fails, the game pauses (waiting for specified player(s)) until the
tick can be retrieved.

** Session layer

Orders are received from the layer above, and assembled into
"messages": complete sets of orders for one player, for one tick, plus
the index of the associated tick.  These messages are then sent down
to the layer below for transport to peers.

When a complete set of messages for a given tick has been received
(that is, every message from every player for that tick), the orders
in the message can be passed back up to the layer above for execution.

Note that if a given tick is ready for execution, the layer below
guarantees that all previous ticks will also be ready for execution.

Also note that we do not know whether our peers are ready to execute
the next tick at the same time we are.  Nor do we care.

** Transport layer

One UDP segment is sent from each peer, to each peer, every 40
milliseconds.  Ordinarily this equates to once per tick, but the
messages still need to be re-sent even when the game can't progress to
the next tick because it is waiting for another player.

UDP does not guarantee that segments will arrive, or if they do,
what order they'll arrive in.  UDP will accept incoming messages from
any IP address, and Glob2 makes no attempt to guard against packets
being spoofed.  The only real guarantee it gives is the integrity of
the data in the segment.

The data section of a Glob2 UDP segment consist of an unsigned 32-bit
acknowledgment number, an unsigned 32-bit player number, and a series
of variable-length messages passed down from the layer above.

The 32-bit acknowledgment number is equal to the highest message
number received from the peer who will receive the current segment.

The 32-bit player number is a unique identifier for the current
player, agreed with the help of the YOG server at the start of the
game.

The series of messages contains every message passed down from the
layer above, with a message number greater than the highest
acknowledgment number received from the peer.

Note: this implies that messages are re-sent by default unless they
have been explicitly acknowledged.  Waiting for a specific re-send
request would cause more lag because the re-send request might not
arrive.

        - Andrew




reply via email to

[Prev in Thread] Current Thread [Next in Thread]