PlaytimeReward
- community
- economy
- by limon
- Takaro v0.0.24
- all
Limon_RewardPlaytime: Reward Players for Their Dedication
This module automatically rewards players for their time spent on your server, encouraging longer play sessions and regular participation.
Key Features:

- Timed Rewards: Configure how often players receive rewards while online. The reward interval and cronjob schedule should be synchronized for best results (e.g., set both to 5 minutes).
- Currency Rewards: Automatically grant in-game currency to active players based on your configuration.
- Random Item Rewards: Set up a customizable chance to give random items from your configured list.

- Role-Based Rewards: Use permission overrides to give VIP players increased rewards or higher chances for items.
- Playtime Tracking: The included
/playtimecommand lets players check their current session time, server playtime, and community-wide playtime statistics. - Customizable Messages: Personalize the reward notifications with dynamic placeholders for playtime, currency, and items.

Configuration Options:
rewardInterval: Set how frequently rewards are given (should match cronjob schedule)baseReward: Amount of currency to award each intervalpossibleItems: List of items that can be randomly awardeditemChance: Percentage chance (1-100) to receive an itemrewardMessage: Customize notification with placeholders {minutes}, {currency}, {item}
Permission Options:
PLAYTIME_REWARD_OVERRIDE: Customize currency rewards for specific rolesPLAYTIME_ITEM_CHANCE_OVERRIDE: Modify item drop chances for specific roles
Perfect for servers looking to increase player retention and reward loyal community members.
Configuration 5
Settings you fill in when installing the module on a server.
| Setting | Type | Default | Description |
|---|---|---|---|
rewardInterval rewardInterval | number | 1200000 | Give rewards every X minutes of playtime |
baseReward baseReward | number | 0 | Currency given per reward |
possibleItems Items | array | — | Items that can be randomly awarded |
itemChance itemChance | string | — | Chance to receive an item (1-100) |
rewardMessage rewardMessage | string | "\"You've been online for {minutes} minutes! Reward: {currency} currency and {item}. " | Message with placeholders {minutes}, {currency}, {item} |
Raw config schema
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"required": [],
"additionalProperties": false,
"properties": {
"rewardInterval": {
"title": "rewardInterval",
"description": "Give rewards every X minutes of playtime",
"default": 1200000,
"x-component": "duration",
"type": "number"
},
"baseReward": {
"title": "baseReward",
"description": "Currency given per reward",
"default": 0,
"type": "number"
},
"possibleItems": {
"title": "Items",
"description": "Items that can be randomly awarded",
"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"
}
}
}
},
"itemChance": {
"title": "itemChance",
"description": "Chance to receive an item (1-100)\n",
"type": "string",
"minLength": 1,
"maxLength": 100
},
"rewardMessage": {
"title": "rewardMessage",
"description": "Message with placeholders {minutes}, {currency}, {item}",
"default": "\"You've been online for {minutes} minutes! Reward: {currency} currency and {item}. ",
"type": "string"
}
}
} Raw UI schema
{} Commands 1
Chat commands players trigger in game.
-
playtime
Check your playtime statistics
Command source
// commands/playtime.js import { takaro, data } from '@takaro/helpers'; async function main() { const { player, gameServerId, pog } = data; // Search for the most recent player connected event for this player const connectEvents = await takaro.event.eventControllerSearch({ filters: { eventName: ['player-connected'], gameserverId: [gameServerId], playerId: [player.id] }, sortBy: "createdAt", sortDirection: "desc", limit: 1 }); // Format session playtime let sessionTimeString = "No data available"; if (connectEvents.data.data.length > 0) { // Get the connection timestamp const connectionTime = new Date(connectEvents.data.data[0].createdAt); const currentTime = new Date(); // Calculate time difference in minutes const diffMs = currentTime - connectionTime; const diffMinutes = Math.floor(diffMs / 60000); sessionTimeString = formatPlaytime(diffMinutes); } // Get playtime from POG and player objects (in seconds) const serverPlaytimeMinutes = Math.floor(pog.playtimeSeconds / 60); const communityPlaytimeMinutes = Math.floor(player.playtimeSeconds / 60); const serverPlaytimeString = formatPlaytime(serverPlaytimeMinutes); const communityPlaytimeString = formatPlaytime(communityPlaytimeMinutes); await player.pm( `Playtime stats:\n` + `Current session: ${sessionTimeString}\n` + `This server: ${serverPlaytimeString}\n` + `Total community: ${communityPlaytimeString}` ); } // Helper function to format minutes into readable time function formatPlaytime(minutes) { const days = Math.floor(minutes / 1440); const hours = Math.floor((minutes % 1440) / 60); const remainingMinutes = minutes % 60; let timeString = ""; if (days > 0) { timeString += `${days} day${days !== 1 ? 's' : ''}`; if (hours > 0 || remainingMinutes > 0) timeString += `, `; } if (hours > 0) { timeString += `${hours} hour${hours !== 1 ? 's' : ''}`; if (remainingMinutes > 0) timeString += ` and `; } if (remainingMinutes > 0 || (days === 0 && hours === 0)) { timeString += `${remainingMinutes} minute${remainingMinutes !== 1 ? 's' : ''}`; } return timeString; } await main();
Cron jobs 1
Work the module runs on a schedule.
-
rewardOnlinePlaytime
Cron job source
// cronJobs/rewardOnlinePlaytime.js import { takaro, data, checkPermission } from '@takaro/helpers'; // Helper function to format playtime into readable time function formatPlaytime(minutes) { if (minutes < 60) { return `${minutes} minute${minutes === 1 ? '' : 's'}`; } else if (minutes < 1440) { const hours = Math.floor(minutes / 60); const remainingMinutes = minutes % 60; return `${hours} hour${hours === 1 ? '' : 's'} ${remainingMinutes} minute${remainingMinutes === 1 ? '' : 's'}`; } else { const days = Math.floor(minutes / 1440); const hours = Math.floor((minutes % 1440) / 60); return `${days} day${days === 1 ? '' : 's'} ${hours} hour${hours === 1 ? '' : 's'}`; } } async function main() { const { gameServerId, module: mod } = data; // Get online players const onlinePlayers = await takaro.playerOnGameserver.playerOnGameServerControllerSearch({ filters: { gameServerId: [gameServerId], online: [true] } }); // If no players online, exit early if (onlinePlayers.data.meta.total === 0) { return; } // Parse configuration values const interval = mod.userConfig.rewardInterval; const baseReward = mod.userConfig.baseReward; const possibleItems = mod.userConfig.possibleItems || []; const configItemChance = parseInt(mod.userConfig.itemChance || '0'); const rewardMessage = mod.userConfig.rewardMessage; // Get currency name let currencyName = "coins"; try { const currencyNameSetting = await takaro.settings.settingsControllerGetOne('currencyName', gameServerId); if (currencyNameSetting && currencyNameSetting.data.data) { currencyName = currencyNameSetting.data.data.value; } } catch (error) { // Use default if setting not found } // Process each online player for (const pog of onlinePlayers.data.data) { try { // Find last reward time variable const lastRewardVar = await takaro.variable.variableControllerSearch({ filters: { key: ['last_playtime_reward'], playerId: [pog.playerId], gameServerId: [gameServerId], moduleId: [mod.moduleId] } }); // Get current time const now = Date.now(); let lastRewardTime = 0; let lastRewardVarId = null; if (lastRewardVar.data.data.length > 0) { lastRewardTime = parseInt(lastRewardVar.data.data[0].value); lastRewardVarId = lastRewardVar.data.data[0].id; } // Check if it's time for a reward if (now - lastRewardTime >= interval) { // Get player's session time let sessionTimeString = "some time"; try { const connectEvents = await takaro.event.eventControllerSearch({ filters: { eventName: ['player-connected'], gameserverId: [gameServerId], playerId: [pog.playerId] }, sortBy: "createdAt", sortDirection: "desc", limit: 1 }); if (connectEvents.data.data.length > 0) { const connectionTime = new Date(connectEvents.data.data[0].createdAt); const currentTime = new Date(); const diffMs = currentTime - connectionTime; const diffMinutes = Math.floor(diffMs / 60000); sessionTimeString = formatPlaytime(diffMinutes); } } catch (error) { // Continue with default session time string } // Variables to track rewards let currencyAwarded = 0; let itemReceived = "nothing"; // Check for permission override for currency reward const currencyPermission = checkPermission(pog, 'PLAYTIME_REWARD_OVERRIDE'); const actualReward = currencyPermission && currencyPermission.count != null ? currencyPermission.count : baseReward; // Grant currency if configured if (actualReward > 0) { await takaro.playerOnGameserver.playerOnGameServerControllerAddCurrency(gameServerId, pog.playerId, { currency: actualReward }); currencyAwarded = actualReward; } // Check for item chance override const itemChancePermission = checkPermission(pog, 'PLAYTIME_ITEM_CHANCE_OVERRIDE'); const actualItemChance = itemChancePermission && itemChancePermission.count != null ? itemChancePermission.count : configItemChance; // Determine if player gets an item if (possibleItems.length > 0 && Math.random() * 100 < actualItemChance) { // Select random item from the list const randomItem = possibleItems[Math.floor(Math.random() * possibleItems.length)]; if (randomItem && randomItem.item) { try { // Get item details const itemDetails = await takaro.item.itemControllerFindOne(randomItem.item); if (itemDetails && itemDetails.data.data) { // Give item to player await takaro.gameserver.gameServerControllerGiveItem(gameServerId, pog.playerId, { name: itemDetails.data.data.code, amount: randomItem.amount || 1, quality: randomItem.quality || '' }); itemReceived = `${randomItem.amount || 1}x ${itemDetails.data.data.name}`; } } catch (error) { // Failed to give item, continue with default } } } // Send reward message to player const formattedMessage = rewardMessage .replace('{minutes}', sessionTimeString) .replace('{currency}', `${currencyAwarded} ${currencyName}`) .replace('{item}', itemReceived); await takaro.gameserver.gameServerControllerSendMessage(gameServerId, { message: formattedMessage, opts: { recipient: { gameId: pog.gameId } } }); // Update last reward time if (lastRewardVarId) { await takaro.variable.variableControllerUpdate(lastRewardVarId, { value: now.toString() }); } else { await takaro.variable.variableControllerCreate({ key: 'last_playtime_reward', value: now.toString(), playerId: pog.playerId, gameServerId: gameServerId, moduleId: mod.moduleId }); } } } catch (error) { // Skip to next player if there's an error continue; } } } await main();
Permissions 2
Roles you can grant to decide who may use what.
-
Playtime Reward Override
Override the base currency reward for playtime. Count value determines the reward amount.
-
Playtime Item Chance Override
Override the chance to receive an item. Count value is the percentage (0-100).