Roulette
- community
- minigames
- by limon
- Takaro v0.0.21
- all
Roulette Module: Casino-Style Gambling for Your Game Server
A realistic casino-style roulette game where players can bet currency and win based on where the ball lands.
Key Features
- Authentic Gameplay: Simple, realistic roulette with true-to-life odds and mechanics.
- Multiple Bet Types: Various betting options with different risk/reward ratios.
- Accurate Validation: Color and number validation matching a real roulette wheel.
- Statistics Tracking: Monitor your gambling performance over time.
- Configurable Settings: Adjustable house edge and betting limits.
- Optional Cooldown: Set time between spins to prevent excessive gambling.
- VIP Permissions: Special access for VIP players to higher betting limits.
- Admin Controls: Commands to view and reset player statistics.
How to Play
/roulette red 100- Bet 100 on any red number/roulette black 200- Bet 200 on any black number/roulette even 150- Bet 150 on even numbers/roulette odd 150- Bet 150 on odd numbers/roulette high 100- Bet 100 on high numbers (19-36)/roulette low 100- Bet 100 on low numbers (1-18)/roulette 17 200- Bet 200 specifically on number 17/roulette red17 300- Bet 300 specifically on red 17 (higher payout)/roulettestats- View your personal roulette statistics/rouletterules- Display roulette rules and payouts
Payouts
- Red/Black: 1:1
- Even/Odd: 1:1
- High/Low: 1:1
- Single Number: 35:1
- Color+Number: 70:1
All payouts are subject to the configured house edge.
Configuration Options
- Minimum bet amount
- Maximum bet amount
- House edge percentage
- Cooldown time between spins
This module provides a fun and engaging way for players to gamble their in-game currency with realistic odds and authentic roulette gameplay.
Configuration 3
Settings you fill in when installing the module on a server.
| Setting | Type | Default | Description |
|---|---|---|---|
minimumBet minimumBet | number | 10 | The minimum amount a player can bet on a single spin. |
maximumBet maximumBet | number | 100 | The maximum amount a player can bet on a single spin. |
houseEdge houseEdge | number | 5 | Percentage of winnings the house takes as profit (5 = 5%). |
Raw config schema
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"required": [],
"additionalProperties": false,
"properties": {
"minimumBet": {
"title": "minimumBet",
"description": "The minimum amount a player can bet on a single spin.",
"default": 10,
"type": "number"
},
"maximumBet": {
"title": "maximumBet",
"description": "The maximum amount a player can bet on a single spin.",
"default": 100,
"type": "number"
},
"houseEdge": {
"title": "houseEdge",
"description": "Percentage of winnings the house takes as profit (5 = 5%).",
"default": 5,
"type": "number"
}
}
} Raw UI schema
{} Commands 4
Chat commands players trigger in game.
-
roulettestats
Shows your roulette statistics
Command source
import { takaro, data } from '@takaro/helpers'; async function main() { const { player, gameServerId, module: mod } = data; const statsKey = 'roulette_stats'; const statsSearch = await takaro.variable.variableControllerSearch({ filters: { key: [statsKey], playerId: [player.id], gameServerId: [gameServerId], moduleId: [mod.moduleId], }, }); if (statsSearch.data.data.length === 0) { await player.pm("π° You haven't played any roulette games yet!"); return; } const stats = JSON.parse(statsSearch.data.data[0].value); const winRate = stats.played > 0 ? ((stats.won / stats.played) * 100).toFixed(1) : 0; // More compact stats display const statsDisplay = [ `π° ROULETTE STATS π°`, `Games: ${stats.played} (${stats.won} wins, ${stats.lost} losses)`, `Win rate: ${winRate}%`, `Total wagered: ${stats.totalWagered} currency`, `π Good luck on your next spin!` ]; await player.pm(statsDisplay.join('\n')); } await main(); -
roulettereset
Reset a player's roulette statistics (admin only).
Argument Type Default Help playerstring Player whose stats to reset Command source
import { takaro, data, checkPermission, TakaroUserError } from '@takaro/helpers'; async function main() { const { player, gameServerId, arguments: args, module: mod, pog } = data; // Check admin permission if (!checkPermission(pog, 'ROULETTE_ADMIN')) { throw new TakaroUserError('You do not have permission to reset roulette statistics!'); } // Get target player if (!args.player) { throw new TakaroUserError('Please specify a player whose stats you want to reset.'); } const targetPlayerId = args.player.playerId; const targetPlayerName = args.player.name; // Find stats to reset const statsKey = 'roulette_stats'; const statsSearch = await takaro.variable.variableControllerSearch({ filters: { key: [statsKey], playerId: [targetPlayerId], gameServerId: [gameServerId], moduleId: [mod.moduleId], }, }); if (statsSearch.data.data.length === 0) { throw new TakaroUserError(`No roulette statistics found for ${targetPlayerName}.`); } // Delete the stats variable await takaro.variable.variableControllerDelete(statsSearch.data.data[0].id); // Also delete any cooldown variables const cooldownKey = 'roulette_cooldown'; const cooldownSearch = await takaro.variable.variableControllerSearch({ filters: { key: [cooldownKey], playerId: [targetPlayerId], gameServerId: [gameServerId], moduleId: [mod.moduleId], }, }); if (cooldownSearch.data.data.length > 0) { await takaro.variable.variableControllerDelete(cooldownSearch.data.data[0].id); } await player.pm(`β Successfully reset roulette statistics for ${targetPlayerName}.`); // Log the action await takaro.gameserver.gameServerControllerExecuteCommand(gameServerId, { command: `say [Admin] ${player.name} has reset ${targetPlayerName}'s roulette statistics.`, }); } await main(); -
rouletterules
Shows the rules and payouts for roulette.
Command source
import { takaro, data } from '@takaro/helpers'; async function main() { const { player, module: mod } = data; const minimumBet = mod.userConfig.minimumBet; const maximumBet = mod.userConfig.maximumBet; const houseEdge = mod.userConfig.houseEdge; // Part 1: Introduction and basic info const rules1 = [ `π° π² ROULETTE RULES π² π°`, '', `Minimum bet: ${minimumBet} currency`, `Maximum bet: ${maximumBet} currency`, `House edge: ${houseEdge}%`, ]; // Part 2: Bet types const rules2 = [ 'BET TYPES AND PAYOUTS:', '', 'π΄ RED - Pays 1:1 - Bet on the ball landing on a red number', 'β« BLACK - Pays 1:1 - Bet on the ball landing on a black number', 'π’ EVEN - Pays 1:1 - Bet on the ball landing on an even number (not 0)', 'π’ ODD - Pays 1:1 - Bet on the ball landing on an odd number', 'β¬οΈ HIGH - Pays 1:1 - Bet on the ball landing on numbers 19-36', 'β¬οΈ LOW - Pays 1:1 - Bet on the ball landing on numbers 1-18', 'π― NUMBER - Pays 35:1 - Bet on a specific number (0-36)', 'π― COLOR+NUMBER - Pays 70:1 - Bet on a specific number AND color', ]; // Part 3: Examples const rules3 = [ 'EXAMPLES:', '/roulette red 100 - Bet 100 on red', '/roulette 17 50 - Bet 50 on number 17', '/roulette black 200 - Bet 200 on black', '/roulette red17 500 - Bet 500 on red 17', '', 'Use /roulettestats to view your statistics!' ]; // Send messages with a slight delay between them await player.pm(rules1.join('\n')); await player.pm(rules2.join('\n')); await player.pm(rules3.join('\n')); } await main(); -
roulette
Place a bet and spin the roulette wheel.
Argument Type Default Help betTypestring Type of bet (red, black, even, odd, high, low) or a number 0-36 amountnumber Amount to bet Command source
import { takaro, data, checkPermission, TakaroUserError } from '@takaro/helpers'; async function main() { const { player, gameServerId, arguments: args, module: mod, pog } = data; // Define the roulette wheel number colors const redNumbers = [1, 3, 5, 7, 9, 12, 14, 16, 18, 19, 21, 23, 25, 27, 30, 32, 34, 36]; const blackNumbers = [2, 4, 6, 8, 10, 11, 13, 15, 17, 20, 22, 24, 26, 28, 29, 31, 33, 35]; // Check permission if (!checkPermission(pog, 'ROULETTE_PLAY')) { throw new TakaroUserError('You do not have permission to play roulette!'); } // Get the input from the first argument (bet type + possible number) const betInput = args.betType ? args.betType.toLowerCase() : null; const betAmount = Number(args.amount); if (!betInput) { throw new TakaroUserError('Please specify what you want to bet on!'); } // Validate bet amount if (isNaN(betAmount) || betAmount <= 0) { throw new TakaroUserError('Please enter a valid positive bet amount!'); } // Parse the bet type and number from the input let betType = null; let betNumber = null; let betColor = null; // Define valid bet types const simpleBetTypes = ['red', 'black', 'even', 'odd', 'high', 'low']; // Check if it's a simple bet type (red, black, etc.) if (simpleBetTypes.includes(betInput)) { betType = betInput; } // Check if it's a number bet (e.g., "number17" or just "17") else if (betInput.startsWith('number')) { betType = 'number'; betNumber = Number(betInput.substring(6)); // Extract number after "number" } // Check if it's red+number (e.g., "red17") else if (betInput.startsWith('red') && betInput.length > 3) { betType = 'colorednumber'; betColor = 'red'; betNumber = Number(betInput.substring(3)); // Extract number after "red" // Validate the number is actually red on a real roulette wheel if (!redNumbers.includes(betNumber)) { throw new TakaroUserError(`Number ${betNumber} is not red on the roulette wheel. It's ${blackNumbers.includes(betNumber) ? 'black' : 'green (0)'}.`); } } // Check if it's black+number (e.g., "black17") else if (betInput.startsWith('black') && betInput.length > 5) { betType = 'colorednumber'; betColor = 'black'; betNumber = Number(betInput.substring(5)); // Extract number after "black" // Validate the number is actually black on a real roulette wheel if (!blackNumbers.includes(betNumber)) { throw new TakaroUserError(`Number ${betNumber} is not black on the roulette wheel. It's ${redNumbers.includes(betNumber) ? 'red' : 'green (0)'}.`); } } // Check if it's just a number else if (!isNaN(Number(betInput)) && Number(betInput) >= 0 && Number(betInput) <= 36) { betType = 'number'; betNumber = Number(betInput); } // Unknown bet type else { throw new TakaroUserError(`Invalid bet type! Valid options: ${simpleBetTypes.join(', ')}, a number 0-36, or color+number (e.g., red17)`); } // Validate number if it's a number bet if ((betType === 'number' || betType === 'colorednumber') && (isNaN(betNumber) || betNumber < 0 || betNumber > 36 || !Number.isInteger(betNumber))) { throw new TakaroUserError('Please specify a valid number between 0 and 36!'); } // Get minimum and maximum bet limits const minimumBet = mod.userConfig.minimumBet; let maximumBet = mod.userConfig.maximumBet; // Check higher limits permission const higherLimitsPermission = checkPermission(pog, 'ROULETTE_HIGHER_LIMITS'); if (higherLimitsPermission && higherLimitsPermission.count > 0) { maximumBet *= higherLimitsPermission.count; } // Validate bet amount against limits if (betAmount < minimumBet) { throw new TakaroUserError(`The minimum bet is ${minimumBet} currency!`); } if (betAmount > maximumBet) { throw new TakaroUserError(`The maximum bet is ${maximumBet} currency!`); } // Check if player is on cooldown const cooldownTime = mod.userConfig.cooldownTime; if (cooldownTime > 0) { // Only check cooldown if it's enabled const cooldownKey = 'roulette_cooldown'; const cooldownVar = await takaro.variable.variableControllerSearch({ filters: { key: [cooldownKey], playerId: [player.id], gameServerId: [gameServerId], moduleId: [mod.moduleId], }, }); if (cooldownVar.data.data.length > 0) { const lastSpinTime = new Date(cooldownVar.data.data[0].value).getTime(); const currentTime = Date.now(); const timeElapsed = currentTime - lastSpinTime; if (timeElapsed < cooldownTime) { const timeRemaining = Math.ceil((cooldownTime - timeElapsed) / 1000); throw new TakaroUserError(`Please wait ${timeRemaining} seconds before spinning again!`); } // Update cooldown await takaro.variable.variableControllerUpdate(cooldownVar.data.data[0].id, { value: new Date().toISOString(), }); } else { // Create cooldown await takaro.variable.variableControllerCreate({ key: cooldownKey, value: new Date().toISOString(), gameServerId, moduleId: mod.moduleId, playerId: player.id, }); } } // Check if player has enough currency const playerData = await takaro.playerOnGameserver.playerOnGameServerControllerGetOne(gameServerId, player.id); const currentBalance = playerData.data.data.currency; if (currentBalance < betAmount) { throw new TakaroUserError(`You need ${betAmount} currency to place this bet. You only have ${currentBalance}.`); } // Deduct the bet amount await takaro.playerOnGameserver.playerOnGameServerControllerDeductCurrency( gameServerId, player.id, { currency: betAmount } ); // Set bet message based on bet type let betMessage = ''; if (betType === 'colorednumber') { betMessage = `${betColor} ${betNumber}`; } else if (betType === 'number') { betMessage = `number ${betNumber}`; } else { betMessage = betType; } // More compact spinning message await player.pm(`π° Bet ${betAmount} on ${betMessage}... The wheel is spinning!`); // Spin the wheel (generate a random number between 0 and 36) const result = Math.floor(Math.random() * 37); const isRed = redNumbers.includes(result); const isBlack = blackNumbers.includes(result); const isEven = result !== 0 && result % 2 === 0; const isOdd = result % 2 === 1; const isHigh = result >= 19 && result <= 36; const isLow = result >= 1 && result <= 18; // Display the result with Unicode for visual effect - more compact let resultColor = isRed ? 'π΄ red' : isBlack ? 'β« black' : 'π’ green'; await player.pm(`π² Result: ${result} ${resultColor}`); // Determine if player won let playerWon = false; let payoutMultiplier = 0; const houseEdge = mod.userConfig.houseEdge / 100; // Convert percentage to decimal switch (betType) { case 'red': payoutMultiplier = 2 * (1 - houseEdge); playerWon = isRed; break; case 'black': payoutMultiplier = 2 * (1 - houseEdge); playerWon = isBlack; break; case 'even': payoutMultiplier = 2 * (1 - houseEdge); playerWon = isEven; break; case 'odd': payoutMultiplier = 2 * (1 - houseEdge); playerWon = isOdd; break; case 'high': payoutMultiplier = 2 * (1 - houseEdge); playerWon = isHigh; break; case 'low': payoutMultiplier = 2 * (1 - houseEdge); playerWon = isLow; break; case 'number': payoutMultiplier = 36 * (1 - houseEdge); playerWon = (result === betNumber); break; case 'colorednumber': // For colored number bets, we need both the number AND color to match payoutMultiplier = 72 * (1 - houseEdge); // Double the normal number bet payout playerWon = (result === betNumber) && ((betColor === 'red' && isRed) || (betColor === 'black' && isBlack)); break; } // Update player stats await updatePlayerStats(player.id, gameServerId, mod.moduleId, betAmount, playerWon); // Pay out winnings if player won if (playerWon) { const winnings = Math.floor(betAmount * payoutMultiplier); await takaro.playerOnGameserver.playerOnGameServerControllerAddCurrency( gameServerId, player.id, { currency: winnings } ); // More compact win message await player.pm(`π° You win! +${winnings} currency! π°`); // Broadcast big wins to everyone if (winnings >= 1000) { await takaro.gameserver.gameServerControllerSendMessage(gameServerId, { message: `π° ${player.name} just won ${winnings} currency at roulette with a bet on ${betMessage}!` }); } } else { // More compact loss message await player.pm(`β You lose! Better luck next time!`); } // Get updated balance const updatedPlayerData = await takaro.playerOnGameserver.playerOnGameServerControllerGetOne(gameServerId, player.id); await player.pm(`Balance: ${updatedPlayerData.data.data.currency} currency`); } async function updatePlayerStats(playerId, gameServerId, moduleId, betAmount, won) { const statsKey = 'roulette_stats'; const statsSearch = await takaro.variable.variableControllerSearch({ filters: { key: [statsKey], playerId: [playerId], gameServerId: [gameServerId], moduleId: [moduleId], }, }); let stats = { played: 0, won: 0, lost: 0, totalWagered: 0, }; if (statsSearch.data.data.length > 0) { stats = JSON.parse(statsSearch.data.data[0].value); await takaro.variable.variableControllerUpdate(statsSearch.data.data[0].id, { value: JSON.stringify({ played: stats.played + 1, won: stats.won + (won ? 1 : 0), lost: stats.lost + (won ? 0 : 1), totalWagered: stats.totalWagered + betAmount, }), }); } else { await takaro.variable.variableControllerCreate({ key: statsKey, value: JSON.stringify({ played: 1, won: won ? 1 : 0, lost: won ? 0 : 1, totalWagered: betAmount, }), gameServerId, moduleId: moduleId, playerId: playerId, }); } } await main();
Permissions 3
Roles you can grant to decide who may use what.
-
Play Roulette
Allows the player to place bets and play roulette.
-
Higher Betting Limits
Allows the player to exceed the normal maximum bet. Count is multiplier for max bet.
-
Roulette Admin
Allows resetting player statistics and other administrative functions.