Prize Pool et Économie

Cette section détaille le système d'économie virtuelle du jeu, incluant la gestion du prize pool, des frais d'entrée, et de la distribution des gains.

PrizePoolService (prize-pool.service.ts)

Service qui gère la distribution de la monnaie virtuelle en fin de partie.

Méthodes principales

async distributePrizePool(game: OnGoingGame)

Description : Distribue le prize pool de la partie aux joueurs.
Paramètres :

Logique de distribution :

  1. Identifie les gagnants (équipe ou joueur unique)
  2. Filtre les bots (ne reçoivent pas de monnaie)
  3. Calcule les montants :
    • 2/3 du prize pool → gagnants (divisé équitablement)
    • 1/3 du prize pool → perdants (prix de consolation, divisé équitablement)
  4. Crédite les comptes via UserService
  5. Log des distributions

Cas particuliers :

Retour : Promise<void>

private async creditWinners(winners: Player[], amount: number)

Description : Crédite les comptes des gagnants.
Paramètres :

Actions :

  1. Filtre les bots
  2. Calcule montant par gagnant
  3. Crédite chaque compte via UserService.addVirtualCurrency()

Retour : Promise<void>

private async creditLosers(losers: Player[], amount: number)

Description : Crédite les comptes des perdants (prix de consolation).
Paramètres :

Logique : Identique à creditWinners mais avec 1/3 du prize pool

Retour : Promise<void>

async refundPlayer(firebaseUid: string, amount: number)

Description : Rembourse un joueur (si partie annulée ou joueur expulsé).
Paramètres :

Actions : Crédite le compte via UserService.addVirtualCurrency()

Retour : Promise<void>

Intégration avec OnGoingGame

Propriétés liées à l'économie

OnGoingGame

{
    prizePool: number,        // Cagnotte accumulée
    entryFee: number,        // Frais d'entrée (0-100 coins)
    // ...
}

Flux du prize pool

1. Configuration de la partie

const game = new OnGoingGame({
    entryFee: 50,           // Admin définit les frais
    prizePool: 0            // Initialisé à 0
});

2. Joueurs rejoignent

// Pour chaque joueur rejoignant:
if (game.entryFee > 0) {
    // Vérifier solde
    if (user.virtualCurrencyBalance >= game.entryFee) {
        // Débiter
        await userService.deductVirtualCurrency(
            user.firebaseUid, 
            game.entryFee
        );
        // Ajouter au prize pool
        game.prizePool += game.entryFee;
    } else {
        // Refuser l'accès
        throw new Error('Insufficient funds');
    }
}

3. Fin de partie

await prizePoolService.distributePrizePool(game);

4. Distribution calculée

const winnersShare = Math.floor(game.prizePool * 2 / 3);
const losersShare = game.prizePool - winnersShare;

const amountPerWinner = Math.floor(winnersShare / realWinners.length);
const amountPerLoser = Math.floor(losersShare / realLosers.length);

Intégration avec UserService

Méthodes utilisées

async addVirtualCurrency(firebaseUid: string, amount: number)

Description : Ajoute de la monnaie virtuelle au solde d'un utilisateur.
Paramètres :

Actions : Incrémente virtualCurrencyBalance
Retour : Promise<void>

async deductVirtualCurrency(firebaseUid: string, amount: number)

Description : Déduit de la monnaie virtuelle du solde d'un utilisateur.
Paramètres :

Validation : Solde suffisant
Actions : Décrémente virtualCurrencyBalance
Retour : Promise<void>

Scénarios d'économie

1. Partie avec frais d'entrée

Configuration :

Accumulation :

Distribution :

Bilan : Total distribué = 132 + 66 = 198 coins (arrondi inférieur)

2. Partie sans frais

Configuration :

Résultat :

3. Partie annulée

Situation : Admin quitte avant démarrage

Actions :

4. Joueur expulsé (kick)

Situation : Admin expulse un joueur de la salle d'attente

Actions :

5. Dernier survivant (Battle Royale)

Situation : Un seul joueur reste en vie

Distribution :

Validation des frais d'entrée

Configuration de la partie

Lors de la création de partie, validation du entryFee :

Vérification avant de rejoindre

if (game.entryFee > 0) {
    const user = await userService.getUserByFirebaseUid(firebaseUid);
    if (user.virtualCurrencyBalance < game.entryFee) {
        throw new Error('Insufficient funds');
    }
}

Monnaie Virtuelle

Solde par défaut

Nouveaux utilisateurs :

Sources de gains

  1. Parties gagnées : 2/3 du prize pool divisé
  2. Parties perdues : 1/3 du prize pool divisé (consolation)
  3. Bonus futurs : Quêtes, achievements, événements (non implémentés)

Dépenses

  1. Frais d'entrée : 0-100 coins par partie
  2. Boutique : 300-1500 coins par item

Équilibrage

Le système est conçu pour que :

Gestion d'erreurs

Fonds insuffisants

Scénario : Joueur tente de rejoindre une partie payante sans solde suffisant

Réponse :

{
    error: 'INSUFFICIENT_FUNDS',
    message: 'You do not have enough virtual currency',
    required: 50,
    current: 30
}

Erreur de distribution

Scénario : Erreur lors du crédit d'un compte

Actions :

Logging

Tous les événements économiques sont loggés :

Format :

[PrizePoolService] Distributing 200 coins to 4 players
[PrizePoolService] Winner user123 received 66 coins
[PrizePoolService] Loser user456 received 33 coins

Extensions possibles

Bonus et multiplicateurs

Leaderboard économique

Transactions