fix: Correct PnL calculation by using betAmount in net profit computation
Some checks failed
Deploy to Production / test (push) Failing after 34s
Some checks failed
Deploy to Production / test (push) Failing after 34s
- Add betAmount field to BlackjackState to track the base bet - Fix finishPlayerTurns: multiply hand.bet by state.betAmount for actual money bets - Fix GameServer: roundPayouts are already gross payouts (not multipliers) - Update cumulative PnL calculation to correctly subtract actual bet amount - Add betAmount support to riggedState test helper
This commit is contained in:
@@ -95,10 +95,9 @@ export class GameServer {
|
|||||||
const gameName = gameRegistry.get(room.gameSlug)?.name ?? "Game";
|
const gameName = gameRegistry.get(room.gameSlug)?.name ?? "Game";
|
||||||
const payoutDetails: Record<string, { net: number }> = {};
|
const payoutDetails: Record<string, { net: number }> = {};
|
||||||
|
|
||||||
for (const [playerId, multiplier] of Object.entries(roundPayouts)) {
|
for (const [playerId, grossPayout] of Object.entries(roundPayouts)) {
|
||||||
if (multiplier <= 0) continue;
|
// roundPayout is already the gross payout amount (not a multiplier)
|
||||||
const grossPayout = Math.floor(betAmount * multiplier);
|
const netProfit = Math.floor(grossPayout) - betAmount; // Calculate net profit (gross payout minus original bet)
|
||||||
const netProfit = grossPayout - betAmount; // Calculate net profit (gross payout minus original bet)
|
|
||||||
try {
|
try {
|
||||||
await economyService.modifyUserBalance(
|
await economyService.modifyUserBalance(
|
||||||
playerId,
|
playerId,
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ function riggedState(overrides: {
|
|||||||
activePlayerIndex?: number;
|
activePlayerIndex?: number;
|
||||||
phase?: "betting" | "player_turns" | "resolved";
|
phase?: "betting" | "player_turns" | "resolved";
|
||||||
roundNumber?: number;
|
roundNumber?: number;
|
||||||
|
betAmount?: number;
|
||||||
}): BlackjackState {
|
}): BlackjackState {
|
||||||
return {
|
return {
|
||||||
deck: overrides.deck ?? [makeCard("5"), makeCard("6"), makeCard("7"), makeCard("8"), makeCard("9"), makeCard("10")],
|
deck: overrides.deck ?? [makeCard("5"), makeCard("6"), makeCard("7"), makeCard("8"), makeCard("9"), makeCard("10")],
|
||||||
@@ -43,6 +44,7 @@ function riggedState(overrides: {
|
|||||||
activePlayerIndex: overrides.activePlayerIndex ?? 0,
|
activePlayerIndex: overrides.activePlayerIndex ?? 0,
|
||||||
phase: overrides.phase ?? "player_turns",
|
phase: overrides.phase ?? "player_turns",
|
||||||
roundNumber: overrides.roundNumber ?? 1,
|
roundNumber: overrides.roundNumber ?? 1,
|
||||||
|
betAmount: overrides.betAmount ?? 0,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -196,10 +196,10 @@ function finishPlayerTurns(state: BlackjackState): BlackjackState {
|
|||||||
|
|
||||||
// Then calculate PnL based on resolved hands
|
// Then calculate PnL based on resolved hands
|
||||||
const roundPayout = calculateRoundPayouts({ [id]: { ...seat, hands: resolvedHands } });
|
const roundPayout = calculateRoundPayouts({ [id]: { ...seat, hands: resolvedHands } });
|
||||||
const roundPnl = roundPayout[id] ?? 0;
|
const roundPayoutMoney = roundPayout[id] ?? 0;
|
||||||
// Subtract the total bet amount to get net profit/loss
|
// Subtract the total bet amount to get net profit/loss
|
||||||
const roundBetTotal = seat.hands.reduce((sum, h) => sum + h.bet, 0);
|
const roundBetTotal = seat.hands.reduce((sum, h) => sum + (h.bet * state.betAmount), 0);
|
||||||
const roundNetPnl = roundPayout[id] ? roundPayout[id] - roundBetTotal : -roundBetTotal;
|
const roundNetPnl = roundPayoutMoney ? roundPayoutMoney - roundBetTotal : -roundBetTotal;
|
||||||
|
|
||||||
resolvedSeats[id] = {
|
resolvedSeats[id] = {
|
||||||
...seat,
|
...seat,
|
||||||
@@ -361,7 +361,8 @@ export const blackjackPlugin: GamePlugin<BlackjackState, BlackjackAction> = {
|
|||||||
maxPlayers: 6,
|
maxPlayers: 6,
|
||||||
manualStart: true,
|
manualStart: true,
|
||||||
|
|
||||||
createInitialState(players: string[], _options?: Record<string, unknown>): BlackjackState {
|
createInitialState(players: string[], options?: Record<string, unknown>): BlackjackState {
|
||||||
|
const betAmount = typeof options?.betAmount === 'number' ? options.betAmount : 0;
|
||||||
const seats: Record<string, PlayerSeat> = {};
|
const seats: Record<string, PlayerSeat> = {};
|
||||||
for (const pid of players) {
|
for (const pid of players) {
|
||||||
seats[pid] = {
|
seats[pid] = {
|
||||||
@@ -380,6 +381,7 @@ export const blackjackPlugin: GamePlugin<BlackjackState, BlackjackAction> = {
|
|||||||
activePlayerIndex: -1,
|
activePlayerIndex: -1,
|
||||||
phase: "betting",
|
phase: "betting",
|
||||||
roundNumber: 1,
|
roundNumber: 1,
|
||||||
|
betAmount,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -41,6 +41,8 @@ export interface BlackjackState {
|
|||||||
activePlayerIndex: number;
|
activePlayerIndex: number;
|
||||||
phase: "betting" | "player_turns" | "resolved";
|
phase: "betting" | "player_turns" | "resolved";
|
||||||
roundNumber: number;
|
roundNumber: number;
|
||||||
|
/** The base bet amount for this game (0 for free play). */
|
||||||
|
betAmount: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Actions ──
|
// ── Actions ──
|
||||||
|
|||||||
Reference in New Issue
Block a user