GGZ Instant Gaming

Josef Spillner, 14.04.2002

This article describes a game launch using a GGZ Gaming Zone server, without requiring a traditional GGZ client. It is therefore a concept which can be implemented by game authors for games which do, for example, have a long history of being launched on their own, so the players don't have to learn a new program. This will be referred to as GGZ Instant Gaming in this article. Note that the use of a GGZ client like kggz or ggz-gtk is still recommended.

All communication is done via an XML protocol. The current GGZ protocol has the version number 6, and is not stabilized yet. The game author should use proven functionality for the XML parsing, for example by using expat or qxmlreader, whatever is appropriate.

Let's start. The game connects to a GGZ server (a method of doing so, using a connection dialog or automatic connection via meta servers, must be provided by the game itself). It is presented with a 'welcome string', which consists of the opening SESSION tag and the SERVER identification which has OPTIONs like the maximum chat length.

<SESSION>
<SERVER ID='GGZ-0.0.5' NAME='An Unconfigured GGZ Server' VERSION='6' STATUS='ok'>
   <OPTIONS CHATLEN='512'/>
</SERVER>


The game client can now log in. This is done by replying with a correct XML header, and opening the SESSION from the client side, followed by the LOGIN attempt. This contains the player's NAME, and the PASSWORD when playing as registered user (which is not required).

<?xml version='1.0' encoding='ISO-8859-1'?>
<SESSION>
<LOGIN TYPE='guest'>
   <NAME>josef</NAME>
</LOGIN>


If the login succeeds, the RESULT returns code zero, and the message of the day (MOTD) is sent. The login procedure is then finished, and the game client can proceed with further action. Otherwise, either a player with this name is already logged in, or this is a registered name. See the GGZ protocol documentation for detailed information on the return codes.

<RESULT ACTION='login' CODE='0'/>
<MOTD PRIORITY='normal'>
  <![CDATA[No MOTD today!]]>
</MOTD>


Now the game requests information about the available rooms, and the installed game servers. It does so by sending the LIST command, which contains room and game as list types. In the example, a full listing is issued, which returns all available information. This is not strictly necessary, but useful in most cases.

<LIST TYPE='room' FULL='true'/>
<LIST TYPE='game' FULL='true'/>


Each list command is answered by a RESULT block, which, in this case, contains (surprise) a LIST. The room list contains all the available ROOMs, which by now only reveal a DESCription, beside the game name and the room id. The latter one is important to match the id of the GAME entries in the game list. Each game is identified by a PROTOCOL, which itself consists of the protocol engine and the protocol version. Both of these must actually match the one of the game client in order to be able to play. A game DESCription is also sent, along with the number of ALLOWed players and bots, and further information ABOUT the game.

<RESULT ACTION='list' CODE='0'>
<LIST TYPE='room'>
<ROOM ID='0' NAME='Entry Room' GAME='-1'>
<DESC>A place to meet and choose a game room</DESC>
</ROOM>
<ROOM ID='1' NAME='Chess' GAME='0'>
<DESC>Example Chess Room</DESC>
</ROOM>
</LIST>
...
</RESULT>


<RESULT ACTION='list' CODE='0'>
<LIST TYPE='game'>
<GAME ID='0' NAME='Chess' VERSION='0.0.6'>
<PROTOCOL ENGINE='Chess' VERSION='2'/>
<ALLOW PLAYERS='2' BOTS='0'/>
<ABOUT AUTHOR='Ismael Orenstein' URL='http://ggz.sourceforge.net/games/chess/'/>
<DESC>GGZ game module for playing Chess</DESC>
</GAME>
</LIST>
...
</RESULT>


The game client is now ready to ENTER one room. It will then show up in the player list of every GGZ client, so GGZ Instant Gaming should not use well-known public servers. However, for the beginning, it is sufficient to add a signature like '/xxx' to the player name (which is allowed to be 16 chars long), just like GGZap does with appending '/zap'.

<ENTER ROOM='0'/>


