7dtd_triviaTime

  • community
  • minigames
  • by limon
  • Takaro v0.2.1
  • 7 Days to Die
Version
View export JSON

Limon_triviaTime: Interactive Trivia Game System

The Limon_triviaTime module transforms your gaming server with an engaging trivia game system that automatically poses questions and rewards correct answers. This enhanced version supports both the Open Trivia Database API and custom questions.

Key Benefits:

  • Dual Question Sources: Choose between Open Trivia Database API or custom questions
  • Rich Category Selection: Access to 20+ categories from the API including General Knowledge, Science, Sports, History, and more
  • Difficulty Control: Easy, Medium, and Hard difficulty levels
  • Flexible Question Types: Support for True/False and Multiple Choice questions
  • Flexible Reward System: Choose between currency or item rewards for winners
  • Automated Scheduling: Set trivia events to run at specified intervals
  • Player Engagement Tool: Keeps your community active and entertained
  • Simple Answer Validation: Easy command-based answer submission system

Features:

  • Open Trivia Database API integration with 4000+ verified questions
  • Configurable question database with pre-populated examples as fallback
  • Dual reward types (currency or items)
  • Customizable item quality and quantity settings
  • Permission-based participation control
  • Automated trivia scheduling with cron jobs
  • Real-time feedback on incorrect answers
  • Server-wide announcements for winners
  • HTML entity decoding for proper question display
  • Session token support to prevent duplicate questions

Ideal for server administrators looking to increase player retention and build community through interactive gameplay elements. Works seamlessly with existing Takaro economy and item systems.

Configuration 11

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

SettingTypeDefaultDescription
questionSource Question Source string "api" Choose between Open Trivia Database API or custom questions
apiCategory API Categories array ["any"] Categories for Open Trivia Database questions (select multiple or 'any')
apiDifficulty API Difficulty string "any" Difficulty level for Open Trivia Database questions
apiType Question Type string "any" Type of questions from API
rewardType Reward Type string "currency" Choose Currency, Items, or Both (random)
rewardAmount Reward Amount number 100 Currency reward amount
rewardItems Items array Items to give as rewards
questions Custom Questions (Fallback) array [{"question":"What is the capital of France?","answer":"Paris"},{"question":"What is the largest planet in our solar system?","answer":"Jupiter"}] Used when API is unavailable or question source is set to custom
triviaStartSound Trivia Start Sound string "ui_click" Sound to play to all players when a new trivia question is posted (leave empty to disable)
correctAnswerSound Correct Answer Sound string "ui_unlock" Sound to play to all players when someone answers correctly (leave empty to disable)
wrongAnswerSound Wrong Answer Sound string "ui_denied" Sound to play to the player when they answer incorrectly (leave empty to disable)
Raw config schema
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "questionSource": {
      "title": "Question Source",
      "description": "Choose between Open Trivia Database API or custom questions",
      "type": "string",
      "enum": [
        "api",
        "custom"
      ],
      "default": "api"
    },
    "apiCategory": {
      "title": "API Categories",
      "description": "Categories for Open Trivia Database questions (select multiple or 'any')",
      "type": "array",
      "items": {
        "type": "string",
        "enum": [
          "any",
          "general_knowledge",
          "books",
          "film",
          "music",
          "musicals_theatres",
          "television",
          "video_games",
          "board_games",
          "science_nature",
          "computers",
          "mathematics",
          "mythology",
          "sports",
          "geography",
          "history",
          "politics",
          "art",
          "celebrities",
          "animals",
          "vehicles",
          "comics",
          "gadgets",
          "anime_manga",
          "cartoon_animations"
        ]
      },
      "uniqueItems": true,
      "default": [
        "any"
      ]
    },
    "apiDifficulty": {
      "title": "API Difficulty",
      "description": "Difficulty level for Open Trivia Database questions",
      "type": "string",
      "enum": [
        "any",
        "easy",
        "medium",
        "hard"
      ],
      "default": "any"
    },
    "apiType": {
      "title": "Question Type",
      "description": "Type of questions from API",
      "type": "string",
      "enum": [
        "any",
        "multiple",
        "boolean"
      ],
      "default": "any"
    },
    "rewardType": {
      "title": "Reward Type",
      "description": "Choose Currency, Items, or Both (random)",
      "default": "currency",
      "type": "string",
      "enum": [
        "currency",
        "items",
        "both"
      ]
    },
    "rewardAmount": {
      "title": "Reward Amount",
      "description": "Currency reward amount",
      "default": 100,
      "type": "number",
      "minimum": 1,
      "maximum": 100000
    },
    "rewardItems": {
      "title": "Items",
      "description": "Items to give as rewards",
      "x-component": "item",
      "type": "array",
      "uniqueItems": true,
      "items": {
        "type": "object",
        "title": "Item",
        "properties": {
          "item": {
            "type": "string",
            "title": "Item"
          },
          "amount": {
            "type": "number",
            "title": "Amount"
          },
          "quality": {
            "type": "string",
            "title": "Quality"
          }
        }
      }
    },
    "questions": {
      "type": "array",
      "title": "Custom Questions (Fallback)",
      "description": "Used when API is unavailable or question source is set to custom",
      "items": {
        "type": "object",
        "properties": {
          "question": {
            "type": "string",
            "description": "The question",
            "minLength": 1
          },
          "answer": {
            "type": "string",
            "description": "The answer"
          }
        }
      },
      "default": [
        {
          "question": "What is the capital of France?",
          "answer": "Paris"
        },
        {
          "question": "What is the largest planet in our solar system?",
          "answer": "Jupiter"
        }
      ]
    },
    "triviaStartSound": {
      "title": "Trivia Start Sound",
      "description": "Sound to play to all players when a new trivia question is posted (leave empty to disable)",
      "type": "string",
      "default": "ui_click"
    },
    "correctAnswerSound": {
      "title": "Correct Answer Sound",
      "description": "Sound to play to all players when someone answers correctly (leave empty to disable)",
      "type": "string",
      "default": "ui_unlock"
    },
    "wrongAnswerSound": {
      "title": "Wrong Answer Sound",
      "description": "Sound to play to the player when they answer incorrectly (leave empty to disable)",
      "type": "string",
      "default": "ui_denied"
    }
  },
  "additionalProperties": false
}
Raw UI schema
{
  "rewardItems": {
    "items": {
      "item": {
        "ui:widget": "item"
      }
    }
  }
}

