Referee

A Volity referee is a Jabber entity that sits at every table, acting as the point of communication between a game and its players.

In fact, the referee is the game, to a great degree, since the current state of any table's game is known wholly by the referee, and it must describe the game individually to each player. It does this by sending Jabber-RPC requests to a player whenever the game state changes from that player's perspective; these requests, on receipt, trigger ECMAScript functions found within the UI file currently loaded on the player's client, which in turn causes something appropriate to happen before the player's eyes: the scoreboard is updated, or a card is dealt, or a piece is captured.

The referee is also the target of communication from the player to the game. For instance, a player's current UI might display a "Roll dice" button, or an animated image of the dice themselves, which, when clicked, send a game.roll_dice RPC request to the table's referee. Typically, the referee would respond by determining the die roll through its own internal methods, then sending to that player's client (or all players, if the roll isn't secret) another RPC request that confides the roll's result.

Referee as GM

Those familiar with tabletop roleplaying games, such as Dungeons & Dragons, might appreciate the metaphor comparing a Volity referee to a game master. It holds the whole game concept, and its current state, "in its head", and its the sole interface between the players and the game world, continually updating their current perspective on it. Players are free to talk to each other, but to make anything happen in the game world, they have to to talk to the referee, who lets them know what happens as a result.

Current Implementations

Frameworks that implement a referee (in Perl and Python) are available from the parlor and referee. The parlor's job is to create referees on demand.)

If you want to create a Volity game, you do not have to implement the entire referee from scratch. Download one of these frameworks, and then extend the base Game class to implement your game logic.

RPC Requests

The following faults can be generated by any referee method:

Since only clients call methods on referees, all return values for these methods take the flag-led array format described on the RPC replies page. Therefore, all return values listed in this section actually refer to array values that go after the "volity.ok" flag.

Possible non-fault errors are listed under separate "token.html" class=wikipagelink>tokens, as described (or not) in each case.

volity.add_bot ()

Requests that the referee add a retainer bot to the table. The response is a fault (with an explanatory message attached) if the referee cannot add a bot to the table right now. Otherwise, the response is the full JID of the bot which was created.

The bot is initially unseated; the players are responsible for seating it appropriately.

volity.add_bot ( URI, JID )

Same as above, but requests a specific bot -- that is, a bot with a specific bot algorithm URI -- from a specific factory. If JID is the empty string, the parlor JID, or the referee JID (all equivalent for this purpose) then the request is directed at the parlor itself. If not, the request is directed at an external bot factory.

volity.remove_bot ( JID )

Request that the referee remove the retainer bot with the given JID from the table. This only works on bots that were added with volity.add_bot(), and it only works if the bot is unseated. If the bot is managed by an external bot factory, this causes a volity.leave_table() call to the bot.

volity.ready ()

This method signals that the player who made this request accepts the current table configuration and is ready to begin playing a new game there. The referee will begin the game only when all the players have so signalled.

If the referee is unwilling to start a new game with the table's current setup, it will deny the request with one of the flags listed below. The player is effectively signaling approval for a game configuration that can't actually be played.

Otherwise, the referee will report the player's readiness to all players in the MUC, by sending volity.player_ready.

Any change in the table's configuration cancels any previously sent ready signals.

volity.unready ()

Signals that the sending player is not ready to begin playing, and thus delay the game from starting. This is mainly useful should the player change his or her mind after sending a volity.ready request. If the player is already unready, this does nothing.

If this succeeds, the referee will report it to all players in the MUC, by sending volity.player_unready.

volity.stand ( JID )

Requests the referee to remove the player with the given JID from his seat. Effectively, the player becomes an observer.

If the player is already standing, this succeeds and does nothing.

volity.sit ( JID )

This method is distinct from the argument-taking form described below.

Requests the referee to assign a seat to the player with the given JID. Usually, this is equivalent to wishing to join the game as a solitary player, rather than sharing a seat with existing players.

The player referred to by the JID will most often be the same as that of the sending user -- that is, this request will usually result from a player wishing to seat itself. However, a player that has tasked itself with setting up the table and assigning seats might make this call on behalf of another player, using that other player's JID. Referees must pay attention to the difference, but it is ultimately up to them how to respond to requests to seat other players.

