fix: Correct PnL calculation to show net profit instead of gross payout
Some checks failed
Deploy to Production / test (push) Failing after 36s
Some checks failed
Deploy to Production / test (push) Failing after 36s
- GameServer.ts: Calculate netProfit = grossPayout - betAmount and send as 'net' instead of sending gross payout labeled as net - BlackjackGame.tsx: Fix PnL calculations to use net profit correctly - Hand win/blackjack now shows net profit (payout minus bet) - Lose correctly shows negative bet amount - Round result banner displays roundNet (net profit) with appropriate colors - Remove dead code (myPnl variable that was calculated but never used) - Update color coding: green for profit, red for loss, blue for zero balance
This commit is contained in:
@@ -97,15 +97,16 @@ export class GameServer {
|
|||||||
|
|
||||||
for (const [playerId, multiplier] of Object.entries(roundPayouts)) {
|
for (const [playerId, multiplier] of Object.entries(roundPayouts)) {
|
||||||
if (multiplier <= 0) continue;
|
if (multiplier <= 0) continue;
|
||||||
const amount = Math.floor(betAmount * multiplier);
|
const grossPayout = Math.floor(betAmount * multiplier);
|
||||||
|
const netProfit = grossPayout - betAmount; // Calculate net profit (gross payout minus original bet)
|
||||||
try {
|
try {
|
||||||
await economyService.modifyUserBalance(
|
await economyService.modifyUserBalance(
|
||||||
playerId,
|
playerId,
|
||||||
BigInt(amount),
|
BigInt(grossPayout),
|
||||||
TransactionType.GAME_WIN,
|
TransactionType.GAME_WIN,
|
||||||
`${gameName} round payout (room ${roomId.slice(0, 8)})`,
|
`${gameName} round payout (room ${roomId.slice(0, 8)})`,
|
||||||
);
|
);
|
||||||
payoutDetails[playerId] = { net: amount };
|
payoutDetails[playerId] = { net: netProfit };
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.error("web", `Round payout failed for ${playerId} in room ${roomId}: ${err}`);
|
logger.error("web", `Round payout failed for ${playerId} in room ${roomId}: ${err}`);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -211,13 +211,13 @@ function Seat({ seat, playerName, isMe, isActivePlayer, activeHandIdx, betAmount
|
|||||||
const hasHands = seat.hands.length > 0;
|
const hasHands = seat.hands.length > 0;
|
||||||
const compact = seat.hands.length > 2;
|
const compact = seat.hands.length > 2;
|
||||||
|
|
||||||
// Calculate current round PnL for the display
|
// Calculate current round PnL for the display (only needed before results are shown)
|
||||||
const currentRoundPnl = seat.hands.reduce((sum, h) => {
|
const currentRoundPnl = seat.hands.reduce((sum, h) => {
|
||||||
if (!h.result) return sum; // Not yet resolved
|
if (!h.result) return sum; // Not yet resolved
|
||||||
const handWin = h.bet * betAmount;
|
const handWin = h.bet * betAmount;
|
||||||
if (h.result === "win" || h.result === "blackjack") return sum + handWin;
|
if (h.result === "win" || h.result === "blackjack") return sum + (handWin - betAmount); // Net profit
|
||||||
if (h.result === "push") return sum; // Push returns bet
|
if (h.result === "push") return sum; // Push returns bet, so net is 0
|
||||||
return sum - handWin; // Lose
|
return sum - betAmount; // Lose loses the bet amount
|
||||||
}, 0);
|
}, 0);
|
||||||
const totalPnl = seat.cumulativePnl + currentRoundPnl;
|
const totalPnl = seat.cumulativePnl + currentRoundPnl;
|
||||||
|
|
||||||
@@ -364,11 +364,11 @@ function RoundResultBanner({ roundNumber, roundResult, myPlayerId, betAmount, my
|
|||||||
<div className="flex items-center justify-center gap-3 bg-black/30 rounded-xl px-4 py-2">
|
<div className="flex items-center justify-center gap-3 bg-black/30 rounded-xl px-4 py-2">
|
||||||
<span className="text-xs text-white/50">Round {roundNumber}</span>
|
<span className="text-xs text-white/50">Round {roundNumber}</span>
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
{myPayout && betAmount > 0 && (
|
{betAmount > 0 && (
|
||||||
<span className={`text-xs font-semibold ${
|
<span className={`text-xs font-semibold ${
|
||||||
myPayout.net > betAmount ? "text-emerald-400" : myPayout.net === betAmount ? "text-blue-400" : "text-white/60"
|
roundNet > 0 ? "text-emerald-400" : roundNet < 0 ? "text-red-400" : "text-blue-300"
|
||||||
}`}>
|
}`}>
|
||||||
Round: {myPayout.net > 0 ? "+" : ""}{myPayout.net} AU
|
Round: {roundNet > 0 ? "+" : ""}{roundNet} AU
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
<div className="w-px h-4 bg-white/20" />
|
<div className="w-px h-4 bg-white/20" />
|
||||||
@@ -398,16 +398,6 @@ export function BlackjackGame({ state, myPlayerId, isSpectator, onAction, player
|
|||||||
}, [players]);
|
}, [players]);
|
||||||
|
|
||||||
const mySeat = view.seats[myPlayerId];
|
const mySeat = view.seats[myPlayerId];
|
||||||
const myBetPlaced = mySeat?.hasBet ?? false;
|
|
||||||
|
|
||||||
// Calculate current balance (if betting) or just track profit/loss
|
|
||||||
const balance = betAmount > 0 && mySeat?.hands.length === 0
|
|
||||||
? 0 // Not yet bet for this round
|
|
||||||
: mySeat?.hands.reduce((sum, h) => sum + (h.result === "win" || h.result === "blackjack"
|
|
||||||
? h.bet * betAmount
|
|
||||||
: h.result === "push" ? h.bet * betAmount
|
|
||||||
: 0), 0) - (myBetPlaced ? mySeat.hands.reduce((sum, h) => sum + h.bet * betAmount, 0) : 0);
|
|
||||||
const myPnl = (mySeat?.cumulativePnl ?? 0) + balance;
|
|
||||||
|
|
||||||
// Determine who can sit (spectators during betting phase)
|
// Determine who can sit (spectators during betting phase)
|
||||||
const canSitDown = isSpectator && isBetting && view.turnOrder.length < 6;
|
const canSitDown = isSpectator && isBetting && view.turnOrder.length < 6;
|
||||||
|
|||||||
Reference in New Issue
Block a user