slotMachines

  • community
  • minigames
  • by limon
  • Takaro v0.0.24
  • all
Version
View export JSON

Limon_slotMachines: Casino-Style Gambling for Your Game Server

This module adds an exciting slot machine to your game server, letting players gamble their in-game currency for a chance to win big prizes!

Key Features:

Slots gameplay

  • Authentic Casino Experience: Three-reel slot machine with multiple symbols and varied payouts
  • Visual Animation: Progressive reel reveals with suspenseful animations
  • Big Win Announcements: Server-wide jackpot notifications for big winners
  • Statistics Tracking: Detailed personal gambling stats for each player

Commands:

  • /slots [amount] - Place a bet and spin the slot machine
  • /slotsstats - View your personal gambling statistics
  • /slotsrules - Check payouts, rules and betting information
  • /slotsreset [player] - Admin command to reset player statistics

Slots rules

Winning Combinations:

  • Three matching symbols (Three sevens: 25x your bet!)
  • Three bells: 10x your bet
  • Three plums: 6x your bet
  • Three oranges: 4x your bet
  • Three lemons: 3x your bet
  • Three cherries: 2x your bet
  • Any combination ending with seven: 1.5x your bet

Player Statistics:

Slots statistics

  • Games played, wins, losses, and total currency wagered
  • Win rate percentage calculation

Configuration:

Slot machine configuration

  • minimumBet: Lowest possible wager amount
  • maximumBet: Highest possible wager amount
  • houseEdge: Percentage profit margin for the server

Permissions:

  • SLOTS_PLAY: Basic permission to use the slot machine
  • SLOTS_HIGHER_LIMITS: VIP permission allowing higher maximum bets
  • SLOTS_ADMIN: Administrative access to reset stats and manage the module

Configuration 3

Settings you fill in when installing the module on a server.

