This is a documentation for Board Game Arena: play board games online !

Your game state machine: states.inc.php: Perbedaan antara revisi

Dari Board Game Arena
Loncat ke navigasi Loncat ke pencarian
(→‎args: argPlayerTurn instead argPlaceWorker :))
 
(13 revisi perantara oleh 3 pengguna tidak ditampilkan)
Baris 47: Baris 47:


ID=99 is reserved for the last game state of the game (end of the game) (and you must not modify it).
ID=99 is reserved for the last game state of the game (end of the game) (and you must not modify it).
Note: you may use any ID, even ID greater than 100. But you cannot use 1 and 99.
Note²: You can't of course use the same ID twice.


=== name ===
=== name ===
Baris 82: Baris 86:
                 break;
                 break;
</pre>
</pre>
=== type ===
(mandatory)
You can use 3 types of game states:
* activeplayer (1 player is active and must play)
* multipleactiveplayer (1..N players can be active and must play)
* game (no player is active. This is a transitional state to do something automatic specified by game rules)


=== description ===
=== description ===
Baris 97: Baris 110:
In the description string, you can use ${actplayer} to refer to the active player.
In the description string, you can use ${actplayer} to refer to the active player.


You can also use custom arguments in your description. These custom arguments correspond to values returned by your "arg" PHP method (see below "arg" field).
You can also use custom arguments in your description. These custom arguments correspond to values returned by your "args" PHP method (see below "args" field).


Example of custom field:
Example of custom field:
Baris 104: Baris 117:
In states.inc.php:
In states.inc.php:
         "description" => clienttranslate('${actplayer} must choose ${nbr} identical energies'),
         "description" => clienttranslate('${actplayer} must choose ${nbr} identical energies'),
         "arg" => "argMyArgumentMethod"
         "args" => "argMyArgumentMethod"


In mygame.game.php:
In mygame.game.php:
Baris 119: Baris 132:
Note²: Usually, you specify a string for "activeplayer" and "multipleactiveplayer" game states, and you specify an empty string for "game" game states. BUT, if you are using synchronous notifications, the client can remains few seconds on a "game" type game state, and in this case this may be useful to display a description in the status bar during this state.
Note²: Usually, you specify a string for "activeplayer" and "multipleactiveplayer" game states, and you specify an empty string for "game" game states. BUT, if you are using synchronous notifications, the client can remains few seconds on a "game" type game state, and in this case this may be useful to display a description in the status bar during this state.


== descriptionmyturn ==
=== descriptionmyturn ===


(mandatory for "activeplayer" and "multipleactiveplayer" game states type)
(mandatory for "activeplayer" and "multipleactiveplayer" game states type)
Baris 133: Baris 146:


