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

PlayerCounter and TableCounter

From Board Game Arena
Jump to navigation Jump to search


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

Counters allow to manipulate numbers in the game. PlayerCounter is for counters that have a distinct value for each player (for example, the player money). TableCounter is for single values, like current round.

Overview

They both share similar functions, and they can update automatically the JS counter (see Counter "create" parameters).

You can initialize them using the counterFactory available in the Game class (and State classes) like this:

        $this->roundCounter = $this->counterFactory->createTableCounter('round');
        $this->playerCredits = $this->counterFactory->createPlayerCounter('credits');

Note that by default, they have a min to 0 and no max, but you can change that in the create function.

Two PlayerCounter are available by default on the games, playerScore and playerScoreAux. As their name suggests, they will update the player_score and player_score_aux for you (and scoreCtrl on front-side), so you never need to update manually the scores on the DB. They don't have a min, and default is 0, so if you need to set a different initial value, call $this->playerScore->setAll(2).

$this->counterFactory->createPlayerCounter(string $name, ?int $min = 0, ?int $max = null): PlayerCounter

$this->counterFactory->createTableCounter(string $name, ?int $min = 0, ?int $max = null): TableCounter

PlayerCounter

initDb(array $playerIds, int $initialValue = 0)
Initialize the database. Must be called from setupNewGame (or if adding to older games in upgradeTableDb).
Parameters:
  • array $playerIds the player ids having the counter (usually, array_keys($players), but you might want to add 0 for an automata)
  • int $initialValue initial value, if different than 0
get(int $playerId): int
Returns the current value of the counter for a player.
Parameters:
  • int $playerId the player id
Throws:
  • UnknownPlayerException if $playerId is not in the player ids initialized by initDb
set(int $playerId, int $value, ?\Bga\GameFramework\NotificationMessage $message): int
Set the value of the counter, and send a notif to update the value on the front side. Returns the new value.
Parameters:
  • int $playerId the player id
  • int $value the new value
  • ?\Bga\GameFramework\NotificationMessage $message the next notif to send to the front. Empty for no log, null for no notif at all (the front will not be updated).
Throws:
  • OutOfRangeCounterException if the value is outside the min/max
  • UnknownPlayerException if $playerId is not in the player ids initialized by initDb
inc(int $playerId, int $inc, ?\Bga\GameFramework\NotificationMessage $message): int
Increment the value of the counter, and send a notif to update the value on the front side. Returns the new value. Note: if the inc is 0, no notif will be sent.
Parameters:
  • int $playerId the player id
  • int $inc the value to add to the current value
  • ?\Bga\GameFramework\NotificationMessage $message the next notif to send to the front. Empty for no log, null for no notif at all (the front will not be updated).
Throws:
  • OutOfRangeCounterException if the value is outside the min/max
  • UnknownPlayerException if $playerId is not in the player ids initialized by initDb
getMin(): int
Returns the lowest value.
getMax(): int
Returns the highest value.
getAll(): array
Return the values for each player, as an associative array $playerId => $value.
setAll(int $value, ?\Bga\GameFramework\NotificationMessage $message): int
Set the value of the counter for all the players, and send a notif to update the value on the front side. Returns the new value.
Parameters:
  • int $value the new value
  • ?\Bga\GameFramework\NotificationMessage $message the next notif to send to the front. Empty for no log, null for no notif at all (the front will not be updated).
Throws:
  • OutOfRangeCounterException if the value is outside the min/max
fillResult(array &$result, ?string $fieldName = null)
Updates the result object, to be used in the `getAllDatas` function. Will set the value on each $result["players"] sub-array.
Parameters:
  • array &$result the object to update
  • ?string $fieldName the field name to set in $result["players"], if different than the counter name.

TableCounter

initDb(int $initialValue = 0)
Initialize the DB elements. Must be called during game `setupNewGame`.
Parameters:
  • int $initialValue initial value, if different than 0
get(): int
Returns the current value of the counter.
set(int $value, ?\Bga\GameFramework\NotificationMessage $message): int
Set the value of the counter, and send a notif to update the value on the front side. Returns the new value.
Parameters:
  • int $value the new value
  • ?\Bga\GameFramework\NotificationMessage $message the next notif to send to the front. Empty for no log, null for no notif at all (the front will not be updated).
Throws:
  • OutOfRangeCounterException if the value is outside the min/max
inc(int $inc, ?\Bga\GameFramework\NotificationMessage $message): int
Increment the value of the counter, and send a notif to update the value on the front side. Returns the new value. Note: if the inc is 0, no notif will be sent.
Parameters:
  • int $inc the value to add to the current value
  • ?\Bga\GameFramework\NotificationMessage $message the next notif to send to the front. Empty for no log, null for no notif at all (the front will not be updated).
Throws:
  • OutOfRangeCounterException if the value is outside the min/max
fillResult(array &$result, ?string $fieldName = null)
Updates the result object, to be used in the `getAllDatas` function.
Parameters:
  • array &$result the object to update
  • ?string $fieldName the field name to set in $result[, if different than the counter name.

Default args sent to the notif

The notification sent to the front-end will contain some default args, so if you want to write something like this:

$this->playerScore->inc(
  $playerId, 
  -1, 
  new NotificationMessage(clienttranslate('${player_name} loses ${absInc} points with played card ${card_name}'), ['card_name' => 'Hunter'])
);

The NotificationMessage args only needs the one that are not supplied automatically by the PlayerCounter.

Built-in args are:

  • name: the name of the player counter
  • value: the new value
  • oldValue: the value before the update
  • inc: the increment
  • absInc: the absolute value of the increment, allowing you to use '...loses ${absInc} ...' in the notif message if you are incrementing with a negative value
  • playerId (only for PlayerCounter)
  • player_name (only for PlayerCounter)

Example

To have a counter to store and display the player energy, you will have :

In the Game class properties (with use Bga\GameFramework\Components\Counters\PlayerCounter; on top of the file):

public PlayerCounter $playerEnergy;

In __construct:

$this->playerEnergy = $this->counterFactory->createPlayerCounter('energy');

In setupNewGame:

$this->playerEnergy->initDb(array_keys($players));

In getAllDatas:

$this->playerEnergy->fillResult($result);

In an act function, when you want to update it:

$this->game->playerEnergy->inc($activePlayerId, 1);

In the JS setup:

            Object.values(gamedatas.players).forEach(player => {
                this.getPlayerPanelElement(player.id).insertAdjacentHTML('beforeend', `
                    <div id="energy-player-counter-${player.id}"></div> 
                    <span>${_("Energy")}</span>
                `);
                const counter = new ebg.counter();
                counter.create(
                    `energy-player-counter-${player.id}`, 
                    { value: player.energy, playerCounter: 'energy', playerId: player.id }
                );
            });

Nothing more to be set, the JS counter will update automatically when you call set or inc!

Use the notif result on front side

If you want to get the update values on the front side for something else than updating a Counter, you can listen to the predefined notification to do additional stuff:

    notif_setPlayerCounter: async function( args )
    {
        const { name, value, oldValue, inc, absInc, playerId } = args;
        if (type === 'energy') {
            this.getPlayerTable(playerId).setEnergyTokens(value);
        }
    }

In the same fashion, there is notif_setTableCounter and notif_setPlayerCounterAll.