I'm currently happily coding away at the Lobby for the game. Most of the code is in now, with the exception of colors / factions / map. I'll add in which map will be loaded soon to the host as a command line switch (dune -host 2 -name Host -map mp_test.map). I also added in most of the code for the LobbyClient. When connecting to the server, it will display a nice "Connecting..." text and when handshaking between client/server has been completed, it will show the same text as the lobby(ie, n out of m connected players).
Now, let's dive into the messaging system:
I decided to cut up the system into small, manageable components. This means there's a Server, LobbyServer and GameServer. The Server object manages the connections and routes the messages to the sub-system. The responsibility of the LobbyServer / GameServer should be obvious.
Because I wanted to seperate out the systems, the first byte in a message is the 'targeted' sub-system. The 2nd byte is the message and the 3rd and beyond bytes are message specific:
1 byte 1 byte n bytes
[Sub-System] [Message] [Message Specific Data]
There are no fields in my messages which specify the length of data. Because Lidgren handles all the low-level stuff, it will wrap my data into UDP packets, and reading data back is as simple as msg.ReadString() / msg.ReadByte(). No need to check for correct length, or if all the data is valid: Lidgren does that terrible work for me.
The pro of my system, is that I don't get insanely long switch statements to handle all the messages. This is how my 'main' message pump looks on the server:
It's quite simple, and adding new sub-systems is a matter of seconds.
The ProcessMessage() then reads the next byte in the message, which contains the message, which is used to pass it to the correct handler. That looks like this:
How each message is composed isn't really that important. I can give you the exact details, but it sounds more boring than interesting.