Note: you can use ${you} in description my turn in order the description can display "You" instead of the name of the player.
Note: you can use ${you} in description my turn in order the description can display "You" instead of the name of the player.
=== action ===
(mandatory for "game" game state type)
"action" specify a PHP method to call when entering into this game state.
Example:
<pre>
In states.inc.php:
    28 => array(
        "name" => "startPlayerTurn",
        "description" => '',
        "type" => "game",
        "action" => "stStartPlayerTurn",
In mygame.game.php:
    function stStartPlayerTurn()
    { 
        // ... do something at the beginning of this game state
</pre>
Usually, for "game" game state type, the action method is used to do some automatic stuff specified by the rules (ex: check victory conditions, deal cards for a new round, go to the next player...) and then jump to another game state.
Note: a BGA convention specify that PHP method called with "action" are prefixed by "st".
=== transitions ===
(mandatory)
With "transition" you specify in which game state you can jump from a given game state.
Example:
<pre>
    25 => array(
        "name" => "myGameState",
        "transitions" => array( "nextPlayer" => 27, "endRound" => 39 ),
        ....
    }
</pre>
In the example above, if "myGameState" is the current active game state, I can jump to game state with ID 27, or game state with ID 39.
Example to jump to ID 27:
<pre>
In mygame.game.php:
    $this->gamestate->nextState( "nextPlayer" );
</pre>
Important: "nextPlayer" is the name of the transition, and NOT the name of the target game state. Several transitions can lead to the same game state.
Note: if you have only 1 transition, you may give it an empty name.
Example:
<pre>
In states.inc.php:
    "transitions" => array( "" => 27 ),
In mygame.game.php:
    $this->gamestate->nextState(  );    // We don't need to specify a transition as there is only one here
</pre>
=== possibleactions ===
(mandatory for "activeplayer" and "multipleactiveplayer" game states)
"possibleactions" defines the actions possible by the players at this game state.
By defining "possibleactions", you make sure players can't do actions that they are not allowed to do at this game states.
Example:
<pre>
In states.game.php:
      "possibleactions" => array( "playCard", "pass" ),
In mygame.game.php:
        function playCard( ...)
        {
            self::checkAction( "playCard" );    // Will failed if "playCard" is not specified in "possibleactions" in current game state.
            ....
In mygame.js:
        playCard: function( ... )
        {
            if( this.checkAction( "playCard" ) ) // Will failed if "playCard" is not specified in "possibleactions" in current game state.
            {  return ;  }
            ....
</pre>
=== args ===
(optional)
From time to time, it happens that you need some information on the client side (ie : for your game interface) only for a specific game state.
Example 1 : for Reversi, the list of possible moves during playerTurn state.
Example 2 : in Caylus, the number of remaining king's favor to choose in the state where the player is choosing a favor.
Example 3 : in Can't stop, the list of possible die combination to be displayed to the active player in order he can choose among them.
In such a situation, you can specify a method name as the « args » argument for your game state. This method must get some piece of information about the game (ex : for Reversi, the possible moves) and return them.
Thus, this data can be transmitted to the clients and used by the clients to display it. It should always be an associative array.
Let's see a complete example using args with « Reversi » game :
In states.inc.php, we specify some « args » argument for gamestate « playerTurn » :
<pre>
    10 => array(
        "name" => "playerTurn",
"description" => clienttranslate('${actplayer} must play a disc'),
"descriptionmyturn" => clienttranslate('${you} must play a disc'),
        "type" => "activeplayer",
        "args" => "argPlayerTurn",    <================================== HERE
        "possibleactions" => array( 'playDisc' ),
        "transitions" => array( "playDisc" => 11, "zombiePass" => 11 )
    ),
</pre>
It corresponds to a « argPlayerTurn » method in our PHP code (reversi.game.php):
<pre>
    function argPlayerTurn()
    {
        return array(
            'possibleMoves' => self::getPossibleMoves()
        );
    }
</pre>
Then, when we enter into « playerTurn » game state on the client side, we can highlight the possible moves on the board using information returned by argPlayerTurn :
<pre>
        onEnteringState: function( stateName, args )
        {
          console.log( 'Entering state: '+stateName );
           
            switch( stateName )
            {
            case 'playerTurn':
                this.updatePossibleMoves( args.args.possibleMoves );
                break;
            }
        },
</pre>
Note: you can also used values returned by your "args" method to have some custom values in your "description"/"descriptionmyturn" (see above).
Note: as a BGA convention, PHP methods called with "args" are prefixed by "arg" (ex: argPlayerTurn).
=== updateGameProgression ===
(optional)
IF you specify "updateGameProgression => true" in a game state, your "getGameProgression" PHP method will be called at the beginning of this game state - and thus the game progression of the game will be updated.
At least one of your game state (any of them) must specify updateGameProgression=>true.

Revisi terkini sejak 5 Mei 2013 22.14

This file describes the game states machine of your game (all the game states properties, and the transitions to get from one state to another).

Important: to understand the game state machine, the best is to read this presentation first:

Focus on BGA game state machine

Overall structure

The machine states is described by a PHP associative array.

Example:

$machinestates = array(

    // The initial state. Please do not modify.
    1 => array(
        "name" => "gameSetup",
        "description" => clienttranslate("Game setup"),
        "type" => "manager",
        "action" => "stGameSetup",
        "transitions" => array( "" => 2 )
    ),
    
    // Note: ID=2 => your first state

    2 => array(
    		"name" => "playerTurn",
    		"description" => clienttranslate('${actplayer} must play a card or pass'),
    		"descriptionmyturn" => clienttranslate('${you} must play a card or pass'),
    		"type" => "activeplayer",
    		"possibleactions" => array( "playCard", "pass" ),
    		"transitions" => array( "playCard" => 2, "pass" => 2 )
    ),

Syntax

id

The keys determine game states IDs (in the example above: 1 and 2).

IDs must be positive integers.

ID=1 is reserved for the first game state and should not be used (and you must not modify it).

ID=99 is reserved for the last game state of the game (end of the game) (and you must not modify it).

Note: you may use any ID, even ID greater than 100. But you cannot use 1 and 99.

Note²: You can't of course use the same ID twice.

name

(mandatory)

The name of a game state is used to identify it in your game logic.

Several game states can share the same name, however this is not recommended.

PHP example:


// Get current game state
$state = $this->gamestate->state();
if( $state['name'] == 'myGameState' )
{
...
}

JS example:

        onEnteringState: function( stateName, args )
        {
            console.log( 'Entering state: '+stateName );
            
            switch( stateName )
            case 'myGameState':
            
                // Do some stuff at the beginning at this game state
                ....
                
                break;

type

(mandatory)

You can use 3 types of game states:

  • activeplayer (1 player is active and must play)
  • multipleactiveplayer (1..N players can be active and must play)
  • game (no player is active. This is a transitional state to do something automatic specified by game rules)

description

(mandatory)

The description is the string that is displayed in the main action bar (top of the screen) when the state is active.

When a string is specified as a description, you must use "clienttranslate" in order the string can be translate on the client side:

 		"description" => clienttranslate('${actplayer} must play a card or pass'),

In the description string, you can use ${actplayer} to refer to the active player.

You can also use custom arguments in your description. These custom arguments correspond to values returned by your "args" PHP method (see below "args" field).

Example of custom field:


In states.inc.php:
        "description" => clienttranslate('${actplayer} must choose ${nbr} identical energies'),
        "args" => "argMyArgumentMethod"

In mygame.game.php:
    function argMyArgumentMethod()
    {
        return array(
            'nbr' => 2  // In this case ${nbr} in the description will be replaced by "2"
        );    
    }

Note: You may specify an empty string ("") here if it never happens that the game remains in this state (ie: if this state immediately jump to another state when activated).

Note²: Usually, you specify a string for "activeplayer" and "multipleactiveplayer" game states, and you specify an empty string for "game" game states. BUT, if you are using synchronous notifications, the client can remains few seconds on a "game" type game state, and in this case this may be useful to display a description in the status bar during this state.

descriptionmyturn

(mandatory for "activeplayer" and "multipleactiveplayer" game states type)

"descriptionmyturn" has exactly the same role and properties than "description", except that this value is displayed to the current active player - or to all active players in case of a multipleactiveplayer game state.

In general, we have this situation:

        "description" => clienttranslate('${actplayer} can take some actions'),
        "descriptionmyturn" => clienttranslate('${you} can take some actions'),

Note: you can use ${you} in description my turn in order the description can display "You" instead of the name of the player.

action

(mandatory for "game" game state type)

"action" specify a PHP method to call when entering into this game state.

Example:

In states.inc.php:
    28 => array(
        "name" => "startPlayerTurn",
        "description" => '',
        "type" => "game",
        "action" => "stStartPlayerTurn",

In mygame.game.php:
    function stStartPlayerTurn()
    {   
        // ... do something at the beginning of this game state

Usually, for "game" game state type, the action method is used to do some automatic stuff specified by the rules (ex: check victory conditions, deal cards for a new round, go to the next player...) and then jump to another game state.

Note: a BGA convention specify that PHP method called with "action" are prefixed by "st".

transitions

(mandatory)

With "transition" you specify in which game state you can jump from a given game state.

Example:

    25 => array(
        "name" => "myGameState",
        "transitions" => array( "nextPlayer" => 27, "endRound" => 39 ),
        ....
    }

In the example above, if "myGameState" is the current active game state, I can jump to game state with ID 27, or game state with ID 39.

Example to jump to ID 27:

In mygame.game.php:
    $this->gamestate->nextState( "nextPlayer" );

Important: "nextPlayer" is the name of the transition, and NOT the name of the target game state. Several transitions can lead to the same game state.

Note: if you have only 1 transition, you may give it an empty name.

Example:

In states.inc.php:
    "transitions" => array( "" => 27 ),

In mygame.game.php:
    $this->gamestate->nextState(  );     // We don't need to specify a transition as there is only one here


possibleactions

(mandatory for "activeplayer" and "multipleactiveplayer" game states)

"possibleactions" defines the actions possible by the players at this game state.

By defining "possibleactions", you make sure players can't do actions that they are not allowed to do at this game states.

Example:

In states.game.php:
       	"possibleactions" => array( "playCard", "pass" ),

In mygame.game.php:
        function playCard( ...)
        {
             self::checkAction( "playCard" );    // Will failed if "playCard" is not specified in "possibleactions" in current game state.

            ....

In mygame.js:
        playCard: function( ... )
        {
            if( this.checkAction( "playCard" ) ) // Will failed if "playCard" is not specified in "possibleactions" in current game state.
            {  return ;   }

            ....

args

(optional)

From time to time, it happens that you need some information on the client side (ie : for your game interface) only for a specific game state.

Example 1 : for Reversi, the list of possible moves during playerTurn state. Example 2 : in Caylus, the number of remaining king's favor to choose in the state where the player is choosing a favor. Example 3 : in Can't stop, the list of possible die combination to be displayed to the active player in order he can choose among them.

In such a situation, you can specify a method name as the « args » argument for your game state. This method must get some piece of information about the game (ex : for Reversi, the possible moves) and return them.

Thus, this data can be transmitted to the clients and used by the clients to display it. It should always be an associative array.

Let's see a complete example using args with « Reversi » game :

In states.inc.php, we specify some « args » argument for gamestate « playerTurn » :

    10 => array(
        "name" => "playerTurn",
		"description" => clienttranslate('${actplayer} must play a disc'),
		"descriptionmyturn" => clienttranslate('${you} must play a disc'),
        "type" => "activeplayer",
        "args" => "argPlayerTurn",    <================================== HERE
        "possibleactions" => array( 'playDisc' ),
        "transitions" => array( "playDisc" => 11, "zombiePass" => 11 )
    ),

It corresponds to a « argPlayerTurn » method in our PHP code (reversi.game.php):

    function argPlayerTurn()
    {
        return array(
            'possibleMoves' => self::getPossibleMoves()
        );
    }

Then, when we enter into « playerTurn » game state on the client side, we can highlight the possible moves on the board using information returned by argPlayerTurn :

        onEnteringState: function( stateName, args )
        {
           console.log( 'Entering state: '+stateName );
            
            switch( stateName )
            {
            case 'playerTurn':
                this.updatePossibleMoves( args.args.possibleMoves );
                break;
            }
        },

Note: you can also used values returned by your "args" method to have some custom values in your "description"/"descriptionmyturn" (see above).

Note: as a BGA convention, PHP methods called with "args" are prefixed by "arg" (ex: argPlayerTurn).

updateGameProgression

(optional)

IF you specify "updateGameProgression => true" in a game state, your "getGameProgression" PHP method will be called at the beginning of this game state - and thus the game progression of the game will be updated.

At least one of your game state (any of them) must specify updateGameProgression=>true.