Message Formats

A XBlast message has the basic format of a central data block to which one or two layers are added.

Layers

A layer is a data portion containing entries that generally describe the type of message contained in the data block. The result is a layered data block which itself can be used with another layer.

Datagram Layer - Dgram(DATA)

Given a data block DATA containing N bytes, the Datagram layer leads to the following layered data:
     START    - unsigned char, currently \0x68
     LENGTH   - unsigned char, length of DATA = \N
     DATA     - n bytes, given data block
     END      - unsigned char, currently \0x16
Obviously, the Datagram layer can only deal with data blocks up to 255 bytes. It simply enables a receiver to recognize where the end of the data block is. Routines dealing with the Datagram layer are defined and implemented in net_dgram.[ch].

Telegram Layer - Tele(COT,ID,IOB,DATA)

Given a data block DATA containing N bytes, the Telegram layer leads to the following layered data:
     START    - unsigned char, currently \0x68
     LENGTH   - unsigned char, length of DATA = \N
     COT      - unsigned char, cause of transmission
     ID       - unsigned char, id of transmission
     IOB      - unsigned char, information object
     DATA     - n bytes, given data block
     END      - unsigned char, currently \0x16
The Telegram layer is only applicable to data blocks of up to 255 bytes. In comparison to the Datagram layer, the Telegram adds three descriptive parameters. The COT parameter roughly describes why the data is sent. Currently the following values are recognized (see net_tele.h):
/* cause of transmission */
typedef enum {
  XBT_COT_Activate,         /* server demands activation */
  XBT_COT_Spontaneous,      /* client message */
  XBT_COT_SendData,         /* send data to client */
  XBT_COT_RequestData,      /* request data from client */
  XBT_COT_DataNotAvailable, /* client does not have data */
  XBT_COT_DataAvailable,    /* client has data */
  /* --- */
  NUM_XBT_COT
} XBTeleCOT;
The ID parameter describes the format of the data itself. The following values are currently recognized (see net_tele.h):
/* telegram object id */
typedef enum {
  XBT_ID_GameConfig,        /* game data */
  XBT_ID_PlayerConfig,      /* player data */
  XBT_ID_RequestDisconnect, /* host wants disconnect */
  XBT_ID_HostDisconnected,  /* message host has disconnected */
  XBT_ID_StartGame,         /* server starts the game */
  XBT_ID_RandomSeed,        /* seed for random numer generator */
  XBT_ID_LevelConfig,       /* level data */
  XBT_ID_DgramPort,         /* port for datagram connection */
  XBT_ID_Sync,              /* synchronisation between client and server */
  XBT_ID_Async,             /* client and server asynced */
  XBT_ID_HostIsIn,          /* host is in game */
  XBT_ID_HostIsOut,         /* host is out of game */
  XBT_ID_TeamChange,        /* Team Change */
  XBT_ID_WinnerTeam,        /* Client sends winner team for level */
  XBT_ID_GameStat,          /* Host sends game statistics */
  XBT_ID_PID,               /* Central sends PID */
  XBT_ID_Chat,              /* Server/Client sends chat line */
  /* --- */
  NUM_XBT_ID
} XBTeleID;
The IOB parameter is used to denote what the data refers to. Its meaning usually depends on the ID value. Its main use is in Server-to-Client transmission to identify the client the data refers to. Routines dealing with the Telegram layer are defined and implemented in net_tele.[ch].

Browse Layer - Browse(TYPE,SERIAL)

Given a data block DATA containing N bytes, the Browse layer leads to the following layered data:
     MAGIC    - char[], currently "XBLAST" (what else? ;)
     PROTO    - unsigned char, protocol version, currently "\x01"
     TYPE     - unsigned char, message type
     SERIAL   - unsigned char, serial of transmission
     DATA     - n bytes, given data block
The Browse layer is theoretically applicable to any data block, but since it is used exclusively in conjunction with the Datagram layer in XBlast, the largest sensible data size is 246 (giving a layered data size of 255). The first descriptive parameter TYPE describes the format of the data. The following values, taken from browse.h, are currently recognized:
typedef enum {
  XBBT_None,  /* invalid data */
  XBBT_Query, /* query for games */
  XBBT_Reply, /* direct reply from game server */
  XBBT_NewGame, /* XBCC inform central of new game */
  XBBT_NewGameOK /* XBCC inform central of new game */
} XBBrowseTeleType;
The second descriptive parameter SERIAL denotes the message id from the original sender. Any receivers simply use the received serial in replies, but I have not seen that put to use yet in XBlast. Routines dealing with the Browse layer are defined and implemented in browse.[ch].

