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

Zombie Mode: Difference between revisions

From Board Game Arena
Jump to navigation Jump to search
No edit summary
Line 44: Line 44:


<pre>
<pre>
     function zombieTurn( $state, $active_player )
     protected function zombieTurn(array $state, int $active_player): void
     {
     {
    $statename = $state['name'];
        $state_name = $state["name"];


         if( $statename == 'myFirstGameState'
         if ($state["type"] === "activeplayer") {
            ||  $statename == 'my2ndGameState'
            switch ($state_name) {
            ||  $statename == 'my3rdGameState'
                case 'state1':
              ....
                    $this->zombieTurn_state1($active_player);
          )
                    break;
        {
                case 'state2':
             $this->gamestate->nextState( "zombiePass" );
                    $this->zombieTurn_state2($active_player);
                    break;
                case 'state3':
                    $this->zombieTurn_state3($active_player);
                    break;
                }
                // ... handle all your states in the same fashion
            }
 
            return;
        }
 
        // Make sure player is in a non-blocking status for role turn.
        if ($state["type"] === "multipleactiveplayer") {
            // this example is a Zombie level 0, for let 1 or more, it would be similar to the examples for activeplayer state
             $this->gamestate->setPlayerNonMultiactive($active_player, '');
            return;
         }
         }
         else
 
            throw new BgaVisibleSystemException( "Zombie mode not supported at this game state: ".$statename );
         throw new \feException("Zombie mode not supported at this game state: \"{$state_name}\".");
    }
 
    protected function zombieTurn_state1(int $active_player): void
    {
        // example of Zombie level 0
        $this->gamestate->nextState("zombiePass"); // you need to declare this transition that will bring the player/bot to the next state.
    }
 
    protected function zombieTurn_state2(int $active_player): void
    {
        // example of Zombie level 1
        $args = $this->argState1();
        $possibleMoves = $args['possibleMoves'];
 
        $zombieChoice = $possibleMoves[bga_rand(0, count($possibleMoves) - 1)]; // random choice over possible moves
        return $this->actPlayState1Action($zombieChoice, $active_player);
    }
 
    protected function zombieTurn_state3(int $active_player): void
    {
        // example of Zombie level 2
        $this->gamestate->nextState("zombiePass"); // you need to declare this transition that will bring the player/bot to the next state.
     }
     }
</pre>
</pre>


Note that in the example above, all corresponding game state should implement "zombiePass" as a transition.
'''Very important''': your zombie code will be called when the player leaves the game. The server will handle the Zombie turn, so there is no current player associated to this action. In your zombieTurn function, you must '''never''' use getCurrentPlayerId() or getCurrentPlayerName(), but use $active_player id instead (or $this->getPlayerNameById($active_player) ).
 
'''Very important''': your zombie code will be called when the player leaves the game. This action is triggered from the main site and propagated to the gameserver from a server, not from a browser. As a consequence, there is no current player associated to this action. In your zombieTurn function, you must '''never''' use getCurrentPlayerId() or getCurrentPlayerName(), otherwise it will fail with a "Not logged" error message. Just use the $active_player id instead.


== Testing the Zombie mode ==
== Testing the Zombie mode ==

Revision as of 09:10, 4 September 2025


Game File Reference



Useful Components

