GGZ Gaming Zone Design Specification | |||
---|---|---|---|
<<< Previous Page | Home | Next Page >>> |
Warning |
This chapter is horribly out of date. We will be fixing it soon |
Main GGZ server (called ggzd)
Individual game servers
Run-time config utility programs
Meta server
We will discuss each of these in turn, but first we'll look at the overall architecture.
The GGZ server will handle incoming connections, manage the user database, and keep track of all of the games being played (referred to as game tables). Clients are always in direct communication with control.Note that ggzd will not handle the specifics of how to play any particular game. That logic is contained in the individual game servers. It is expected (and hoped!) that game developers will write their own games servers for use with GGZ. GGZ will attempt to provide a simple framework for writing network games in which developers need not worry about connections or user logins or maintaining statistics. All of that will be done by GGZ. Game developers should only have to concern themselves with gameplay.
The third item is more loosely connected. We will provide some sort of run-time configuration utilities for GGZ, so the main server will not have to be restarted (or worse.. recompiled!) in order for various options to be changed. The first such utily is ggzduedit, with which the user database can be edited.
Some options may include:
Location of game servers
Set auto removal of inactive users
Set inactivity threshold
Set auto clearing of statistics
Set clearing interval
Log level (level of detail in server logs)
This is the main brain for the server side of GGZ. It handles client logins and new user registrations. It manages option negotiation with the clients, and launches new game sessions. It maintains a list of running game sessions and keeps a database of win/lose statistics for each user. It coordinates games, users, and databases, and is responsible for interacting with the client, the running games, and the config utility.
Several possible designs were being considered before settling on the current one. It is possible that as GGZ develops this design will change as well. Since ggzd must communicate with multiple parties (game tables, users, etc.) it was decided to use a multi-threaded concurrent server where each connection (be it user or game table) gets its own thread. This avoids the situation where ggzd is servicing a request and therefore cannot handle any incoming connections or other requests. Brent chose threads rather than forking child processes because threads have a smaller overhead and it is easier to share memory between threads than between processes.
Every time a new user connects, ggzd creates a new thread to handle all requests for that user. This thread is known as the player handler. If the user decides to launch a new game table, the player handler creates a thread to handle all requests from the game table. This new thread is known as the table handler. The table handler waits until enough players have joined the table and then forks a process, known as the game table process, in which to run the game server. (The reason game servers are not run within a thread is so that game developers not be required to worry about writing thread-safe code.)
During the course of the game, the player thread for each player acts as a liaison between the player and the game table, passing requests back and forth transparent to the player and the game server. When a player logs out, the player handler thread is destroyed.
Quite a few game servers will be provided with GGZ, but it is hoped that others will write game modules, and either submit them for inclusion in the GGZ package, or maintain and distribute them separately. The following API describes how ggzd will interact with the game processes.
Note: All interaction is enclosed within the ggzdmod library. Game developers should use it (or any of its wrappers) so they don't have to deal with the protocol in use directly.
Four types of data are exchanged between ggzd and game servers:
chr: a 1-byte signed char
int: a 4-byte signed integer in network byte order
str: a multibyte null-terminated string preceded by its length (including null-termination) as an integer.
fd: a file descriptor passed via sendmsg() along with a single byte of dummy data
The following is a complete list of messages between the game module and the control section of the server. Again, I have chosen to intersperse game module requests with the corresponding control responses.
Please note: the following is not written stone, merely a list of ideas.
REQ_GAME_LAUNCH int: number of seats at table sequence of int: seat assignment (-1 for OPEN, -2 for COMP, -3 RESV) str: name of player (if assignment >=0 or == RESV) fd: file dscriptor of player (if assignment >= 0) RSP_GAME_LAUNCH chr: success flag (0 if OK, -1 if error) REQ_GAME_JOIN int: seat number str: name of player fd: file dscriptor of player RSP_GAME_JOIN chr: success flag (0 if OK, -1 if error) REQ_GAME_LEAVE str: name of player RSP_GAME_LEAVE chr: success flag (0 if OK, -1 if error) MSG_GAME_OVER int: number of statistics sequence of int: player index int: number of games won int: number of games lost MSG_LOG int: log level mask str: log message MSG_DBG int: debug level mask str: debug message |
Since the server runs non-interactively in the background, there needs to be some run-time configuration tools so that server options may be changed without restarting. Updates are either executed indirectly (e.g. when removing a player from the database), or explicitely (e.g. when changing some configuration parameters and sending a hangup signal to ggzd). The latter one will be steered by a configuration utily as well at some point.
Messages between ggzd and the config utilities might include:
Request available game types (loaded modules)
Add/Remove Game types
Remove users
Request list of active games
Clear Player statistics
Modify logging