Data blocks

The data blocks are the core data portions used in the messages that are actually sent from socket to socket.

empty

No data, length=0.

config

A config is a null terminated string of the form 'entry=val\0'.

port

A port is a null terminated string. The value is extracted with sscanf() and format "%u".

hoststate

A hoststate is a null terminated string. The value is extracted with sscanf() and format "%u", then cast to the XBHostState type (mi_tool.h):
/* client state */
typedef enum {
  XBHS_None,
  XBHS_Wait,   /* waiting for client to send player data */
  XBHS_In,     /* client is in the game */
  XBHS_Out,    /* client is out of the game */
  XBHS_Server, /* host is server */
  XBHS_Ready,  /* host is ready to start */
  /*---*/
  NUM_XBHS
} XBHostState;

team

A team is a null terminated string. The value is extracted with sscanf() and format "%u", then cast to the XBTeamState type:
/* team state */
typedef enum {
  XBTS_None,
  XBTS_Red,   /* unknown if this is good */
  XBTS_Green,
  XBTS_Blue,
  /*---*/
  NUM_XBTS
} XBTeamState;

chat

A chat has the form
   ORIGIN   - who sent, higher 4bits are host, lower 4bits are player
   TARGET   - where to send, higher 4bits are host, lower 4bits are player
   DATA     - null terminated string, the message

seed

A seed is a null terminated string. The value is extracted with sscanf() and format "%u".

result

A result has the form
   N        - int (4 bytes), determines number of players and result type
   SCORE    - int[2] (8 bytes), pid of player and score
   ...
   SCORE    - int[2] (8 bytes), pid of player and score
The number of players is abs(N), which is of course also has to be the number of SCORE entries. A negative N denotes the end of game, which makes the score parts of the SCORE entries the number of wins. A positive N denotes a level result, which makes the score parts of the SCORE entries either =0 (player did not win) or !=0 (player won). The int values are currently extracted using memcpy(), which invites endian problems (needs fixing!). It should be little-endian order, which is used consistently elsewhere in XBlast.

times

A times data block has the format
   GAMETIME - unsigned short 0xFFFF
   PING     - unsigned short (2 bytes), client ping time
   ...
   PING     - unsigned short (2 bytes), client ping time
The unsigned short's are stored in little-endian byte order. A ping time of 0xFFFF denotes a client with no ping time.

frames

A frames data block has the format
   GAMETIME - unsigned short (2 bytes), current game time
   ACTION   - unsigned char (1 byte), player action
   ...
   ACTION   - unsigned char (1 byte), player action
The game time is in little-endian byte order and has to be smaller than 0xFFFE (OxFFFE is reserved for future, 0xFFFF used by times data block). An action byte value of 0xFF marks the end of action for that client. Other action byte values are parsed by the routines in action.c.

newgame

A newgame data block has the format
  PORT    - unsigned short (2 bytes), little-endian port number
  VERSION - unsigned char[3], major/minor/patch version of server
  GAME    - char[48], game name string, null terminated
  ID      - int (4 bytes), little-endian game id
  PAR     - unsigned char[3], numLives/numWins/frameRate

gamecfg

A gamecfg data block has the format
  PORT    - unsigned short (2 bytes), little-endian port number
  VERSION - unsigned char[3], major/minor/patch version of server
  GAME    - char[48], game name string, null terminated
  HOST    - char[32], host ip string, null terminated
  ID      - int (4 bytes), little-endian game id
  PAR     - unsigned char[3], numLives/numWins/frameRate

gameid

A gameid data block is an int (4 bytes) in little-endian byte order.

Config databases

This section describes config database entries and their values as needed for network communication. Databases consists of possibly multiple sections with the section entries being config data blocks, i.e. null-terminated "entry=value" strings. The entry strings are defined by atoms - for the actual string behind the atom, see atom.c.

game config

The game config database is a single section of config data blocks. The server game config holds the following data, after "Create a Network game": The initial game config determined by the server for a freshly connected client consists of the #GameHost group only, where only the atomHost and atomPort entries represent meaningful data. The client game config consists of the other three groups - of the #GameSetup group, only atomInfoTime, atomBot, atomBeep, atomMusic seem to contain meaningful data for a client.

player config

The player config database is a single section of config datablocks. It holds the following data:

level config

The level config is a multi-section database, each section containing config datablocks. The recognized section names are: A more detailed description to follow.