Official

  • Deck: a PHP component to manage cards (deck, hands, picking cards, moving cards, shuffle deck, ...).
  • PlayerCounter and TableCounter: PHP components to manage counters.
  • Draggable: a JS component to manage drag'n'drop actions.
  • Counter: a JS component to manage a counter that can increase/decrease (ex: player's score).
  • ExpandableSection: a JS component to manage a rectangular block of HTML than can be displayed/hidden.
  • Scrollmap: a JS component to manage a scrollable game area (useful when the game area can be infinite. Examples: Saboteur or Takenoko games).
  • Stock: a JS component to manage and display a set of game elements displayed at a position.
  • Zone: a JS component to manage a zone of the board where several game elements can come and leave, but should be well displayed together (See for example: token's places at Can't Stop).
  • bga-animations : a JS component for animations.
  • bga-cards : a JS component for cards.
  • bga-dice : a JS component for dice.
  • bga-autofit : a JS component to make text fit on a fixed size div.
  • bga-score-sheet : a JS component to help you display an animated score sheet at the end of the game.

Unofficial



Game Development Process



Guides for Common Topics



Miscellaneous Resources

What is the Zombie mode

When a player leaves a game for any reason (being expelled out of time or quitting the game), he becomes a "zombie player". In this case, the results of the game won't count for statistics, but we must let the other players finish the game anyway. That's why zombie mode exists: allow the other player to finish the game, against the Zombie (a bot) that replaces the leaver player.

The different Zombie levels

Level 0: the passing zombie
Just pass to the next step without doing any action
For example, in 7 wonders, take a random card and discard it (we cannot just pass in this game as it would mess with the next player hand)
Level 1: the random zombie
Code a random possible action
For example, in 7 wonders, take a random card and play it
Level 2: the simple zombie
Take the action that will bring the most value given the visible information. Isn't planning for future move, nor remember previously known information. Does not try to take a lower value in order to block the opponent.
For example, in 7 wonders, take a card that will bring the most points to the players. If there is a tie, the one that will cost less. If there is still a tie, randomly in the subset
Level 3: the smart zombie
Can plan and/or remember previously revealed information.
For example, in 7 wonders, it could remember which cards could be back in the next turn to make the best move.


Ideally, aim for level 1 or 2 for your implementation.

While developing your zombie mode, keep in mind that:

  • Do not refer to the rules, because this situation is not planned by the rules.
  • Try to figure that you are playing with your friends and one of them has to leave: how can we finish the game without killing the spirit of the game?
  • The idea is NOT to develop an artificial intelligence for the game.
  • Do not try to end the game early, even in a two-player game. The zombie is there to allow the game to continue, not to end it.

Implementing the Zombie mode

Each time a zombie player must play, your "zombieTurn" method is called.

Parameters:

  • $state: the current game state.
  • $active_player: the id of the active player.

Most of the time, your zombieTurn method looks like this:

    protected function zombieTurn(array $state, int $active_player): void
    {
        $state_name = $state["name"];

        if ($state["type"] === "activeplayer") {
            switch ($state_name) {
                case 'state1':
                    $this->zombieTurn_state1($active_player);
                    break;
                case 'state2':
                    $this->zombieTurn_state2($active_player);
                    break;
                case 'state3':
                    $this->zombieTurn_state3($active_player);
                    break;
                }
                // ... handle all your states in the same fashion
            }

            return;
        }

        // Make sure player is in a non-blocking status for role turn.
        if ($state["type"] === "multipleactiveplayer") {
            // this example is a Zombie level 0, for let 1 or more, it would be similar to the examples for activeplayer state
            $this->gamestate->setPlayerNonMultiactive($active_player, '');
            return;
        }

        throw new \feException("Zombie mode not supported at this game state: \"{$state_name}\".");
    }

    protected function zombieTurn_state1(int $active_player): void
    {
        // example of Zombie level 0
        $this->gamestate->nextState("zombiePass"); // you need to declare this transition that will bring the player/bot to the next state.
    }

    protected function zombieTurn_state2(int $active_player): void
    {
        // example of Zombie level 1
        $args = $this->argState1();
        $possibleMoves = $args['possibleMoves'];

        $zombieChoice = $possibleMoves[bga_rand(0, count($possibleMoves) - 1)]; // random choice over possible moves
        return $this->actPlayState1Action($zombieChoice, $active_player);
    }

    protected function zombieTurn_state3(int $active_player): void
    {
        // example of Zombie level 2
        $this->gamestate->nextState("zombiePass"); // you need to declare this transition that will bring the player/bot to the next state.
    }

Very important: your zombie code will be called when the player leaves the game. The server will handle the Zombie turn, so there is no current player associated to this action. In your zombieTurn function, you must never use getCurrentPlayerId() or getCurrentPlayerName(), but use $active_player id instead (or $this->getPlayerNameById($active_player) ).

Testing the Zombie mode

Create a table in Friendly mode (the infinite time symbol if you're starting from the game page) and Express Start.

Open one of the other players, and in the menu, select "Quit this game" and confirm.

As it's friendly mode, you won't get karma penalty. If it's not friendly mode, you would lose karma, and testing repeatedly, your player might not be allowed to join games anymore!