Communication system
This paper explains how we will implement the comunications between
entities. An entity is a copy of Frozen Bubble with networking enabled.
We go through some paragraphs, describing what we will code.
Index
Protocols
Protocols
Before coding we planned our protocol, examining what problems we could
encounter. First, we distinguished between a "pre-game"protocol and an
"in-game" protocol. Our problem was to find a list of the hosts able to
play with. A(n) host should not be too distant from us to mantain a good
playability. When we retrieve the list of the hosts, we can play a
single game with the chosen host. In this case we need a syncronized
protocol, or something that looks like :) Well, this paragraph should be
only an introduction. If you want more, read further! Other problems
were related to reliability of the comunication, but we discuss about
this later too.
As a summary, the problems we needed to solve were:
- neighbour discovery,
- latency calculation,
- synchronization of the games,
- reliability of the comunication.
Little NOTE: the next section explains the in-game protocol, since the
pre-game protocol is simpler and is discussed later.
In Game Protocol: Interlaced Asynchronous
Our first "in-game" protocol came out discovering a list of needs among
which we can find:
- a queue of input events, to be shared with the one that the game
includes
- buffering the previous packet, to mantain a unique signum that
identifies our packet
- a timestamp, that helps to get an unique packet
- and last managing timers all around (packet retransmission, game
events).
Packet description
The sample packet we send across the network is a couple of status
words, one for each gaming entity, a couple of univocal signa (we used
timestamps) and a simple parity. The status word is data that must be
sent, collected from the input queue of the game.
[imagine... greatest song ever. nbIago blah]
Entity behavior description
A game session is composed of two entities sending packets,
synchronized in the way that follows.
The two entities, from now on A and B, send the packet described above
in an independent way. (In the pre-game session they (A, B) synchronized
a clock, but this doesn't change the way the two entities interact
later.) The first packet that the A entity sends contain an empty remote
status word, while the local status word is generated by the first
state inserted in the event queue and the univocal reference (time).
The following packets are identical, except for the remote status word
(it changes to the received local status word, that's local to the
remote host). The following packets are generated concatenating
the local and remote status word. As a completition, for each packet
received one packet is sent as a reply.
If the received packet is coherent with the status word sent (it means
that the received remote status word and the local word are the same) a
new local status word is collected from the game event queue and the
received local status word is sent above to the game. New packets will
have a new local status word, but an unchanged remote status word.
If the received packet is incoherent the packet transmitted will
contain the old remote status word. (This reflects the need for a
transmitter buffer).
NOTE:
This structure requires a strict latency calculation in order to
mantain a good playability. Before proceeding we defined a maximum
latency to avoid game slowdowns. In this moment it's about 40 ms. When
we will have completed our tests probably it will change. We put our
hands in frozen-bubble to test the slowdown of such a timer, changing $TARGET_ANIM_SPEED to the original
value of 20 plus 1/8 of the maximum latency. Then we added a fictitious
delay, as heavy as the maximum latency admitted, in the input management
cycle.
Synchronization and random events
Frozen bubble includes also some rand() calls, so we have to
synchronize also the random seed to get a coherent evolution of he
game. We are examining the code so to understand in which ways we can
modify the code, but probably all the synchronization will be done with
a srand() during the communication setup.
Pre-game Protocol
The pre-game protocol looks simpler than the in-game protocol. Just now
it is based on multicasting. Every entity subscribes an multicast group
and sends an Available packet.
Packet description
The packet contains an identifier (name) and the version of the
game/protocol. In each packet is present also a time reference
(signum/identifier) and a command. Each host can get informations about
the other end of the comunication (multicast or unicast) socket from the
IP headers included.
The command contained in the packet is one of the following:
- PING/AVAILABLE,
- STARTGAME,
- ENDGAME,
- AWAY.
Entity behavior description
Every entity subscribes the predefined multicast group, as said. Then
it sends a PING/AVAILABLE packet to the group. Each entity that receives
this packet replies with an unicast packet, in order to get an accurate
latency calculation. When the hosts have a good evaluation of the round
trip time they include the remote host in the list of the available
hosts. As a note, the hosts included in this list aren't distant more
than a specified delay.
When an host wants to leave the game session sends an ENDGAME packet so
to disappear from the list of the available hosts. Instead, if an host
doesn't want to play, it sends an AWAY packet.