{
  "name": "Hangman",
  "author": "limon",
  "supportedGames": [
    "all"
  ],
  "takaroVersion": "v0.0.21",
  "versions": [
    {
      "tag": "0.0.1",
      "description": "A classic Hangman game where players guess letters to reveal a hidden word.",
      "configSchema": "{\"$schema\":\"http://json-schema.org/draft-07/schema#\",\"type\":\"object\",\"required\":[],\"additionalProperties\":false,\"properties\":{\"maxWrongGuesses\":{\"title\":\"maxWrongGuesses\",\"description\":\"Maximum number of wrong guesses allowed before the game ends.\",\"default\":6,\"type\":\"number\",\"minimum\":1,\"maximum\":100},\"winReward\":{\"title\":\"winReward\",\"description\":\"Amount of currency to reward the player who guesses the word correctly.\",\"default\":100,\"type\":\"number\"},\"hostReward\":{\"title\":\"hostReward\",\"description\":\"Amount of currency to reward the player who hosts the game if nobody guesses the word.\",\"default\":50,\"type\":\"number\"},\"gameTimeout\":{\"title\":\"gameTimeout\",\"description\":\"Maximum time a game can run before automatically ending.\",\"default\":60000,\"x-component\":\"duration\",\"type\":\"number\"},\"minWordLength\":{\"title\":\"minWordLength\",\"description\":\"Minimum length of words that can be used in the game.\",\"default\":4,\"type\":\"number\",\"minimum\":3},\"maxWordLength\":{\"title\":\"maxWordLength\",\"description\":\"Maximum length of words that can be used in the game.\",\"default\":15,\"type\":\"number\",\"minimum\":5},\"entryFee\":{\"title\":\"entryFee\",\"description\":\"Cost to join a Hangman game\",\"default\":10,\"type\":\"number\"},\"guessPrice\":{\"title\":\"guessPrice\",\"description\":\"Cost per letter guess\",\"default\":0,\"type\":\"number\"},\"hostingFee\":{\"title\":\"hostingFee\",\"description\":\"Cost to create and host a new Hangman game\",\"default\":20,\"type\":\"number\"}}}",
      "uiSchema": "{}",
      "commands": [
        {
          "name": "hangmanReveal",
          "trigger": "hangmanreveal",
          "helpText": "No help text available",
          "function": "// commands/hangmanReveal.js\nimport { takaro, data, TakaroUserError, checkPermission } from '@takaro/helpers';\nimport { getGameState, saveGameState } from './utils.js';\n\nasync function main() {\n    const { player, gameServerId, module: mod, pog } = data;\n\n    // Check if there's a game in progress\n    const gameState = await getGameState(gameServerId, mod.moduleId);\n    if (!gameState) {\n        throw new TakaroUserError('There is no Hangman game in progress!');\n    }\n\n    // Check if player has permission to reveal\n    const isHost = gameState.hostId === player.id;\n    const isAdmin = checkPermission(pog, 'HANGMAN_ADMIN');\n\n    if (!isHost && !isAdmin) {\n        throw new TakaroUserError('Only the game host or an admin can reveal the word!');\n    }\n\n    // Reveal the word and end the game\n    await takaro.gameserver.gameServerControllerSendMessage(gameServerId, {\n        message: `${player.name} has revealed the word: ${gameState.word}`\n    });\n\n    // Clear game state\n    await clearGameState(gameServerId, mod.moduleId);\n    return { success: true };\n}\n\nawait main();",
          "arguments": []
        },
        {
          "name": "hangmanStatus",
          "trigger": "hangmanstatus",
          "helpText": "No help text available",
          "function": "// commands/hangmanStatus.js\nimport { takaro, data, TakaroUserError } from '@takaro/helpers';\nimport { getGameState, renderHangmanState } from './utils.js';\n\nasync function main() {\n    const { player, gameServerId, module: mod } = data;\n\n    // Check if there's a game in progress\n    const gameState = await getGameState(gameServerId, mod.moduleId);\n    if (!gameState) {\n        throw new TakaroUserError('There is no Hangman game in progress!');\n    }\n\n    // Show the game status\n    if (!gameState.started) {\n        const playerList = gameState.players.map(p => p.name).join(', ');\n        await player.pm(`Hangman game hosted by ${gameState.hostName} is waiting to start.`);\n        await player.pm(`Players (${gameState.players.length}): ${playerList}`);\n        await player.pm(`Current pot: ${gameState.pot || 0} currency`);\n        await player.pm('Type /hangmanjoin to participate!');\n    } else {\n        // Show the current state of the game\n        const display = renderHangmanState(gameState);\n        await player.pm(`Current Hangman Game Status:`);\n        await player.pm(display);\n        await player.pm(`Players (${gameState.players.length}): ${gameState.players.map(p => p.name).join(', ')}`);\n        await player.pm(`Current pot: ${gameState.pot || 0} currency`);\n    }\n}\n\nawait main();",
          "arguments": []
        },
        {
          "name": "hangmanCancel",
          "trigger": "hangmancancel",
          "helpText": "No help text available",
          "function": "// commands/hangmanCancel.js\nimport { takaro, data, TakaroUserError, checkPermission } from '@takaro/helpers';\nimport { getGameState, clearGameState } from './utils.js';\n\nasync function main() {\n    const { player, gameServerId, module: mod, pog } = data;\n\n    // Check if there's a game to cancel\n    const gameState = await getGameState(gameServerId, mod.moduleId);\n    if (!gameState) {\n        throw new TakaroUserError('There is no Hangman game in progress!');\n    }\n\n    // Check if player has permission to cancel\n    const isHost = gameState.hostId === player.id;\n    const isAdmin = checkPermission(pog, 'HANGMAN_ADMIN');\n\n    if (!isHost && !isAdmin) {\n        throw new TakaroUserError('Only the game host or an admin can cancel the game!');\n    }\n\n    // Cancel the game\n    await clearGameState(gameServerId, mod.moduleId);\n\n    // Announce cancellation\n    await takaro.gameserver.gameServerControllerSendMessage(gameServerId, {\n        message: `${player.name} has cancelled the current Hangman game.`\n    });\n\n    if (gameState.started) {\n        await takaro.gameserver.gameServerControllerSendMessage(gameServerId, {\n            message: `The word was: ${gameState.word}`\n        });\n    }\n\n\n}\n\nawait main()",
          "arguments": []
        },
        {
          "name": "hangmanStart",
          "trigger": "hangmanstart",
          "helpText": "No help text available",
          "function": "// commands/hangmanStart.js\nimport { takaro, data, TakaroUserError, checkPermission } from '@takaro/helpers';\n\nasync function main() {\n    const { player, gameServerId, module: mod, arguments: args, pog } = data;\n\n    try {\n        // Check if player has permission to host games\n        if (!checkPermission(pog, 'HANGMAN_HOST')) {\n            throw new TakaroUserError('You do not have permission to host Hangman games!');\n        }\n\n        // Search for existing game\n        const gameVars = await takaro.variable.variableControllerSearch({\n            filters: {\n                key: ['hangman_game_state'],\n                gameServerId: [gameServerId],\n                moduleId: [mod.moduleId]\n            }\n        });\n\n        // Check if there's an existing game\n        if (gameVars.data.data.length === 0) {\n            // No existing game\n            if (!args.word) {\n                throw new TakaroUserError('You must provide a word or phrase to start a Hangman game!');\n            }\n\n            // Word provided, create new game\n            const word = args.word.toLowerCase().trim();\n\n            // Validate word\n            if (word.length < mod.userConfig.minWordLength) {\n                throw new TakaroUserError(`Word must be at least ${mod.userConfig.minWordLength} characters long!`);\n            }\n\n            if (word.length > mod.userConfig.maxWordLength) {\n                throw new TakaroUserError(`Word must be no more than ${mod.userConfig.maxWordLength} characters long!`);\n            }\n\n            if (!/^[a-z ]+$/.test(word)) {\n                throw new TakaroUserError('Word can only contain letters and spaces!');\n            }\n\n            // Check if there's a hosting fee and process it\n            let hostingFee = mod.userConfig.hostingFee || 0;\n            if (hostingFee > 0) {\n                try {\n                    // Check if player has enough currency\n                    const playerData = await takaro.playerOnGameserver.playerOnGameServerControllerGetOne(gameServerId, player.id);\n                    const currentBalance = playerData.data.data.currency;\n\n                    if (currentBalance < hostingFee) {\n                        throw new TakaroUserError(`You need ${hostingFee} currency to host a Hangman game. You only have ${currentBalance}.`);\n                    }\n\n                    // Deduct the hosting fee\n                    await takaro.playerOnGameserver.playerOnGameServerControllerDeductCurrency(\n                        gameServerId,\n                        player.id,\n                        {\n                            currency: hostingFee\n                        }\n                    );\n\n                    await player.pm(`You paid ${hostingFee} currency to host this Hangman game.`);\n                } catch (error) {\n                    if (error instanceof TakaroUserError) throw error;\n                    console.error('Economy error:', error);\n                    throw new TakaroUserError('Failed to process hosting fee. Economy system might be disabled.');\n                }\n            }\n\n            // Create game state\n            const gameState = {\n                word: word,\n                hostId: player.id,\n                hostName: player.name,\n                players: [{ id: player.id, name: player.name }],\n                guessedLetters: [],\n                wrongLetters: [],\n                wrongGuesses: 0,\n                maxWrongGuesses: mod.userConfig.maxWrongGuesses,\n                startTime: Date.now(),\n                gameTimeout: mod.userConfig.gameTimeout,\n                active: false,\n                started: false,\n                pot: hostingFee // Initialize pot with the hosting fee\n            };\n\n            // Create variable\n            await takaro.variable.variableControllerCreate({\n                key: 'hangman_game_state',\n                value: JSON.stringify(gameState),\n                gameServerId,\n                moduleId: mod.moduleId\n            });\n\n            // Send messages\n            await player.pm(`You've started a new Hangman game with the word: ${word}`);\n            await player.pm('As the host, you cannot participate in guessing since you know the word.');\n            await player.pm('Players can join by typing /hangmanjoin');\n            await player.pm('Once players have joined, use /hangmanstart again (with the word) to begin the game!');\n\n            await takaro.gameserver.gameServerControllerSendMessage(gameServerId, {\n                message: `${player.name} has created a new Hangman game! Type /hangmanjoin to participate.`\n            });\n        }\n        else {\n            // Existing game, try to activate it\n            const gameState = JSON.parse(gameVars.data.data[0].value);\n\n            // If game already started\n            if (gameState.started) {\n                throw new TakaroUserError('A Hangman game is already in progress! Use /hangmanstatus to see the current game.');\n            }\n\n            // If player is not host\n            if (gameState.hostId !== player.id) {\n                throw new TakaroUserError('You are not the host of this game! Only the host can start it.');\n            }\n\n            // If not enough players\n            if (gameState.players.length < 2) {\n                throw new TakaroUserError('At least one other player must join before you can start the game!');\n            }\n\n            // Activate game\n            gameState.active = true;\n            gameState.started = true;\n\n            // Update variable\n            await takaro.variable.variableControllerUpdate(gameVars.data.data[0].id, {\n                value: JSON.stringify(gameState)\n            });\n\n            // Announce game start\n            await takaro.gameserver.gameServerControllerSendMessage(gameServerId, {\n                message: `The Hangman game has begun! Use /hangmanguess [letter] to make guesses. Current pot: ${gameState.pot} currency.`\n            });\n        }\n    } catch (error) {\n        if (error instanceof TakaroUserError) {\n            throw error;\n        }\n        console.error('Error in hangmanStart:', error);\n        throw new TakaroUserError('An error occurred while processing your command.');\n    }\n}\n\nawait main();",
          "arguments": [
            {
              "name": "word",
              "type": "string",
              "helpText": "The word or phrase players will try to guess.",
              "defaultValue": "",
              "position": 0
            }
          ]
        },
        {
          "name": "hangmanJoin",
          "trigger": "hangmanjoin",
          "helpText": "No help text available",
          "function": "// commands/hangmanJoin.js\nimport { takaro, data, TakaroUserError, checkPermission } from '@takaro/helpers';\n\nasync function main() {\n    const { player, gameServerId, module: mod, pog } = data;\n\n    // Check if player has permission to play\n    if (!checkPermission(pog, 'HANGMAN_PLAY')) {\n        throw new TakaroUserError('You do not have permission to play Hangman games!');\n    }\n\n    // Check if there's a game to join\n    const gameVars = await takaro.variable.variableControllerSearch({\n        filters: {\n            key: ['hangman_game_state'],\n            gameServerId: [gameServerId],\n            moduleId: [mod.moduleId]\n        }\n    });\n\n    if (gameVars.data.data.length === 0) {\n        throw new TakaroUserError('There is no Hangman game in progress! Use /hangmanstart to create one.');\n    }\n\n    const gameState = JSON.parse(gameVars.data.data[0].value);\n\n    // Check if player is the host\n    if (player.id === gameState.hostId) {\n        throw new TakaroUserError('You are the host of this game! As the host, you cannot participate in guessing since you know the word.');\n    }\n\n    // Check if game has already started\n    if (gameState.started) {\n        throw new TakaroUserError('The game has already started! Wait for the next game.');\n    }\n\n    // Check if player is already in the game\n    if (gameState.players.some(p => p.id === player.id)) {\n        throw new TakaroUserError('You have already joined this game!');\n    }\n\n    // Process entry fee if configured\n    const entryFee = mod.userConfig.entryFee || 0;\n    if (entryFee > 0) {\n        try {\n            // Check if player has enough currency\n            const playerData = await takaro.playerOnGameserver.playerOnGameServerControllerGetOne(gameServerId, player.id);\n            const currentBalance = playerData.data.data.currency;\n\n            if (currentBalance < entryFee) {\n                throw new TakaroUserError(`You need ${entryFee} currency to join this game. You only have ${currentBalance}.`);\n            }\n\n            // Deduct the entry fee\n            await takaro.playerOnGameserver.playerOnGameServerControllerDeductCurrency(\n                gameServerId,\n                player.id,\n                {\n                    currency: entryFee\n                }\n            );\n\n            // Add to the pot\n            gameState.pot += entryFee;\n\n            await player.pm(`You paid ${entryFee} currency to join the game. Current pot: ${gameState.pot}`);\n        } catch (error) {\n            if (error instanceof TakaroUserError) throw error;\n            console.error('Economy error:', error);\n            throw new TakaroUserError('Failed to process entry fee. Economy system might be disabled.');\n        }\n    }\n\n    // Add player to game\n    gameState.players.push({ id: player.id, name: player.name });\n\n    // Save updated game state\n    await takaro.variable.variableControllerUpdate(gameVars.data.data[0].id, {\n        value: JSON.stringify(gameState)\n    });\n\n    // Notify players\n    await player.pm('You have joined the Hangman game!');\n\n    // Notify the host - using the correct API call\n    const hostPlayer = await takaro.player.playerControllerGetOne(gameState.hostId);\n    if (hostPlayer && hostPlayer.data && hostPlayer.data.data) {\n        const hostPog = await takaro.playerOnGameserver.playerOnGameServerControllerSearch({\n            filters: {\n                playerId: [gameState.hostId],\n                gameServerId: [gameServerId],\n                online: [true]\n            }\n        });\n\n        if (hostPog.data.data.length > 0) {\n            // Host is online, send a PM\n            await takaro.gameserver.gameServerControllerExecuteCommand(gameServerId, {\n                command: `pm ${hostPog.data.data[0].steamId} \"${player.name} has joined your Hangman game! ${gameState.players.length} players are now participating.\"`\n            });\n        }\n    }\n\n    // Send announcement\n    await takaro.gameserver.gameServerControllerSendMessage(gameServerId, {\n        message: `${player.name} has joined the Hangman game! (${gameState.players.length} players)`\n    });\n}\n\nawait main();",
          "arguments": []
        },
        {
          "name": "hangmanGuess",
          "trigger": "hangmanguess",
          "helpText": "No help text available",
          "function": "// commands/hangmanGuess.js\nimport { takaro, data, TakaroUserError, checkPermission } from '@takaro/helpers';\n\nasync function main() {\n  const { player, gameServerId, module: mod, arguments: args, pog } = data;\n\n  // Check if player has permission to play\n  if (!checkPermission(pog, 'HANGMAN_PLAY')) {\n    throw new TakaroUserError('You do not have permission to play Hangman games!');\n  }\n\n  // Check if there's a game in progress\n  const gameVars = await takaro.variable.variableControllerSearch({\n    filters: {\n      key: ['hangman_game_state'],\n      gameServerId: [gameServerId],\n      moduleId: [mod.moduleId]\n    }\n  });\n\n  if (gameVars.data.data.length === 0) {\n    throw new TakaroUserError('There is no Hangman game in progress!');\n  }\n\n  const gameState = JSON.parse(gameVars.data.data[0].value);\n\n  // Check if the game is active\n  if (!gameState.active) {\n    throw new TakaroUserError('The game has not started yet!');\n  }\n\n  // Check if player is participating\n  if (!gameState.players.some(p => p.id === player.id)) {\n    throw new TakaroUserError('You are not participating in this game! Wait for the next one.');\n  }\n\n  // Check if player is the host\n  if (player.id === gameState.hostId) {\n    throw new TakaroUserError('As the game host, you cannot participate in guessing since you know the word!');\n  }\n\n  // Validate guess\n  if (!args.letter) {\n    throw new TakaroUserError('You must provide a letter or word to guess!');\n  }\n\n  // Process guess fee\n  const guessPrice = mod.userConfig.guessPrice || 0;\n  if (guessPrice > 0) {\n    try {\n      // Check if player has enough currency\n      const playerData = await takaro.playerOnGameserver.playerOnGameServerControllerGetOne(gameServerId, player.id); const currentBalance = playerData.data.data.currency;\n\n      if (currentBalance < guessPrice) {\n        throw new TakaroUserError(`You need ${guessPrice} currency to make a guess. You only have ${currentBalance}.`);\n      }\n\n      // Deduct the guess fee\n      await takaro.playerOnGameserver.playerOnGameServerControllerDeductCurrency(\n        gameServerId,\n        player.id,\n        {\n          currency: guessPrice\n        }\n      );\n\n      // Add to the pot\n      gameState.pot += guessPrice;\n\n      await player.pm(`You paid ${guessPrice} currency to make a guess. Current pot: ${gameState.pot}`);\n    } catch (error) {\n      if (error instanceof TakaroUserError) throw error;\n      console.error('Economy error:', error);\n      throw new TakaroUserError('Failed to process guess fee. Economy system might be disabled.');\n    }\n  }\n\n  const guess = args.letter.toLowerCase().trim();\n\n  // Handle full word guess\n  if (guess.length > 1) {\n    // Check if the guess matches the full word\n    if (guess === gameState.word) {\n      // Player correctly guessed the whole word!\n      await takaro.gameserver.gameServerControllerSendMessage(gameServerId, {\n        message: `Congratulations! ${player.name} has correctly guessed the word: ${gameState.word}`\n      });\n\n      // Award pot to winner\n      if (gameState.pot > 0) {\n        try {\n          await takaro.playerOnGameserver.playerOnGameServerControllerAddCurrency(\n            gameServerId,\n            player.id,\n            {\n              currency: gameState.pot\n            }\n          );\n\n          await player.pm(`Congratulations! You won the entire pot of ${gameState.pot} currency!`);\n          await takaro.gameserver.gameServerControllerSendMessage(gameServerId, {\n            message: `${player.name} won the Hangman game and collected the pot of ${gameState.pot} currency!`\n          });\n        } catch (error) {\n          console.error('Error granting currency:', error);\n        }\n      }\n\n      // Clear game state\n      await takaro.variable.variableControllerDelete(gameVars.data.data[0].id);\n      return;\n    } else {\n      // Wrong word guess - counts as a wrong guess\n      gameState.wrongGuesses++;\n\n      await takaro.gameserver.gameServerControllerSendMessage(gameServerId, {\n        message: `${player.name} guessed \"${guess}\" - That's not the word! (${gameState.wrongGuesses}/${gameState.maxWrongGuesses})`\n      });\n\n      // Check if game over due to too many wrong guesses\n      if (gameState.wrongGuesses >= gameState.maxWrongGuesses) {\n        await takaro.gameserver.gameServerControllerSendMessage(gameServerId, {\n          message: `Game over! The word was: ${gameState.word}`\n        });\n\n        // Award pot to host\n        if (gameState.pot > 0) {\n          try {\n            await takaro.playerOnGameserver.playerOnGameServerControllerAddCurrency(\n              gameServerId,\n              gameState.hostId,\n              {\n                currency: gameState.pot\n              }\n            );\n\n            await takaro.player.playerControllerPm(gameState.hostId, {\n              message: `You received the pot of ${gameState.pot} currency because nobody solved your Hangman puzzle!`\n            });\n            await takaro.gameserver.gameServerControllerSendMessage(gameServerId, {\n              message: `${gameState.hostName} receives the ${gameState.pot} currency pot as nobody solved the puzzle!`\n            });\n          } catch (error) {\n            console.error('Error granting currency:', error);\n          }\n        }\n\n        // Clear game state\n        await takaro.variable.variableControllerDelete(gameVars.data.data[0].id);\n        return;\n      }\n\n      // Update game state\n      await takaro.variable.variableControllerUpdate(gameVars.data.data[0].id, {\n        value: JSON.stringify(gameState)\n      });\n\n      // Render current state\n      await renderAndSendGameState(gameState, gameServerId);\n      return;\n    }\n  }\n\n  // Handle single letter guess\n  if (guess.length !== 1 || !/^[a-z]$/.test(guess)) {\n    throw new TakaroUserError('You can only guess a single letter or the entire word!');\n  }\n\n  // Check if letter has already been guessed\n  if (gameState.guessedLetters.includes(guess)) {\n    throw new TakaroUserError(`The letter \"${guess}\" has already been guessed!`);\n  }\n\n  // Record the guess\n  gameState.guessedLetters.push(guess);\n\n  // Check if guess is correct\n  if (gameState.word.includes(guess)) {\n    // Correct guess\n    await takaro.gameserver.gameServerControllerSendMessage(gameServerId, {\n      message: `${player.name} correctly guessed \"${guess}\"!`\n    });\n  } else {\n    // Wrong guess\n    gameState.wrongGuesses++;\n    gameState.wrongLetters.push(guess);\n    await takaro.gameserver.gameServerControllerSendMessage(gameServerId, {\n      message: `${player.name} guessed \"${guess}\" - not in the word! (${gameState.wrongGuesses}/${gameState.maxWrongGuesses})`\n    });\n  }\n\n  // Render current game state\n  await renderAndSendGameState(gameState, gameServerId);\n\n  // Check if the game is over\n  const wordLetters = new Set(gameState.word.replace(/\\s/g, '').split(''));\n  const correctlyGuessed = gameState.guessedLetters.filter(letter => gameState.word.includes(letter));\n  const allLettersGuessed = [...wordLetters].every(letter => correctlyGuessed.includes(letter));\n\n  if (allLettersGuessed) {\n    // Player won!\n    await takaro.gameserver.gameServerControllerSendMessage(gameServerId, {\n      message: `Congratulations! The word has been solved: ${gameState.word}`\n    });\n\n    // Award pot to winner\n    if (gameState.pot > 0) {\n      try {\n        await takaro.playerOnGameserver.playerOnGameServerControllerAddCurrency(\n          gameServerId,\n          player.id,\n          {\n            currency: gameState.pot\n          }\n        );\n\n        await player.pm(`Congratulations! You won the entire pot of ${gameState.pot} currency!`);\n        await takaro.gameserver.gameServerControllerSendMessage(gameServerId, {\n          message: `${player.name} won the Hangman game and collected the pot of ${gameState.pot} currency!`\n        });\n      } catch (error) {\n        console.error('Error granting currency:', error);\n      }\n    }\n\n    // Clear game state\n    await takaro.variable.variableControllerDelete(gameVars.data.data[0].id);\n\n  } else if (gameState.wrongGuesses >= gameState.maxWrongGuesses) {\n    // Game over - too many wrong guesses\n    await takaro.gameserver.gameServerControllerSendMessage(gameServerId, {\n      message: `Game over! The word was: ${gameState.word}`\n    });\n\n    // Award pot to host\n    if (gameState.pot > 0) {\n      try {\n        await takaro.playerOnGameserver.playerOnGameServerControllerAddCurrency(\n          gameServerId,\n          gameState.hostId,\n          {\n            currency: gameState.pot\n          }\n        );\n\n        await takaro.player.playerControllerPm(gameState.hostId, {\n          message: `You received the pot of ${gameState.pot} currency because nobody solved your Hangman puzzle!`\n        });\n        await takaro.gameserver.gameServerControllerSendMessage(gameServerId, {\n          message: `${gameState.hostName} receives the ${gameState.pot} currency pot as nobody solved the puzzle!`\n        });\n      } catch (error) {\n        console.error('Error granting currency:', error);\n      }\n    }\n\n    // Clear game state\n    await takaro.variable.variableControllerDelete(gameVars.data.data[0].id);\n  } else {\n    // Game continues - save updated state\n    await takaro.variable.variableControllerUpdate(gameVars.data.data[0].id, {\n      value: JSON.stringify(gameState)\n    });\n  }\n}\n\n// Helper function to render and send game state\nasync function renderAndSendGameState(gameState, gameServerId) {\n  const { word, guessedLetters, wrongGuesses, maxWrongGuesses, wrongLetters } = gameState;\n\n  // Create the word display with correctly guessed letters shown\n  const wordDisplay = word.split('').map(letter => {\n    if (letter === ' ') return ' ';\n    return guessedLetters.includes(letter.toLowerCase()) ? letter : '_';\n  }).join(' ');\n\n  // Create a dynamic status based on current progress\n  const percentComplete = Math.floor((wrongGuesses / maxWrongGuesses) * 100);\n  let hangmanStatus;\n\n  if (wrongGuesses === 0) {\n    hangmanStatus = \"Hangman: No wrong guesses yet\";\n  } else {\n    hangmanStatus = `Hangman: ${wrongGuesses}/${maxWrongGuesses} wrong guesses (${percentComplete}% to game over)`;\n  }\n\n  const wrongGuessesText = `Wrong guesses: ${wrongLetters.join(' ') || 'none'}`;\n  const guessedLettersText = `Letters guessed: ${guessedLetters.join(' ') || 'none'}`;\n  const potInfo = `Current pot: ${gameState.pot} currency`;\n\n  const display = `${hangmanStatus}\\n${wordDisplay}\\n${wrongGuessesText}\\n${guessedLettersText}\\n${potInfo}`;\n\n  await takaro.gameserver.gameServerControllerSendMessage(gameServerId, {\n    message: display\n  });\n}\n\nawait main();",
          "arguments": [
            {
              "name": "letter",
              "type": "string",
              "helpText": "The letter you want to guess.",
              "defaultValue": "",
              "position": 0
            }
          ]
        }
      ],
      "hooks": [],
      "cronJobs": [],
      "functions": [
        {
          "name": "utils",
          "description": "",
          "function": "// functions/utils.js\nimport { takaro } from '@takaro/helpers';\n\n/**\n * Gets the current hangman game state from variables\n */\nexport async function getGameState(gameServerId, moduleId) {\n    const gameVars = await takaro.variable.variableControllerSearch({\n        filters: {\n            key: ['hangman_game_state'],\n            gameServerId: [gameServerId],\n            moduleId: [moduleId]\n        }\n    });\n\n    if (gameVars.data.data.length === 0) {\n        return null;\n    }\n\n    return JSON.parse(gameVars.data.data[0].value);\n}\n\n/**\n * Saves the current hangman game state to variables\n */\nexport async function saveGameState(gameState, gameServerId, moduleId) {\n    const gameVars = await takaro.variable.variableControllerSearch({\n        filters: {\n            key: ['hangman_game_state'],\n            gameServerId: [gameServerId],\n            moduleId: [moduleId]\n        }\n    });\n\n    if (gameVars.data.data.length === 0) {\n        await takaro.variable.variableControllerCreate({\n            key: 'hangman_game_state',\n            value: JSON.stringify(gameState),\n            gameServerId,\n            moduleId\n        });\n    } else {\n        await takaro.variable.variableControllerUpdate(gameVars.data.data[0].id, {\n            value: JSON.stringify(gameState)\n        });\n    }\n}\n\n/**\n * Clears the current hangman game state\n */\nexport async function clearGameState(gameServerId, moduleId) {\n    const gameVars = await takaro.variable.variableControllerSearch({\n        filters: {\n            key: ['hangman_game_state'],\n            gameServerId: [gameServerId],\n            moduleId: [moduleId]\n        }\n    });\n\n    if (gameVars.data.data.length > 0) {\n        await takaro.variable.variableControllerDelete(gameVars.data.data[0].id);\n    }\n}\n\n/**\n * Renders the current hangman state for display\n */\nexport function renderHangmanState(gameState) {\n    const { word, guessedLetters, wrongGuesses, maxWrongGuesses, wrongLetters } = gameState;\n\n    // Create the word display with correctly guessed letters shown\n    const wordDisplay = word.split('').map(letter => {\n        if (letter === ' ') return ' ';\n        return guessedLetters.includes(letter.toLowerCase()) ? letter : '_';\n    }).join(' ');\n\n    // Create a dynamic status based on current progress\n    const percentComplete = Math.floor((wrongGuesses / maxWrongGuesses) * 100);\n    let hangmanStatus;\n\n    if (wrongGuesses === 0) {\n        hangmanStatus = \"Hangman: No wrong guesses yet\";\n    } else {\n        hangmanStatus = `Hangman: ${wrongGuesses}/${maxWrongGuesses} wrong guesses (${percentComplete}% to game over)`;\n    }\n\n    const wrongGuessesText = `Wrong guesses: ${wrongLetters ? wrongLetters.join(' ') : 'none'}`;\n    const guessedLettersText = `Letters guessed: ${guessedLetters.length > 0 ? guessedLetters.join(' ') : 'none'}`;\n    const potInfo = `Current pot: ${gameState.pot || 0} currency`;\n\n    return `${hangmanStatus}\\n${wordDisplay}\\n${wrongGuessesText}\\n${guessedLettersText}\\n${potInfo}`;\n}\n\n/**\n * Checks if a player has permission to perform an action\n */\nexport function hasPermission(pog, permission) {\n    for (const role of pog.roles) {\n        const perm = role.permissions.find(p => p.permission === permission);\n        if (perm) return true;\n    }\n    return false;\n}"
        }
      ],
      "permissions": [
        {
          "permission": "HANGMAN_HOST",
          "friendlyName": "Host Hangman Game",
          "description": "Allows the player to start and host Hangman games.",
          "canHaveCount": false
        },
        {
          "permission": "HANGMAN_PLAY",
          "friendlyName": "Play Hangman",
          "description": "Allows the player to join and make guesses in Hangman games.",
          "canHaveCount": false
        },
        {
          "permission": "HANGMAN_ADMIN",
          "friendlyName": "Hangman Admin",
          "description": "Allows the player to manage and control running Hangman games.",
          "canHaveCount": false
        }
      ]
    }
  ]
}