$this->bga->playerScore
The built-in PlayerCounter for player.player_score. Access the same instance through $this->bga->playerScore or $this->playerScore in Game.
The counter starts at 0, has no minimum or maximum, and uses player IDs by default. The framework supplies the counter; do not create another counter with the name player_score.
Updating scores
get(int $playerIdOrNo): int
Read a player’s score.
set(int $playerIdOrNo, int $value, ?NotificationMessage $message = new NotificationMessage()): int
Set the score and return its new value.
inc(int $playerIdOrNo, int $inc, ?NotificationMessage $message = new NotificationMessage()): int
Add a signed amount and return the new score.
setAll(int $value, ?NotificationMessage $message = new NotificationMessage()): int
Set every player’s score, for example to give everyone the same starting points.
The default message updates front-end score counters without log text. Pass a Bga\GameFramework\NotificationMessage for a log entry, or null to suppress notifications.
use Bga\GameFramework\NotificationMessage;
$this->bga->playerScore->inc($playerId, 3, new NotificationMessage(
clienttranslate('${player_name} gains ${inc} points')
));
Initial interface data
Include score in each player’s data returned by getAllDatas, as in the generated template. This lets the interface restore the score counters when the page reloads.
See PlayerCounter for player-number mode, all value methods, and notification arguments. Use playerScoreAux for a secondary score that breaks ties.
Final ranking
With normal scoring, higher scores rank first. Equal main scores are compared using playerScoreAux; equality on both values produces a tie.
Reverse scoring
For games where the lowest score wins, return a GameResult from your final state. This ends the game with the requested ranking:
use Bga\GameFramework\GameResult\GameResult;
public function onEnteringState(): GameResult
{
return GameResult::individualRanking(reverseScore: true);
}
This reads scores from the player table. For reverse tie breaking, use reverseScoreAux: true, either on its own or with reverseScore: true.
When migrating running tables that stored negative scores to simulate reverse scoring, preserve their existing sign convention until they finish. You can supply explicit result players with converted scores:
use Bga\GameFramework\GameResult\GameResult;
use Bga\GameFramework\GameResult\Player;
$rows = $this->game->getCollectionFromDb('SELECT * FROM `player`');
$players = Player::fromPlayersDb($rows);
if ($usesLegacyNegativeScores) {
foreach ($players as $player) {
$player->score = -$player->score;
}
}
return GameResult::individualRanking($players, reverseScore: true);
Here $usesLegacyNegativeScores is your game's saved migration flag. Existing games that distinguish the conventions by whether any score is negative can use $this->game->bga->playerScore->getMin() < 0; getMin() returns the lowest current player score, not a configured counter bound. Apply the same convention when changing scores during play.
Cooperative and solo results
For full cooperation, set "is_coop": 1 in gameinfos. Under the default convention, a shared positive score is a win and a score of zero or below is a loss. When winning depends on another threshold, return an explicit result:
use Bga\GameFramework\GameResult\GameResult;
// In the final state's onEnteringState, after computing $teamScore:
return GameResult::coop(score: $teamScore, win: $teamScore >= 12);
For solo play, express the win condition separately from the displayed score:
In a semi-cooperative game where everyone loses together, equal scores produce a shared tie under individual ranking.
Winners and losers without ranked losers
When the rules divide players into winners and equally ranked losers, give every winner the same higher score and every loser the same lower score. Configure losers_not_ranked in gameinfos. Do not use that setting for full cooperation or two-player games.
Players leaving, elimination, and concessions
A player leaving normally neutralizes the results, rather than preserving the ranking produced by ordinary scoring. Games whose rules remain fair with a zombie player can request the Keep ranking on player quit setting from Studio Support. The wiki's neutralization guidance explains the conditions and rollout to existing tables.
Rule-based elimination is separate from leaving a game. Call $this->eliminatePlayer($playerId) in Game only when the rules eliminate that player, and make sure they are no longer active at the end of the action. If this eliminates the last player, finish your end scoring and transition to game end in the same action; otherwise the framework jumps directly to the final state.
For small bookkeeping changes when a player concedes, Game can implement onConcede($concederTeam). The conceding player's ID is available through $concederTeam->players[0]->id. Do not change game state in this callback. Exceptions are logged rather than propagated, so keep its work small and straightforward.