Volity::Bot - A framework for creating automated Volity players
See Volity::Bot::TicTacToe::Random and its source code for a simple but full-featured example.
This class provides a framework for writing Volity bots in Perl. A bot is a program that acts like a human game player. Most bots are servants of game parlors, and are instanced when a human at a table asks the referee there to create one.
To write your own bot,
create a subclass of
The base class takes care of a lot of things that all bots need to do,
including awareness of the table and reacting to players dragging it into seats (or pushing it out of them).
All you need to do in your subclass is write logic specific to the game that you wish your bot to play. This comes down to defining callback methods that capture incoming RPCs from the table's referee, and deciding which RPC calls back to the referee that the bot should make in response.
You put your subclass into use by configuring the
volityd program to use it as its bot class; see volityd.
This will have referees spawned under that game parlor to instance your bot subclass whenever players request bots to play against.
You won't work with these bot objects directly; they are entirely callback-driven.
Some things to keep in mind when creating your subclass...
The object that results from your class will be a Perl pseudohash that makes use of the
(See fields.) As the example shows,
you should declare the the instance variables you intend to use with a
use fields() invocation.
Volity::Bot base class constructor calls
initialize() as a final step,
and you are welcome to override this in order to give your object some final preparations before sending it out into the world.
If you do override this method,
it must have a return value of
$self->SUPER::initialize(@_) or untold chaos will result.
Called with an argument, each of these class methods sets some information about the bot. Your subclass should, at the very least, define its algorithm URI, but it's not a fatal error to leave it blank.
The Frivolity framework substitutes generic default values if you don't assign values to these fields yourself.
A name for this bot. It will appear under this name at the game table. (Multiple instances of the same bot will give themselves this name followed by a number.)
A brief description of this bot.
This bot's algorithm URI.
These methods take no arguments, and return bits of information about the bot's place in the world. You can call them from within any of your callback methods.
The Jabber ID of the MUC where the bot finds itself.
The Jabber ID of the referee at the bot's table.
The bot's nickname at this table.
Returns truth if the bot is seated; falsehood otherwise.
Returns truth if the bot is seated and ready to play, falsehood otherwise.
A hash containing mappings of seat_id to lists of sitting player jids. Presently most useful to obtain a list of occupied seats with the keys function
Returns the ID of the seat where the bot current finds itself, if it is sitting down.
Note for backwards compatibility,
seat() method returns the same value.
It does not return a
only a string.
Makes an RPC call to the table's referee.
It automatically puts it into the "game." namespace for you.
to call the ruleset's
location ) RPC,
you'd call in your Perl code
$self-send_game_rpc_to_referee ( "move_piece",
Note that you should define a separate callback method for every distinct RPC call that your bot class can make. See "RPC Response callbacks". In fact, the base class will log a warning if you don't have such a callback set up for an RPC you call with this method.
Your bot should define a callback method for every Referee-to-player API defined by the game's ruleset document.
The name of the callback method will be exacty the same as the name of the RPC, except with the "game." prefix replaced by "game_rpc_".
The arguments to this method will simply be the arguments of the orginal RPC.
game.player_moved_piece would trigger the method
location ) in your subclass,
called with the arguments
No particular return value, at either the Perl or the RPC level, is expected, so don't worry about that too much.
You should define a response callback method for each distinct ruleset-defined method that your bot could call on the referee. This lets you check the referee's response to your bot's RPC and check its value.
There's always a chance that the referee will return something you didn't expect, even when both your bot and the referee are working just fine. Your bot should be able to recognize these sorts of exceptions and handle them gracefully.
When you make an RPC call to the referee through the
send_game_rpc_to_referee() method (described above),
the Bot base class sets up a callback trigger.
When it receives a response from the referee,
it will call an object object named after the method,
game. namespace replaced with
the response to the RPC call
game.move_piece() would trigger your callback method
The base class will log a warning whenever you call
send_game_rpc_to_referee() but don't have an appropriate response callback method set up.
For basic bot behavior,
the methods described above should suffice.
if you want to add more sophisticated automation and fine-grained handlers to your bot,
Volity::Bot is a sublcass of
so all the methods and techniques described in Volity::Jabber can be used with your bot subclass.
Jason McIntosh <firstname.lastname@example.org>
Copyright (c) 2006 by Jason McIntosh.