This is a documentation for Board Game Arena: play board games online !
PlayerCounter and TableCounter: Difference between revisions
Victoria La (talk | contribs) (toc after large section is weird) |
(Fixed wrong variable name) |
||
| (5 intermediate revisions by one other user not shown) | |||
| Line 21: | Line 21: | ||
== PlayerCounter == | == PlayerCounter == | ||
;initDb(array $playerIds, int $initialValue = 0) | ;initDb(array $playerIds, int $initialValue = 0) | ||
: | :Creates database table if needed (bga_player_counters). Must be called from <code>setupNewGame</code> (or if adding to older games in <code>upgradeTableDb</code>). | ||
:Parameters: | :Parameters: | ||
:* <code>array $playerIds</code> the player ids having the counter (usually, <code>array_keys($players)</code>, but you might want to add 0 for an automata) | :* <code>array $playerIds</code> the player ids having the counter (usually, <code>array_keys($players)</code>, but you might want to add 0 for an automata) | ||
| Line 31: | Line 31: | ||
:* <code>int $playerId</code> the player id | :* <code>int $playerId</code> the player id | ||
:Throws: | :Throws: | ||
:* <code>UnknownPlayerException</code> if $playerId is not in the player ids initialized by initDb | :* <code>UnknownPlayerException</code> if $playerId is not in the player ids initialized by <code>initDb</code> | ||
;set(int $playerId, int $value, ?\Bga\GameFramework\NotificationMessage $message)<nowiki>:</nowiki> int | ;set(int $playerId, int $value, ?\Bga\GameFramework\NotificationMessage $message)<nowiki>:</nowiki> int | ||
:Set the value of the counter, and send a notif to update the value on the front side. Returns the new value. | :Set the value of the counter, and send a notif (of type <code>setPlayerCounter)</code> to update the value on the front side. Returns the new value. | ||
:Parameters: | :Parameters: | ||
:* <code>int $playerId</code> the player id | :* <code>int $playerId</code> the player id | ||
| Line 44: | Line 44: | ||
;inc(int $playerId, int $inc, ?\Bga\GameFramework\NotificationMessage $message)<nowiki>:</nowiki> int | ;inc(int $playerId, int $inc, ?\Bga\GameFramework\NotificationMessage $message)<nowiki>:</nowiki> 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. | :Increment the value of the counter, and send a notif (of type <code>setPlayerCounter)</code>to update the value on the front side. Returns the new value. Note: if the inc is 0, no notif will be sent. | ||
:Parameters: | :Parameters: | ||
:* <code>int $playerId</code> the player id | :* <code>int $playerId</code> the player id | ||
| Line 63: | Line 63: | ||
;setAll(int $value, ?\Bga\GameFramework\NotificationMessage $message)<nowiki>:</nowiki> int | ;setAll(int $value, ?\Bga\GameFramework\NotificationMessage $message)<nowiki>:</nowiki> 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. | :Set the value of the counter for all the players, and send a notif (of type <code>setPlayerCounterAll)</code> to update the value on the front side. Returns the new value. | ||
:Parameters: | :Parameters: | ||
:* <code>int $value</code> the new value | :* <code>int $value</code> the new value | ||
| Line 71: | Line 71: | ||
;fillResult(array &$result, ?string $fieldName = null) | ;fillResult(array &$result, ?string $fieldName = null) | ||
:Updates the result object, to be used in the | :Updates the result object, to be used in the <code>getAllDatas</code> function. Will set the value on each <code>$result["players"]</code> sub-array. | ||
:Parameters: | :Parameters: | ||
:* <code>array &$result</code> the object to update | :* <code>array &$result</code> the object to update | ||
| Line 79: | Line 79: | ||
;initDb(int $initialValue = 0) | ;initDb(int $initialValue = 0) | ||
: | :Creates database table if needed (bga_table_counters). Must be called from <code>setupNewGame</code>. | ||
:Parameters: | :Parameters: | ||
:* <code>int $initialValue</code> initial value, if different than 0 | :* <code>int $initialValue</code> initial value, if different than 0 | ||
| Line 87: | Line 87: | ||
;set(int $value, ?\Bga\GameFramework\NotificationMessage $message)<nowiki>:</nowiki> int | ;set(int $value, ?\Bga\GameFramework\NotificationMessage $message)<nowiki>:</nowiki> int | ||
:Set the value of the counter, and send a notif to update the value on the front side. Returns the new value. | :Set the value of the counter, and send a notif (of type <code>setTableCounter)</code> to update the value on the front side. Returns the new value. | ||
:Parameters: | :Parameters: | ||
:* <code>int $value</code> the new value | :* <code>int $value</code> the new value | ||
| Line 95: | Line 95: | ||
;inc(int $inc, ?\Bga\GameFramework\NotificationMessage $message)<nowiki>:</nowiki> int | ;inc(int $inc, ?\Bga\GameFramework\NotificationMessage $message)<nowiki>:</nowiki> 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. | :Increment the value of the counter, and send a notif (of type <code>setTableCounter)</code>to update the value on the front side. Returns the new value. Note: if the inc is 0, no notif will be sent. | ||
:Parameters: | :Parameters: | ||
:* <code>int $inc</code> the value to add to the current value | :* <code>int $inc</code> the value to add to the current value | ||
| Line 109: | Line 109: | ||
== Default args sent to the notif == | == Default args sent to the notif == | ||
The notification sent to the front will contain some default | The notification sent to the front-end will contain some default args, so if you want to write something like this: | ||
<pre> | <pre> | ||
$this->playerScore->inc( | $this->playerScore->inc( | ||
| Line 137: | Line 137: | ||
</pre> | </pre> | ||
In __construct: | In __construct of Game class: | ||
<pre> | <pre> | ||
$this->playerEnergy = $this->counterFactory->createPlayerCounter('energy'); | $this->playerEnergy = $this->counterFactory->createPlayerCounter('energy'); | ||
| Line 152: | Line 152: | ||
</pre> | </pre> | ||
In an act function, when you want to update it: | In an act function (i.e. in State class), when you want to update it: | ||
<pre> | <pre> | ||
$this->game->playerEnergy->inc($activePlayerId, 1); | $this->game->playerEnergy->inc($activePlayerId, 1); | ||
| Line 161: | Line 161: | ||
Object.values(gamedatas.players).forEach(player => { | Object.values(gamedatas.players).forEach(player => { | ||
this.getPlayerPanelElement(player.id).insertAdjacentHTML('beforeend', ` | this.getPlayerPanelElement(player.id).insertAdjacentHTML('beforeend', ` | ||
<div id="energy-player-counter-${player.id}"></div> Energy | <div id="energy-player-counter-${player.id}"></div> | ||
<span>${_("Energy")}</span> | |||
`); | `); | ||
const counter = new ebg.counter(); | const counter = new ebg.counter(); | ||
| Line 171: | Line 172: | ||
</pre> | </pre> | ||
Nothing more to be set, the JS counter will update automatically when you call <code>set</code> or <code>inc</code>! | Nothing more needs to be set, the JS counter will update automatically when you call <code>set</code> or <code>inc</code>! | ||
== | == Listen to counter notification on the client == | ||
If you want to get the update values on the | If you want to get the update values on the client for something else than updating a Counter, you can listen to the predefined notification to do additional stuff: | ||
<pre> | <pre> | ||
notif_setPlayerCounter: async function( args ) | notif_setPlayerCounter: async function( args ) | ||
{ | { | ||
const { name, value, oldValue, inc, absInc, playerId } = args; | const { name, value, oldValue, inc, absInc, playerId } = args; | ||
if ( | if (name === 'energy') { | ||
this.getPlayerTable(playerId).setEnergyTokens(value); | this.getPlayerTable(playerId).setEnergyTokens(value); | ||
} | } | ||
Latest revision as of 22:49, 11 November 2025
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)
- Creates database table if needed (bga_player_counters). Must be called from
setupNewGame(or if adding to older games inupgradeTableDb). - Parameters:
array $playerIdsthe player ids having the counter (usually,array_keys($players), but you might want to add 0 for an automata)int $initialValueinitial value, if different than 0
- get(int $playerId): int
- Returns the current value of the counter for a player.
- Parameters:
int $playerIdthe player id
- Throws:
UnknownPlayerExceptionif $playerId is not in the player ids initialized byinitDb
- set(int $playerId, int $value, ?\Bga\GameFramework\NotificationMessage $message): int
- Set the value of the counter, and send a notif (of type
setPlayerCounter)to update the value on the front side. Returns the new value. - Parameters:
int $playerIdthe player idint $valuethe new value?\Bga\GameFramework\NotificationMessage $messagethe next notif to send to the front. Empty for no log, null for no notif at all (the front will not be updated).
- Throws:
OutOfRangeCounterExceptionif the value is outside the min/maxUnknownPlayerExceptionif $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 (of type
setPlayerCounter)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 $playerIdthe player idint $incthe value to add to the current value?\Bga\GameFramework\NotificationMessage $messagethe next notif to send to the front. Empty for no log, null for no notif at all (the front will not be updated).
- Throws:
OutOfRangeCounterExceptionif the value is outside the min/maxUnknownPlayerExceptionif $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 (of type
setPlayerCounterAll)to update the value on the front side. Returns the new value. - Parameters:
int $valuethe new value?\Bga\GameFramework\NotificationMessage $messagethe next notif to send to the front. Empty for no log, null for no notif at all (the front will not be updated).
- Throws:
OutOfRangeCounterExceptionif the value is outside the min/max
- fillResult(array &$result, ?string $fieldName = null)
- Updates the result object, to be used in the
getAllDatasfunction. Will set the value on each$result["players"]sub-array. - Parameters:
array &$resultthe object to update?string $fieldNamethe field name to set in $result["players"], if different than the counter name.
TableCounter
- initDb(int $initialValue = 0)
- Creates database table if needed (bga_table_counters). Must be called from
setupNewGame. - Parameters:
int $initialValueinitial 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 (of type
setTableCounter)to update the value on the front side. Returns the new value. - Parameters:
int $valuethe new value?\Bga\GameFramework\NotificationMessage $messagethe next notif to send to the front. Empty for no log, null for no notif at all (the front will not be updated).
- Throws:
OutOfRangeCounterExceptionif 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 (of type
setTableCounter)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 $incthe value to add to the current value?\Bga\GameFramework\NotificationMessage $messagethe next notif to send to the front. Empty for no log, null for no notif at all (the front will not be updated).
- Throws:
OutOfRangeCounterExceptionif 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 &$resultthe object to update?string $fieldNamethe 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 of Game class:
$this->playerEnergy = $this->counterFactory->createPlayerCounter('energy');
In setupNewGame:
$this->playerEnergy->initDb(array_keys($players));
In getAllDatas:
$this->playerEnergy->fillResult($result);
In an act function (i.e. in State class), 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 needs to be set, the JS counter will update automatically when you call set or inc!
Listen to counter notification on the client
If you want to get the update values on the client 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 (name === 'energy') {
this.getPlayerTable(playerId).setEnergyTokens(value);
}
}
In the same fashion, there is notif_setTableCounter and notif_setPlayerCounterAll.