This project is to write the client/server message handling system for a multi-player card game where one or more players could be automated bots. The result of this phase of development would be a PERL module/object that can handle basic networking, event handling, data logging, etc. The actual specifics of a "game" will be abstracted.
Basic functionality:
1. Game server
For this phase, the game server can be a multi-threaded (e.g., non-blocking)
single process that coordinates the human and bot players, maintains game
state, and checks game move validity. Care is needed to ensure that the
server is robust against crashes or hacks/overloads. Error and exception
handling as well as restarting in the even of a crash. Server should
be able to recognize and handle hung or poorly behaving clients.
2. Client
Each client will be it's own process either on the same computer as
the game server or remote.
Game play
It is expected that a human or bot player may initiate a game by
contacting the server telling it the type of game, number of players,
how many are human/bot. The server will either wait until it get
enough human players or spawn off bot clients to fill the open seats.
For now, all games will be turned based - that is, the server will ask
each player in turn what they will do and notify all players what is
being asked and the result of the players turn based on the game
rules. Each client will get a stream of text of move updates from
other players until get a blocking message with a decision request.
Each call from the client will be checked for validity. Process
continues until winner is determined, then stats get updated and
system prepares for a new game.
More details in the attachment...
## Deliverables
Goal: Create a PERL client-server architecture for text-based games
While I want to be forward looking in terms of abstracting the client/server
architecture, the first external implementation will be for a multi-player
card game where one or more players could be automated bots. The result of
this phase of development would be a PERL module/object that can handle basic
networking, event handling, data logging, etc. The actual specifics of a
"game" will be abstracted.
Bots and players will have a database (MYSQL) record with basic
bio (e.g., name/password) and results of games can be saved as well.
At this point, I am open to suggestions as to having game state, open game
info, etc stored in memory by the game server or database.
Miscellaneous: I would like to use this project as a learning process
so I would like to be involved with the incremental develop along with
the developer (e.g., daily code testing/etc). I have considerable
PERL experience but am weaker in network/socket implementations.
Code style: I tend to have a compressed C++-like PERL format style,
prefer sending arguments as hash pointer e.g., $self->foo({a=>1,b=>2})
and then have
sub foo { # food returns alpha * beta
my $self=shift;
my $args=shift
my $a=$$args{a}; # this is the alpha level
my $b=$$args{b}; # each variable gets a comment
return $a*$b;
}
Let's define an agreed upon coding style fairly early so that it's
less work later :)
Basic functionality:
1. Game server
For this phase, the game server can be a multi-threaded (e.g., non-blocking)
single process that coordinates the human and bot players, maintains game
state, and checks game move validity. Care is needed to ensure that the
server is robust against crashes or hacks/overloads. Error and exception
handling as well as restarting in the even of a crash. Server should
be able to recognize and handle hung or poorly behaving clients.
2. Client
Each client will be it's own process either on the same computer as
the game server or remote.
Game play
It is expected that a human or bot player may initiate a game by
contacting the server telling it the type of game, number of players,
how many are human/bot. The server will either wait until it get
enough human players or spawn off bot clients to fill the open seats.
For now, all games will be turned based - that is, the server will ask
each player in turn what they will do and notify all players what is
being asked and the result of the players turn based on the game
rules. Each client will get a stream of text of move updates from
other players until get a blocking message with a decision request.
Each call from the client will be checked for validity. Process
continues until winner is determined, then stats get updated and
system prepares for a new game.
Possible commands
Note: names and functionality can change based on developer feedback.
C: means sent by client, S: sent by server. All commands are blocking
unless ends with NB (e.g., CNB, SNB). Possibly have the return info
always have the name of the command being asked?
C:create_new_game - initiates a game
args: player_id, game_type, n_seats, n_bot|0 (n_ = number_)
returns: game_id
errors: unable to play game_type
C:show_open_games - shows games with open seats (positions)
args: order (create_time, n_human, n_bots, skill_number, etc)
since (timestamp, game_id)
returns: timestamp of query (lets us ask for updates later)
open game info (game id, # players, who, bot/human, seats
open, skill, etc)
errors: no games available
SNB:game_notice - generic message about game used for things
like "player 3 just did X" or "waiting on player 2 to respond" but
in a format for the client program and/or human to parse.
args: game_id, notice_type, value... format/syntax probably some
sort of hash with lots of options.
returns: either an acknowledgment or none
errors: none?
SNB:move_request - basic saying "give me some text/data"
args: game_id, move_type, value... similar to game_notice
returns: either an acknowledgment or none
errors: none?
C:move - sends move info,
args: game_id, move_type, value... similar to game_notice
returns: either an acknowledgment or none
errors: none?
C:spawn_bot_games - tells server to play a number of bot games
args: game_type, n_players, n_games, n_simultaneous
Possible phase2 or redundant/helper commands
C:show_my_games - returns list of games I'm currently in, played before (phase 2?)
C:show_game_players(game_id) - returns info on players in a game (redundant?)
Database
A simple MYSQL database will be used to store results. Here is a first
try at schemas for it.
# record for each human player regardless of which games they play
user (id, username[varchar], fname[varchar], lname[varchar], email[varchar],
password[varchar], create_time)
# description of games
games (id, type[varchar], description[blob], min_players, max_players,
has_callable_bots[1/0], )
# info to enable a server to call a bot
game_bots (id, game_type, name, url, port)
# details of every attempted game
matches (id, game_type[varchar], start_time, finish_time, success_end[1/0]
game_type[varchar], winner_id[int])
# who played in each match
match_players(game_id, user_id)
Simple game idea for testing:
For testing, we could code a game "Guess a number" when N players
take turn guessing a number that picked by the server. After each
guess, the server responds "too high", "too low" or "you guessed it!".
The first who guesses it wins. After the winner is picked, players are asked
if they wish to play again... if all do, then game is repeated otherwise
it ends. The results of each number guessing is stored in a database.
C:start_game({type=>'pick_number', pick_number_min=>1, pick_number_max=>1000,
n_players=>4,n_bot=>2,bot_type=>'hard,easy',
2 bots:
One 'easy' that always picks a random number
One 'hard' that always picks the int(min+max)
Deliverables:
PERL library for GameSystem (used by client/server)
[login to view URL] w/ [login to view URL] library (used by human)
[login to view URL] w/ [login to view URL] library (to activate by server/SOAP?)
[login to view URL] w/ [login to view URL] library
MYSQL table definitions
[login to view URL] (loads in tables and inserts initial game/users)