If the referee decides that the named player can indeed sit down, its return value (after the required volity.ok token) is the ID of the new seat. The referee can use any method to select which of its empty seats the player should join, but it SHOULD favor any empty required seats over other empty seats.

If the player was already seated elsewhere, he is removed from that seat when he is placed in the new one. If he was already seated in the given seat, this does nothing (but still returns the seat ID).

volity.sit ( JID, seat-id )

This method is distinct from the non-argument-taking form described above.

Requests that the player with the given JID be seated in the seat with the given ID.

The player referred to by the JID will most often be the same as that of the sending user -- that is, this request will usually result from a player wishing to seat itself. However, a player that has tasked itself with setting up the table and assigning seats might make this call on behalf of another player, using that other player's JID. Referees must pay attention to the difference, but it is ultimately up to them how to respond to requests to seat other players.

If the referee decides that the named player can indeed sit down in that seat, its return value, is the ID of that seat (as with the non-argument-taking form of this method).

If the player is already seated, this does nothing (but still returns his seat ID).

volity.suspend_game ( )

Requests that the the referee suspend the game. Only seated players can succeed in calling this, and only when the game is active.

volity.send_state()

Requests the the referee send state recovery information to the player. Anyone at the table can call this, at any time.

The client also uses this to inform the referee that it is a Volity client, and not a mere Jabber client. Before the first volity.send_state() call, the referee will refrain from sending RPCs to the client. After that first state recovery blast, the referee will keep the client up to date with all game state changes.

volity.show_table ( true | false )

Requests that the table be available through the game browser (if the argument is true) or not (if the argument is false).

The default for new tables is true.

This is a table configuration request. The referee will accept it only prior to the start of a game. Changing this value will result in the referee setting all seated players to unready.

volity.record_games ( true | false )

Requests that the referee send game records to the bookkeeper at the end of each game (if the argument is 1) or not (if the argument is 0).

The default for new tables is true.

This is a table configuration request. The referee will accept it only prior to the start of a game. Changing this value will result in the referee setting all seated players to unready.

volity.set_language ( language )

Requests a change of the table's preferred language. The argument is a two-letter language code.

This is a table configuration request. The referee will accept it only prior to the start of a game. Changing this value will result in the referee setting all seated players to unready.

volity.kill_game ( true | false )

If the one argument is true, this special config method requests that the game be killed after all active players have indicated readiness.

If it's false, then it requests that the game play resume normally upon all players' readiness.

This is a table configuration request. The referee will accept it only when suspended. Changing this value will result in the referee setting all seated players to unready.

volity.invite_player ( JID )

Requests that the referee invite the player JID to join the table.

The referee responds by sending an invitation to the specified player. If the JID has a resource string, this will be an volity.receive_invitation RPC. If it lacks a resource string, it will be a <message> packet containing an invitation data form.

volity.invite_player ( JID, message )

Requests that the referee invite the player JID to join the table. The message is an additional string, containing a message from the inviter to the invitee.

The referee responds by sending an invitation to the specified player. If the JID has a resource string, this will be an volity.receive_invitation RPC. If it lacks a resource string, it will be a <message> packet containing an invitation data form.

Game RPCs

Note that all the above RPC requests lay in the volity namespace, marking them as systemwide methods. Another Volity RPC namespace, game, serves as the container for game-specific requests; that is, requests defined by a certain ruleset.

game.* RPCs never implicitly cause players to become unready. If the game configuration changes, the referee will send out a burst of volity.player_unready RPCs.

Administrative RPCs

The referee may also respond to various admin RPC requests.

Service Discovery responses

Referees should respond to disco requests as follows:

Info

The referee's identity should have category "zarf.html" class=wikipagelink>Zarf

The attached JEP-0128 form contains the following additional fields:

volity-role
The string referee.
parlor
The JID of this referee's parlor.
table
The JID of this referee's table (MUC).
state
One of the five referee state strings.
players
The number of occupied seats at the table.
max-players
How many seats this referee will allow.
language
The preferred human language for this table, expressed as a two-letter language code
recorded
1 if the referee is recording games on the bookkeeper; 0 otherwise.
visible
1 if the table is visible to the game finder; 0 otherwise.

Items

Empty list. However, sending a disco-items query to the table will result in a list of pointers to the players within (as well as the referee), just like any other Jabber MUC responds with a list of chat participants.