Commands 3

Chat commands players trigger in game.

  • playerAnswer

    Submit your answer to the current trivia question

    ArgumentTypeDefaultHelp
    answer string provide an answer
    Command source
    import { takaro, data, TakaroUserError } from '@takaro/helpers';
    
    async function main() {
        const { player, arguments: args, gameServerId, module: mod, pog } = data;
    
        // Helper function to play sound to all online players
        async function playSoundToPlayers(gameServerId, soundId, repeats = 1) {
            if (!soundId || soundId.trim() === '') {
                return; // Skip if no sound specified
            }
    
            // Get all online players
            const onlinePlayersRes = await takaro.playerOnGameserver.playerOnGameServerControllerSearch({
                filters: {
                    gameServerId: [gameServerId],
                    online: [true]
                }
            });
    
            for (const pogPlayer of onlinePlayersRes.data.data) {
                const targetId = pogPlayer.gameId;
    
                if (!targetId) {
                    console.log('No valid player ID found, skipping player');
                    continue;
                }
    
                const command = `playsound EOS_${targetId} ${soundId}`;
    
                for (let i = 0; i < repeats; i++) {
                    await takaro.gameserver.gameServerControllerExecuteCommand(gameServerId, {
                        command: command
                    });
                }
            }
        }
    
        // Helper function to play sound to a specific player
        async function playSoundToPlayer(gameServerId, playerId, soundId, repeats = 1) {
            if (!soundId || soundId.trim() === '') {
                return; // Skip if no sound specified
            }
    
            // Get the specific player's game ID
            const playerRes = await takaro.playerOnGameserver.playerOnGameServerControllerSearch({
                filters: {
                    gameServerId: [gameServerId],
                    playerId: [playerId],
                    online: [true]
                }
            });
    
            if (playerRes.data.data.length === 0) {
                console.log('Player not found or not online');
                return;
            }
    
            const targetId = playerRes.data.data[0].gameId;
    
            if (!targetId) {
                console.log('No valid player ID found');
                return;
            }
    
            const command = `playsound EOS_${targetId} ${soundId}`;
    
            for (let i = 0; i < repeats; i++) {
                await takaro.gameserver.gameServerControllerExecuteCommand(gameServerId, {
                    command: command
                });
            }
        }
    
        if (!args.answer || args.answer.trim() === '') {
            throw new TakaroUserError('Please provide an answer!');
        }
    
        // Check if there's an active trivia question
        const questionVariable = await takaro.variable.variableControllerSearch({
            filters: {
                key: ['trivia_question'],
                gameServerId: [gameServerId],
                moduleId: [mod.moduleId]
            }
        });
    
        if (questionVariable.data.data.length === 0) {
            throw new TakaroUserError('No active trivia question! Wait for the next one.');
        }
    
        // Get the correct answer
        const answerVariable = await takaro.variable.variableControllerSearch({
            filters: {
                key: ['trivia_answer'],
                gameServerId: [gameServerId],
                moduleId: [mod.moduleId]
            }
        });
    
        if (answerVariable.data.data.length === 0) {
            throw new TakaroUserError('No answer found for the current question.');
        }
    
        // Get reward info
        const rewardVariable = await takaro.variable.variableControllerSearch({
            filters: {
                key: ['trivia_reward'],
                gameServerId: [gameServerId],
                moduleId: [mod.moduleId]
            }
        });
    
        if (rewardVariable.data.data.length === 0) {
            throw new TakaroUserError('No reward configured for this trivia.');
        }
    
        const correctAnswer = answerVariable.data.data[0].value;
        const playerAnswer = args.answer.trim();
    
        // Normalize answers for comparison (lowercase, remove extra spaces)
        const normalizeAnswer = (answer) => {
            return answer.toLowerCase().replace(/\s+/g, ' ').trim();
        };
    
        const normalizedCorrectAnswer = normalizeAnswer(correctAnswer);
        const normalizedPlayerAnswer = normalizeAnswer(playerAnswer);
    
        console.log(`Player ${player.name} answered: "${playerAnswer}" (normalized: "${normalizedPlayerAnswer}")`);
        console.log(`Correct answer: "${correctAnswer}" (normalized: "${normalizedCorrectAnswer}")`);
    
        // Check if the answer is correct
        if (normalizedPlayerAnswer === normalizedCorrectAnswer) {
            // Give reward
            const rewardData = JSON.parse(rewardVariable.data.data[0].value);
    
            let rewardMessage = '';
    
            if (rewardData.type === 'currency') {
                await takaro.playerOnGameserver.playerOnGameServerControllerAddCurrency(gameServerId, player.id, {
                    currency: rewardData.amount
                });
    
                const currencyName = (await takaro.settings.settingsControllerGetOne('currencyName', gameServerId)).data.data.value;
                rewardMessage = `You won ${rewardData.amount} ${currencyName}!`;
    
            } else if (rewardData.type === 'items') {
                const item = (await takaro.item.itemControllerFindOne(rewardData.itemId)).data.data;
    
                await takaro.gameserver.gameServerControllerGiveItem(gameServerId, player.id, {
                    name: item.code,
                    amount: rewardData.amount,
                    quality: rewardData.quality || ''
                });
    
                rewardMessage = `You won ${rewardData.amount}x ${item.name}!`;
            }
    
            // 🆕 WIN TRACKING - Record the player's win
            const winKey = `trivia_wins_${player.id}`;
            const existingWins = await takaro.variable.variableControllerSearch({
                filters: {
                    key: [winKey],
                    gameServerId: [gameServerId],
                    moduleId: [mod.moduleId]
                }
            });
    
            let totalWins = 1;
            if (existingWins.data.data.length > 0) {
                totalWins = parseInt(existingWins.data.data[0].value) + 1;
                await takaro.variable.variableControllerUpdate(existingWins.data.data[0].id, {
                    value: totalWins.toString()
                });
            } else {
                await takaro.variable.variableControllerCreate({
                    key: winKey,
                    value: '1',
                    gameServerId,
                    moduleId: mod.moduleId,
                    playerId: player.id
                });
            }
    
            // Success message with total wins
            await takaro.gameserver.gameServerControllerSendMessage(gameServerId, {
                message: `🎉 ${player.name} got it right! The answer was: ${correctAnswer}. ${rewardMessage} (Total wins: ${totalWins})`
            });
    
            // Play correct answer sound to all online players
            const correctAnswerSound = mod.userConfig.correctAnswerSound;
            if (correctAnswerSound) {
                await playSoundToPlayers(gameServerId, correctAnswerSound, 1);
            }
    
            // Clean up trivia variables
            const variablesToClean = await takaro.variable.variableControllerSearch({
                filters: {
                    key: ['trivia_question', 'trivia_answer', 'trivia_reward', 'trivia_type', 'trivia_incorrect_answers'],
                    gameServerId: [gameServerId],
                    moduleId: [mod.moduleId]
                }
            });
    
            await Promise.all(variablesToClean.data.data.map(variable =>
                takaro.variable.variableControllerDelete(variable.id)
            ));
    
            console.log(`${player.name} answered correctly and won! Total wins: ${totalWins}`);
    
        } else {
            // Wrong answer - play sound only to the player who answered incorrectly
            const wrongAnswerSound = mod.userConfig.wrongAnswerSound;
            if (wrongAnswerSound) {
                await playSoundToPlayer(gameServerId, player.id, wrongAnswerSound, 1);
            }
    
            // Wrong answer message
            await player.pm(`❌ Sorry, "${playerAnswer}" is not correct. Try again!`);
            console.log(`${player.name} answered incorrectly.`);
        }
    }
    
    await main();
  • triviareset

    No help text available

    Command source
    import { takaro, data, checkPermission, TakaroUserError } from '@takaro/helpers';
    
    async function main() {
        const { gameServerId, module: mod, pog, player } = data;
    
        // Check permission
        if (!checkPermission(pog, 'TRIVIA_RESET_LEADERBOARD')) {
            throw new TakaroUserError('You do not have permission to reset the trivia leaderboard.');
        }
    
        // Get all trivia-related variables for this server
        const triviaVariables = await takaro.variable.variableControllerSearch({
            filters: {
                gameServerId: [gameServerId],
                moduleId: [mod.moduleId]
            },
            search: {
                key: ['trivia_wins_', 'trivia_question', 'trivia_answer', 'trivia_reward', 'trivia_type', 'trivia_incorrect_answers']
            },
            limit: 1000
        });
    
        if (triviaVariables.data.data.length === 0) {
            await player.pm('🗑️ No trivia data found to reset.');
            return;
        }
    
        // Delete all trivia variables
        const deletePromises = triviaVariables.data.data.map(variable =>
            takaro.variable.variableControllerDelete(variable.id)
        );
    
        await Promise.allSettled(deletePromises);
    
        // Send confirmation
        const winsCount = triviaVariables.data.data.filter(v => v.key.startsWith('trivia_wins_')).length;
    
        await player.pm(`🗑️ Trivia leaderboard reset successfully! Cleared ${winsCount} player records.`);
    
        // Announce to server
        await takaro.gameserver.gameServerControllerSendMessage(gameServerId, {
            message: `🔄 Trivia leaderboard has been reset by an administrator!`
        });
    
        console.log(`Trivia leaderboard reset by player ${player.name} (${player.id})`);
    }
    
    await main();
  • triviaboard

    No help text available

    Command source
    import { takaro, data } from '@takaro/helpers';
    
    async function main() {
        const { gameServerId, module: mod, player } = data;
    
        // Get all trivia wins for this server
        const allWins = await takaro.variable.variableControllerSearch({
            filters: {
                gameServerId: [gameServerId],
                moduleId: [mod.moduleId]
            },
            search: {
                key: ['trivia_wins_']
            },
            limit: 1000
        });
    
        if (allWins.data.data.length === 0) {
            await player.pm('🏆 No trivia winners yet! Be the first to answer a question correctly!');
            return;
        }
    
        // Sort by wins (stored as string, so convert to number)
        const sortedWins = allWins.data.data
            .map(record => ({
                playerId: record.playerId,
                wins: parseInt(record.value) || 0
            }))
            .sort((a, b) => b.wins - a.wins)
            .slice(0, mod.userConfig.leaderboardSize || 10);
    
        // Get player names
        const leaderboard = await Promise.all(
            sortedWins.map(async (record, index) => {
                const playerData = await takaro.player.playerControllerGetOne(record.playerId);
                return {
                    position: index + 1,
                    name: playerData.data.data.name,
                    wins: record.wins
                };
            })
        );
    
        // Build leaderboard message
        let message = '🏆 **Trivia Leaderboard** 🧠\n\n';
    
        leaderboard.forEach(entry => {
            const medal = entry.position === 1 ? '🥇' : entry.position === 2 ? '🥈' : entry.position === 3 ? '🥉' : '  ';
            message += `${medal} ${entry.position}. ${entry.name} - ${entry.wins} win${entry.wins !== 1 ? 's' : ''}\n`;
        });
    
        // Add current player's ranking if not in top list
        const currentPlayerWins = sortedWins.find(record => record.playerId === player.id);
        if (!currentPlayerWins && allWins.data.data.some(record => record.playerId === player.id)) {
            const playerRecord = allWins.data.data.find(record => record.playerId === player.id);
            const playerWins = parseInt(playerRecord.value) || 0;
            const playerRank = allWins.data.data
                .map(record => parseInt(record.value) || 0)
                .sort((a, b) => b - a)
                .findIndex(wins => wins <= playerWins) + 1;
    
            message += `\n📍 Your rank: #${playerRank} with ${playerWins} win${playerWins !== 1 ? 's' : ''}`;
        }
    
        await player.pm(message);
    }
    
    await main();