In the example, we entered the first room, which is usually the lounge. Success is indicated by the RESULT. The lounge doesn't have a game associated with it, and entering it invokes a server CHAT message.

<RESULT ACTION='enter' CODE='0'/>
<CHAT TYPE='private' FROM='[Server]'>
<![CDATA[You are the only player currently logged in.]]>
</CHAT>


We are then, maybe, interested in a LIST of players currently logged in, and of all the launched tables. Each table represents one running game, and has the players on it which take part in this game. Note that most games won't enter the lounge, but rather go to their room directly. For documentation purpose we will however handle this here.

<LIST TYPE='player'/>
<LIST TYPE='table'/>


Now the server lets us know the RESULT of our query. It sends a LIST of PLAYER s, and an empty list for the tables, which would contain a bunch of TABLEs if there were some running games.

<RESULT ACTION='list' CODE='0'>
<LIST TYPE='player' ROOM='0'>
<PLAYER ID='josef' TYPE='guest' TABLE='-1' LAG='1'/>
</LIST>
</RESULT>


<RESULT ACTION='list' CODE='0'>
<LIST TYPE='table' ROOM='0'>
</LIST>
</RESULT>


Now, the game client ENTERs a room which contains its game type. The server reply is similar to the one above, and has therefore been cut here. Instead, one of the few cases where a server initiates a part of the communication can occur everytime during the login: A PING ...

<PING/>


... which must be answered with a PONG immideately. The player lag calculation takes the time difference as its base, and it may very well be that in the future players with a too high lag are logged out.

<PONG/>


So much for the prerequesites. If this is done, the game client may start a game. It does so by issuing a LAUNCH command, which should create a TABLE. (Technically, the game is then started automatically on the server side.) A table may contain a DESCription, which is empty in the example, and a chain of SEAT tags, each of them telling about a certain seat. In the beginning they're all empty.

<LAUNCH>
<TABLE GAME='12' SEATS='2'>
<DESC></DESC>
<SEAT NUM='0' TYPE='open'/>
<SEAT NUM='1' TYPE='open'/>
</TABLE>
</LAUNCH>


The table launch is then broadcasted to all clients, including the one which issued it. This information gets delivered to the clients by an UPDATE bock, which contains the TABLE, holding all the SEATs. The player itself is placed into the first open seat. This too is broadcasted with an UPDATE tag, which specifies the TABLE in question, and the SEAT of the player. All other seats can either be open too, which means the game is not full yet, or a bot, or a seat reserved for a specific player. Before the player gets his seat, however, the game was launched, and this is indicated with the RESULT tag between the other events.

<UPDATE TYPE='table' ACTION='add' ROOM='13'>
<TABLE ID='0' GAME='12' STATUS='1' SEATS='2'>
<DESC></DESC>
<SEAT NUM='0' TYPE='open'/>
<SEAT NUM='1' TYPE='open'/>
</TABLE>
</UPDATE>


<RESULT ACTION='launch' CODE='0'/>
<UPDATE TYPE='table' ACTION='join' ROOM='13'>
<TABLE ID='0' SEATS='2'>
<SEAT NUM='0' TYPE='player'>josef</SEAT>
</TABLE>
</UPDATE>


If a player tries to get into a game, a game server could still refuse him, so a RESULT is also generated for this event. Again, a code zero means success.

<RESULT ACTION='join' CODE='0'/>


Upon start, either the game server or the game client sends out initial data. This is either tunneled by GGZ using a DATA tag containing some XML CDATA, or exchanged directly by the game client and server, whatever method is implemented.

<DATA SIZE='21'>
<![CDATA[0 0 0 17 75 68 69 32 77 117 101 104 108 101 32 71 97 109 101 10 0 ]]>
</DATA>


That's it. A game could be running in this state. In order to leave, simply disconnecting is enough, the GGZ server does then take care of everything. If there are any open questions, feel free to mail the author at dr_maux@users.sourceforge.net, or subscribe to the GGZ Gaming Zone developer's list, which is ggz-dev@lists.sourceforge.net.