gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

Coding > Multiplayer Packet Methods [Fully Explained]

#28741 - Krakken - Fri Nov 05, 2004 7:08 am

Hi,

I'm making a multiplayer game. I've real lots and lots on serial communication over time and am working on a packeting system for multiplayer transfers.

So far, i've worked out a system. I'll explain it in a second and I just would like some feedback on optimising or improving the system; or even if it's any good for that matter.


System Overview
The system works on a set of packets to send data. Each packet can contain pretty much anything. It implements pretty reliable transfer but can only do one byte per transfer. I intend on syncing transfers to frames so 60 transfers can be made per second - therefore a total of 60 bytes from each person.

How It Works
It works by sending a header followed by a checksum and then the data with information attached to it. If there is a problem at any point the master will cancel the packet and re-transfer all the data.

A List of Features Needed For it to Work

Transfer Type
This indicates the type of transfer:
- 00: Header
- 01: CheckSum
- 02: Normal Data
- 03: Error/Resend Request

Packet ID
The ID of the packet so that the right data can be resent on error. Also, so the data is reconstructed into the correct place. Every struct/whatever has it's own packet ID.

Transfer Bytes
The amount of bytes that need transferring for the particular packet.

CheckSum
To verify data.

Data
The actual data to transfer.

The System Itself
The actual system works as follows.

The Packet Header
The header is a 16-bit short value which is layed out like follows:

F E D C B A 9 8 7 6 5 4 3 2 1 0

T T P P P P P P B B B B B B B B

T: Packet Type (2 bits) = 00 (see above for explanation)
P: Packet ID (6 bits)
B: Bytes to Transfer (8 bits)

The CheckSum
Following the header, all units send out a checksum for their data structure. The format is as follows:

F E D C B A 9 8 7 6 5 4 3 2 1 0

T T C C C C C C C C C C C C C C

T: Packet Type (2 bits) = 01 (see above for explanation)
C: CheckSum (14 bits)

The Data
The data is immediately sent after the CheckSum. It is contually sent until it reaches the specified size from the header. The format is as follows.

F E D C B A 9 8 7 6 5 4 3 2 1 0

T T P P P P P P D D D D D D D D

T: Packet Type (2 bits) = 02 (see above for explanation)
P: Packet ID (6 bits)
D: Data (8 bits)

The Error
When an error occures, the following is sent to the master.

F E D C B A 9 8 7 6 5 4 3 2 1 0

T T P P P P P P X X X X X X X X

T: Packet Type (2 bits) = 03 (see above for explanation)
P: Packet ID (6 bits)
X: N/A (8 bits)

The Communication Method
Only the master machine constructs headers it informs all slave units to create a CheckSum from "Packet ID" data of size "Bytes to Transfer". All units then send back their CheckSum to each other and the transfer begins.

When data is recieved, it is reconstructed in sequence into temporary storage. Then it is tested against the checksum and if there is a match the data is copied into the appropriate "Packet ID" structure for that player. If not, it returns an error message to the master.

If the master recieves an error command, it will restart the transfer.

#28811 - Miked0801 - Sat Nov 06, 2004 8:48 pm

You're missing a couple of very important steps.

1. How do the slaves/master know when a transfer has been successful? If they just go when they've received a valid data packet, it doesn't give the master time to send a message if another unit sent bad data and you are out of sync.

2. Look at eack step and ask yourself what happens if data is corrupted at this step and how does the system recover. What if packet header is missed, then you've lost a bunch of time as crap is sent to all slaves until a checksum occurs - if you're sending 64 byte packets, that's over 32 bad transfers and you've jssut dropped a frame. Same for other steps.

3. You're going to need to sync to gameloop not to vsync else chaos will ensue (or you'll need a whole bunch of if code to handle timing issues that will popup)

4. There is no reason at all to keep sending packet type and ID each frame. You're halving your transfer speed for no good reason. Send it once in the header and be done with it.

5. Transfer speed is going to be really, really slow! You can send roughly 40 bytes in a frame - less with heavy interrupts (like hblanks, vblanks, and music.) If another interrupt takes your SIO out, you have the chance of dropping a packet and therefore a frame. Also, keep in mind all the CPU overhead that all these interrupts firing off cost you. I've found that it can eat upwards of 15% of your CPU time if you let it get greedy.

That's it for now. Good luck on getting it up and running! (not sarcastically)

Mike

#28830 - Krakken - Sun Nov 07, 2004 8:05 am

Hi Miked,

Thanks for your suggestions, I was hoping I would get a reply from you.

I have taken what you said into consideration and have re-worked the system a little so that it should work properly now.

-----

1: Data is now transferred 16-bits at a time.
2: I have completely removed the type bit, I soon realised that it was unneccary if I just make the units remember what state they are in rather than having to be told.
3: I have incorperated a success faliure system. 0xF0F0 is a success and anything else is seen as a faliure.

-----

The format now looks like this:

Header: 8-bits PacketID, 8-bits Bytes to Transfer
CheckSum: 16-bits
Data: 16-bits
Verification: 16-bits (0xF0F0 = Success, Anything Else = Faliure)

-----

I have made a flowchart to show the new system (it doesn't incorperate the point I made below). It should give you a better idea rather than trying to visualise it from words.

[Images not permitted - Click here to view it]

-----

One point that stumped me was how I should sync to my gameloop. How exactly do you mean?

Also, i've just thought. I think it would be a good idea to echo the header back to the master after it is sent and before the checksumas verification.

Thanks again,
Krakken.

PS: This is the 3rd time I have written this... Things kept messing up before like me accidentally closing the window and then following a link before posting it. :(