Cron jobs 1

Work the module runs on a schedule.

  • TriviaTime

    Cron job source
    import { takaro, data } from '@takaro/helpers';
    
    async function main() {
        const { gameServerId, module: mod } = data;
    
        // Helper function to play sound to all online players
        async function playSoundToPlayers(gameServerId, players, soundId, repeats = 1) {
            if (!soundId || soundId.trim() === '') {
                return; // Skip if no sound specified
            }
    
            for (const pog of players) {
                const targetId = pog.gameId;
    
                if (!targetId) {
                    console.log('No valid player ID found, skipping player');
                    continue;
                }
    
                const command = `playsound EOS_${targetId} ${soundId}`;
    
                for (let i = 0; i < repeats; i++) {
                    await takaro.gameserver.gameServerControllerExecuteCommand(gameServerId, {
                        command: command
                    });
                }
            }
        }
    
        // Check for online players
        const currentPlayersRes = await takaro.playerOnGameserver.playerOnGameServerControllerSearch({
            filters: {
                gameServerId: [gameServerId],
                online: [true]
            }
        });
    
        if (currentPlayersRes.data.data.length === 0) {
            console.log('No online players, skipping trivia');
            return;
        }
    
        console.log(`Found ${currentPlayersRes.data.data.length} online players`);
    
        // Clear existing variables first
        const existingVariables = await takaro.variable.variableControllerSearch({
            filters: {
                key: ['trivia_question', 'trivia_answer', 'trivia_reward', 'trivia_type', 'trivia_incorrect_answers'],
                gameServerId: [gameServerId],
                moduleId: [mod.moduleId]
            }
        });
    
        await Promise.all(existingVariables.data.data.map(variable =>
            takaro.variable.variableControllerDelete(variable.id)
        ));
    
        let questionData = null;
        let questionSource = mod.userConfig.questionSource || 'api';
    
        if (questionSource === 'api') {
            console.log('Attempting to fetch from Open Trivia Database API using Axios');
    
            try {
                // Check if axios is available
                if (takaro.axios) {
                    console.log('Axios is available! Making API request...');
    
                    // Build API URL
                    let url = 'https://opentdb.com/api.php?amount=1';
    
                    // Add categories if specified
                    const categories = mod.userConfig.apiCategory || ['any'];
                    if (categories.length > 0 && !categories.includes('any')) {
                        const categoryMap = {
                            'general_knowledge': 9, 'books': 10, 'film': 11, 'music': 12,
                            'musicals_theatres': 13, 'television': 14, 'video_games': 15,
                            'board_games': 16, 'science_nature': 17, 'computers': 18,
                            'mathematics': 19, 'mythology': 20, 'sports': 21, 'geography': 22,
                            'history': 23, 'politics': 24, 'art': 25, 'celebrities': 26,
                            'animals': 27, 'vehicles': 28, 'comics': 29, 'gadgets': 30,
                            'anime_manga': 31, 'cartoon_animations': 32
                        };
    
                        const randomCategory = categories[Math.floor(Math.random() * categories.length)];
                        const categoryId = categoryMap[randomCategory];
                        if (categoryId) {
                            url += `&category=${categoryId}`;
                        }
                    }
    
                    // Add difficulty if specified
                    if (mod.userConfig.apiDifficulty && mod.userConfig.apiDifficulty !== 'any') {
                        url += `&difficulty=${mod.userConfig.apiDifficulty}`;
                    }
    
                    // Add type if specified
                    if (mod.userConfig.apiType && mod.userConfig.apiType !== 'any') {
                        url += `&type=${mod.userConfig.apiType}`;
                    }
    
                    console.log('Fetching trivia question from:', url);
    
                    // Make the API request using Axios
                    const response = await takaro.axios.get(url);
                    const apiData = response.data;
    
                    console.log('API Response:', JSON.stringify(apiData));
    
                    if (apiData.response_code === 0 && apiData.results && apiData.results.length > 0) {
                        const question = apiData.results[0];
    
                        questionData = {
                            question: decodeHtmlEntities(question.question),
                            answer: decodeHtmlEntities(question.correct_answer),
                            type: question.type,
                            incorrectAnswers: question.incorrect_answers ? question.incorrect_answers.map(decodeHtmlEntities) : []
                        };
                        console.log('Successfully fetched API question:', questionData.question);
                    } else {
                        console.log('API returned error or no results:', apiData);
                        questionSource = 'custom';
                    }
                } else {
                    console.log('Axios not available, falling back to custom questions');
                    questionSource = 'custom';
                }
            } catch (error) {
                console.log('API failed, falling back to custom questions:', error.message);
                questionSource = 'custom';
            }
        }
    
        if (questionSource === 'custom' || !questionData) {
            console.log('Using custom questions');
            const questions = mod.userConfig.questions || [
                { question: "What is the largest country in the world?", answer: "Russia" },
                { question: "What is the capital of France?", answer: "Paris" },
                { question: "What is 2 + 2?", answer: "4" }
            ];
    
            const randomQuestion = questions[Math.floor(Math.random() * questions.length)];
            questionData = {
                question: randomQuestion.question,
                answer: randomQuestion.answer,
                type: 'multiple',
                incorrectAnswers: []
            };
        }
    
        if (!questionData) {
            console.log('No question data available');
            return;
        }
    
        // Store question data
        await takaro.variable.variableControllerCreate({
            key: 'trivia_question',
            value: questionData.question,
            gameServerId,
            moduleId: mod.moduleId
        });
    
        await takaro.variable.variableControllerCreate({
            key: 'trivia_answer',
            value: questionData.answer,
            gameServerId,
            moduleId: mod.moduleId
        });
    
        await takaro.variable.variableControllerCreate({
            key: 'trivia_type',
            value: questionData.type,
            gameServerId,
            moduleId: mod.moduleId
        });
    
        if (questionData.incorrectAnswers.length > 0) {
            await takaro.variable.variableControllerCreate({
                key: 'trivia_incorrect_answers',
                value: JSON.stringify(questionData.incorrectAnswers),
                gameServerId,
                moduleId: mod.moduleId
            });
        }
    
        // Setup reward - Updated to handle "both" option
        const rewardType = mod.userConfig.rewardType || 'currency';
        let selectedRewardType = rewardType;
    
        // If "both" is selected, randomly choose between currency and items
        if (rewardType === 'both') {
            selectedRewardType = Math.random() < 0.5 ? 'currency' : 'items';
        }
    
        if (selectedRewardType === 'items') {
            const configuredItems = mod.userConfig.rewardItems || [];
            if (configuredItems.length > 0) {
                const randomItemIndex = Math.floor(Math.random() * configuredItems.length);
                const selectedItem = configuredItems[randomItemIndex];
    
                await takaro.variable.variableControllerCreate({
                    key: 'trivia_reward',
                    value: JSON.stringify({
                        type: 'items',
                        itemId: selectedItem.item,
                        amount: selectedItem.amount || 1,
                        quality: selectedItem.quality || ''
                    }),
                    gameServerId,
                    moduleId: mod.moduleId
                });
            } else {
                console.error('Items reward type selected but no items configured, falling back to currency');
                await takaro.variable.variableControllerCreate({
                    key: 'trivia_reward',
                    value: JSON.stringify({
                        type: 'currency',
                        amount: mod.userConfig.rewardAmount || 100
                    }),
                    gameServerId,
                    moduleId: mod.moduleId
                });
            }
        } else {
            // Currency reward
            await takaro.variable.variableControllerCreate({
                key: 'trivia_reward',
                value: JSON.stringify({
                    type: 'currency',
                    amount: mod.userConfig.rewardAmount || 100
                }),
                gameServerId,
                moduleId: mod.moduleId
            });
        }
    
        const prefix = (await takaro.settings.settingsControllerGetOne('commandPrefix', gameServerId)).data.data.value;
    
        // Create appropriate message based on question type
        let message = `🧠 Trivia Time! ${questionData.question}`;
    
        if (questionData.type === 'boolean') {
            message += ` (Answer with ${prefix}answer true or ${prefix}answer false)`;
        } else if (questionData.incorrectAnswers.length > 0) {
            const allAnswers = [questionData.answer, ...questionData.incorrectAnswers]
                .sort(() => Math.random() - 0.5);
    
            message += `\nOptions: ${allAnswers.join(', ')} (Answer with ${prefix}answer <your choice>)`;
        } else {
            message += ` (Answer with ${prefix}answer <your guess>)`;
        }
    
        // Send the message first
        await takaro.gameserver.gameServerControllerSendMessage(gameServerId, {
            message: message
        });
    
        // Play trivia start sound to all online players
        const triviaStartSound = mod.userConfig.triviaStartSound;
        if (triviaStartSound) {
            await playSoundToPlayers(gameServerId, currentPlayersRes.data.data, triviaStartSound, 1);
        }
    
        console.log('Trivia question posted successfully');
    }
    
    function decodeHtmlEntities(text) {
        if (!text) return text;
    
        const entityMap = {
            '&amp;': '&', '&lt;': '<', '&gt;': '>', '&quot;': '"', '&#039;': "'", '&apos;': "'",
            '&nbsp;': ' ', '&eacute;': 'é', '&egrave;': 'è', '&ecirc;': 'ê', '&euml;': 'ë',
            '&aacute;': 'á', '&agrave;': 'à', '&acirc;': 'â', '&auml;': 'ä',
            '&iacute;': 'í', '&igrave;': 'ì', '&icirc;': 'î', '&iuml;': 'ï',
            '&oacute;': 'ó', '&ograve;': 'ò', '&ocirc;': 'ô', '&ouml;': 'ö',
            '&uacute;': 'ú', '&ugrave;': 'ù', '&ucirc;': 'û', '&uuml;': 'ü',
            '&ntilde;': 'ñ', '&ccedil;': 'ç'
        };
    
        let decoded = text;
        for (const [entity, char] of Object.entries(entityMap)) {
            decoded = decoded.replace(new RegExp(entity, 'g'), char);
        }
    
        decoded = decoded.replace(/&#(\d+);/g, (match, num) => {
            return String.fromCharCode(parseInt(num, 10));
        });
    
        return decoded;
    }
    
    await main();

Permissions 2

Roles you can grant to decide who may use what.

  • Participate in Trivia

    Allows players to participate in trivia games

  • Reset Trivia Leaderboard

    Allows resetting the trivia leaderboard scores