SettingTypeDefaultDescription
minimumBet minimumBet number 10 The minimum amount of currency a player can wager on a single spin.
maximumBet maximumBet number 100 The maximum amount of currency a player can wager 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 of currency a player can wager on a single spin.",
      "default": 10,
      "type": "number",
      "minimum": 0
    },
    "maximumBet": {
      "title": "maximumBet",
      "description": "The maximum amount of currency a player can wager 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.

  • slots

    Play the slot machine with a bet amount.

    ArgumentTypeDefaultHelp
    amount number Play the slot machine with a bet amount
    Command source
    import { takaro, data, checkPermission, TakaroUserError } from '@takaro/helpers';
    
    async function main() {
        const { player, gameServerId, arguments: args, module: mod, pog } = data;
    
        // Check permission
        if (!checkPermission(pog, 'SLOTS_PLAY')) {
            throw new TakaroUserError('You do not have permission to play slots!');
        }
    
        // Get bet amount
        const betAmount = Number(args.amount);
    
        // Validate bet amount
        if (isNaN(betAmount) || betAmount <= 0) {
            throw new TakaroUserError('Please enter a valid positive bet amount!');
        }
    
        // Get minimum and maximum bet limits
        const minimumBet = mod.userConfig.minimumBet;
        let maximumBet = mod.userConfig.maximumBet;
    
        // Check higher limits permission
        const higherLimitsPermission = checkPermission(pog, 'SLOTS_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 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 play slots. You only have ${currentBalance}.`);
        }
    
        // Deduct the bet amount
        await takaro.playerOnGameserver.playerOnGameServerControllerDeductCurrency(
            gameServerId,
            player.id,
            {
                currency: betAmount
            }
        );
    
        // Define slot symbols with their text representations
        const symbols = [
            { name: "cherry", symbol: "CH", weight: 30 },
            { name: "lemon", symbol: "LE", weight: 25 },
            { name: "orange", symbol: "OR", weight: 20 },
            { name: "plum", symbol: "PL", weight: 15 },
            { name: "bell", symbol: "BE", weight: 8 },
            { name: "seven", symbol: "7", weight: 2 }
        ];
    
        // Define payouts for different combinations
        const payouts = {
            "cherry-cherry-cherry": 2,
            "lemon-lemon-lemon": 3,
            "orange-orange-orange": 4,
            "plum-plum-plum": 6,
            "bell-bell-bell": 10,
            "seven-seven-seven": 25,
            "any-any-seven": 1.5
        };
    
        // Show initial message with spinning animation
        await player.pm(`Betting ${betAmount} currency`);
        await player.pm(`[SLOTS] [ ?? | ?? | ?? ] Spinning...`);
    
        // Simulate spinning the reels
        const results = spinReels(symbols);
        const resultSymbols = results.map(r => r.name);
        const resultDisplay = results.map(r => r.symbol);
    
        // Display reels one by one with suspense
        await player.pm(`[SLOTS] [ ${resultDisplay[0]} | ?? | ?? ] Spinning...`);
        await player.pm(`[SLOTS] [ ${resultDisplay[0]} | ${resultDisplay[1]} | ?? ] Spinning...`);
    
        // Final result with dramatic pause
        await player.pm(`[SLOTS] [ ${resultDisplay[0]} | ${resultDisplay[1]} | ${resultDisplay[2]} ] !`);
    
        // Calculate winnings
        let winMultiplier = 0;
        let winDescription = "";
    
        // Check for three of a kind
        if (resultSymbols[0] === resultSymbols[1] && resultSymbols[1] === resultSymbols[2]) {
            const key = `${resultSymbols[0]}-${resultSymbols[1]}-${resultSymbols[2]}`;
            winMultiplier = payouts[key] || 0;
            winDescription = `Three ${resultSymbols[0]}s`;
        }
        // Check for "any-any-seven" combination
        else if (resultSymbols[2] === "seven") {
            winMultiplier = payouts["any-any-seven"];
            winDescription = "Any combination ending with seven";
        }
    
        // Apply house edge
        const houseEdge = mod.userConfig.houseEdge / 100;
        winMultiplier = winMultiplier * (1 - houseEdge);
    
        // Calculate final winnings
        const winnings = Math.floor(betAmount * winMultiplier);
    
        // Update player stats
        await updatePlayerStats(player.id, gameServerId, mod.moduleId, betAmount, winnings > 0);
    
        // Handle result with visual flair based on win size
        if (winnings > 0) {
            // Add winnings to player
            await takaro.playerOnGameserver.playerOnGameServerControllerAddCurrency(
                gameServerId,
                player.id,
                {
                    currency: winnings
                }
            );
    
            // Different win messages based on win size
            if (winnings >= 1000) {
                await player.pm(`!!! JACKPOT !!! JACKPOT !!! JACKPOT !!!`);
                await player.pm(`*** ${winDescription}: +${winnings} CURRENCY! ***`);
    
                // Broadcast big wins
                await takaro.gameserver.gameServerControllerSendMessage(gameServerId, {
                    message: `[SLOTS] JACKPOT! ${player.name} just won ${winnings} currency with ${resultDisplay.join(' ')}`
                });
            }
            else if (winnings >= 500) {
                await player.pm(`** BIG WIN! **`);
                await player.pm(`* ${winDescription}: +${winnings} currency! *`);
            }
            else {
                await player.pm(`Winner! ${winDescription}: +${winnings} currency!`);
            }
        } else {
            // Losing message
            await player.pm(`X No winning combination. Better luck next time! X`);
        }
    
        // Get updated balance
        const updatedPlayerData = await takaro.playerOnGameserver.playerOnGameServerControllerGetOne(gameServerId, player.id);
        await player.pm(`Balance: ${updatedPlayerData.data.data.currency} currency`);
    }
    
    // Function to simulate spinning the reels
    function spinReels(symbols) {
        const results = [];
    
        for (let i = 0; i < 3; i++) {
            // Calculate total weight
            const totalWeight = symbols.reduce((sum, symbol) => sum + symbol.weight, 0);
    
            // Generate random number
            let random = Math.random() * totalWeight;
            let selectedSymbol = null;
    
            // Select symbol based on weight
            for (const symbol of symbols) {
                random -= symbol.weight;
                if (random <= 0) {
                    selectedSymbol = symbol;
                    break;
                }
            }
    
            results.push(selectedSymbol);
        }
    
        return results;
    }
    
    async function updatePlayerStats(playerId, gameServerId, moduleId, betAmount, won) {
        const statsKey = 'slots_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();
  • slotsstats

    Shows your slot machine statistics

    Command source
    import { takaro, data } from '@takaro/helpers';
    
    async function main() {
        const { player, gameServerId, module: mod } = data;
    
        const statsKey = 'slots_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 slot machine 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;
    
        // Stats display
        const statsDisplay = [
            `🎰 SLOT MACHINE 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();
  • slotsreset

    Reset a player's slot machine statistics (admin only)

    ArgumentTypeDefaultHelp
    player string Reset a player's slot machine statistics (admin only)
    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, 'SLOTS_ADMIN')) {
            throw new TakaroUserError('You do not have permission to reset slot machine 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 = 'slots_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 slot machine statistics found for ${targetPlayerName}.`);
        }
    
        // Delete the stats variable
        await takaro.variable.variableControllerDelete(statsSearch.data.data[0].id);
    
        // Also delete any cooldown variables
        const cooldownKey = 'slots_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 slot machine statistics for ${targetPlayerName}.`);
    
        // Log the action
        await takaro.gameserver.gameServerControllerExecuteCommand(gameServerId, {
            command: `say [Admin] ${player.name} has reset ${targetPlayerName}'s slot machine statistics.`,
        });
    }
    
    await main();
  • slotsrules

    Shows the rules and payouts for the slot machine

    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;
    
        // Rules introduction
        const rules1 = [
            `[SLOTS] SLOT MACHINE RULES`,
            '',
            `Minimum bet: ${minimumBet} currency`,
            `Maximum bet: ${maximumBet} currency`,
            `House edge: ${houseEdge}%`,
        ];
    
        // Symbol information
        const rules2 = [
            'SYMBOLS AND PAYOUTS:',
            '',
            'CH Three Cherries: 2x your bet',
            'LE Three Lemons: 3x your bet',
            'OR Three Oranges: 4x your bet',
            'PL Three Plums: 6x your bet',
            'BE Three Bells: 10x your bet',
            '7  Three Sevens: 25x your bet',
            'Any combination ending with 7: 1.5x your bet',
        ];
    
        // Examples and additional info
        const rules3 = [
            'HOW TO PLAY:',
            '/slots 50 - Bet 50 currency on a spin',
            '',
            'Use /slotsstats 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();

Permissions 3

Roles you can grant to decide who may use what.

  • Play Slots

    Allows the player to play the slot machine.

  • Higher Betting Limits

    Allows the player to exceed the normal maximum bet. Count is multiplier for max bet.

  • Slots Admin

    Allows resetting player statistics and other administrative functions.