dailyRewards

  • builtin
  • by Takaro
  • Takaro >=0.0.1
  • all
Version

Built-in modules ship with Takaro — no import needed.

View export JSON

Provides daily login rewards with streak tracking

Configuration 3

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

SettingTypeDefaultDescription
baseReward required Base Reward number 100 Base amount of currency given for daily rewards. This is multiplied by streak level.
maxStreak required Maximum Streak number 365 Maximum streak level a player can reach
milestoneRewards required Milestone Rewards array [{"days":7,"reward":1000,"message":"You did it! 7 days in a row!"},{"days":30,"reward":5000,"message":"A whole month! You're on fire!"},{"days":90,"reward":20000,"message":"90 days! You're unstoppable!"},{"days":180,"reward":50000,"message":"Half a year! You're a legend!"},{"days":365,"reward":150000,"message":"365 days! You're a true champion!"}] Additional rewards for reaching certain streak milestones
Raw config schema
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "baseReward": {
      "type": "number",
      "title": "Base Reward",
      "description": "Base amount of currency given for daily rewards. This is multiplied by streak level.",
      "default": 100,
      "minimum": 1
    },
    "maxStreak": {
      "type": "number",
      "title": "Maximum Streak",
      "description": "Maximum streak level a player can reach",
      "default": 365,
      "minimum": 1
    },
    "milestoneRewards": {
      "type": "array",
      "title": "Milestone Rewards",
      "description": "Additional rewards for reaching certain streak milestones",
      "items": {
        "type": "object",
        "properties": {
          "days": {
            "type": "number",
            "description": "Days needed to reach milestone",
            "minimum": 1
          },
          "reward": {
            "type": "number",
            "description": "Bonus reward amount"
          },
          "message": {
            "type": "string",
            "description": "Message to show when milestone is reached"
          }
        }
      },
      "default": [
        {
          "days": 7,
          "reward": 1000,
          "message": "You did it! 7 days in a row!"
        },
        {
          "days": 30,
          "reward": 5000,
          "message": "A whole month! You're on fire!"
        },
        {
          "days": 90,
          "reward": 20000,
          "message": "90 days! You're unstoppable!"
        },
        {
          "days": 180,
          "reward": 50000,
          "message": "Half a year! You're a legend!"
        },
        {
          "days": 365,
          "reward": 150000,
          "message": "365 days! You're a true champion!"
        }
      ]
    }
  },
  "required": [
    "baseReward",
    "maxStreak",
    "milestoneRewards"
  ],
  "additionalProperties": false
}
Raw UI schema
{}

Commands 3

Chat commands players trigger in game.

  • daily

    Claim your daily reward

    Command source
    import { takaro, data, TakaroUserError } from '@takaro/helpers';
    import { DAILY_KEY, STREAK_KEY, getMultiplier } from './utils.js';
    async function main() {
        const { pog, gameServerId, module: mod } = data;
        // Get last claim time
        const lastClaimRes = await takaro.variable.variableControllerSearch({
            filters: {
                key: [DAILY_KEY],
                gameServerId: [gameServerId],
                playerId: [pog.playerId],
                moduleId: [mod.moduleId],
            },
        });
        const now = new Date();
        let streak = 1;
        if (lastClaimRes.data.data.length > 0) {
            const lastClaim = new Date(JSON.parse(lastClaimRes.data.data[0].value));
            const hoursSinceLastClaim = (now - lastClaim) / (1000 * 60 * 60);
            // Check if 24 hours have passed
            if (hoursSinceLastClaim < 24) {
                const nextClaimTime = new Date(lastClaim.getTime() + 24 * 60 * 60 * 1000);
                throw new TakaroUserError(`You can claim your next reward at ${nextClaimTime.toLocaleString()}`);
            }
            // Get current streak
            const streakRes = await takaro.variable.variableControllerSearch({
                filters: {
                    key: [STREAK_KEY],
                    gameServerId: [gameServerId],
                    playerId: [pog.playerId],
                    moduleId: [mod.moduleId],
                },
            });
            if (streakRes.data.data.length > 0) {
                // If claimed within 48 hours, increment streak
                if (hoursSinceLastClaim < 48) {
                    streak = Math.min(JSON.parse(streakRes.data.data[0].value) + 1, mod.userConfig.maxStreak);
                    await takaro.variable.variableControllerUpdate(streakRes.data.data[0].id, {
                        value: JSON.stringify(streak),
                    });
                }
                else {
                    // Reset streak if more than 48 hours
                    await takaro.variable.variableControllerUpdate(streakRes.data.data[0].id, {
                        value: JSON.stringify(1),
                    });
                }
            }
            else {
                // Create new streak record
                await takaro.variable.variableControllerCreate({
                    key: STREAK_KEY,
                    value: JSON.stringify(1),
                    gameServerId,
                    playerId: pog.playerId,
                    moduleId: mod.moduleId,
                });
            }
            // Update last claim time
            await takaro.variable.variableControllerUpdate(lastClaimRes.data.data[0].id, {
                value: JSON.stringify(now),
            });
        }
        else {
            // First time claim
            await takaro.variable.variableControllerCreate({
                key: DAILY_KEY,
                value: JSON.stringify(now),
                gameServerId,
                playerId: pog.playerId,
                moduleId: mod.moduleId,
            });
            await takaro.variable.variableControllerCreate({
                key: STREAK_KEY,
                value: JSON.stringify(1),
                gameServerId,
                playerId: pog.playerId,
                moduleId: mod.moduleId,
            });
        }
        const multiplier = await getMultiplier(pog);
        const baseReward = mod.userConfig.baseReward * streak * multiplier;
        let bonusReward = 0;
        let milestoneMessage = '';
        // Check for milestones
        for (const milestone of mod.userConfig.milestoneRewards) {
            if (streak === milestone.days) {
                bonusReward = milestone.reward;
                milestoneMessage = `\n${milestone.message}`;
                break;
            }
        }
        // Award total rewards
        const totalReward = baseReward + bonusReward;
        await takaro.playerOnGameserver.playerOnGameServerControllerAddCurrency(gameServerId, pog.playerId, {
            currency: totalReward,
            reason: 'Daily reward',
        });
        const currencyName = (await takaro.settings.settingsControllerGetOne('currencyName', gameServerId)).data.data.value;
        await pog.pm(`Daily reward claimed! You received ${totalReward} ${currencyName}\n` +
            `Current streak: ${streak} days${multiplier > 1 ? ` (${multiplier}x bonus!)` : ''}${milestoneMessage}`);
    }
    await main();
    //# sourceMappingURL=daily.js.map
  • streak

    Check your current daily reward streak and next claim time

    Command source
    import { data, takaro } from '@takaro/helpers';
    import { getPlayerStreak, getLastClaim, getMultiplier } from './utils.js';
    async function main() {
        const { pog, gameServerId, module: mod } = data;
        const streak = await getPlayerStreak(gameServerId, pog.playerId, mod.moduleId);
        const lastClaim = await getLastClaim(gameServerId, pog.playerId, mod.moduleId);
        const multiplier = await getMultiplier(pog);
        const prefix = (await takaro.settings.settingsControllerGetOne('commandPrefix', gameServerId)).data.data.value;
        if (!streak || !lastClaim) {
            await pog.pm(`You haven't claimed any daily rewards yet! Use ${prefix}daily to get started.`);
            return;
        }
        const nextClaimTime = new Date(lastClaim.getTime() + 24 * 60 * 60 * 1000);
        const now = new Date();
        const canClaim = now >= nextClaimTime;
        // Find next milestone
        let nextMilestone = null;
        for (const milestone of mod.userConfig.milestoneRewards) {
            if (milestone.days > streak) {
                nextMilestone = milestone;
                break;
            }
        }
        let message = `Current streak: ${streak} days${multiplier > 1 ? ` (${multiplier}x donor bonus!)` : ''}\n`;
        message += canClaim
            ? `Your daily reward is available! Use ${prefix}daily to claim it!\n`
            : `Next reward available at: ${nextClaimTime.toLocaleString()}\n`;
        if (nextMilestone) {
            message += `\n🎯 Next milestone: ${nextMilestone.days} days (${nextMilestone.days - streak} days to go!)`;
        }
        await pog.pm(message);
    }
    await main();
    //# sourceMappingURL=streak.js.map
  • topstreak

    Shows the players with highest daily reward streaks

    ArgumentTypeDefaultHelp
    count number 5 Number of players to show (max 25)
    Command source
    import { takaro, data } from '@takaro/helpers';
    import { STREAK_KEY } from './utils.js';
    async function main() {
        const { pog, gameServerId, module: mod, arguments: args } = data;
        // Limit count to reasonable number
        const count = Math.min(Math.max(1, args.count), 50);
        // Get all streaks
        const streaksRes = await takaro.variable.variableControllerSearch({
            filters: {
                key: [STREAK_KEY],
                gameServerId: [gameServerId],
                moduleId: [mod.moduleId],
            },
            limit: 1000, // Get all possible streaks
        });
        if (streaksRes.data.data.length === 0) {
            await pog.pm('No players have started their daily streak yet!');
            return;
        }
        // Sort by streak value
        const sortedStreaks = streaksRes.data.data
            .map((record) => ({
            playerId: record.playerId,
            streak: JSON.parse(record.value),
        }))
            .sort((a, b) => b.streak - a.streak)
            .slice(0, count);
        // Get player names
        const playerDetails = await Promise.all(sortedStreaks.map(async (record) => {
            const player = (await takaro.player.playerControllerGetOne(record.playerId)).data.data;
            return {
                name: player.name,
                streak: record.streak,
            };
        }));
        // Build message
        let message = `Top ${count} Daily Streaks:\n\n`;
        for (const [index, player] of playerDetails.entries()) {
            message += `${index + 1}. ${player.name}: ${player.streak} days\n`;
        }
        await pog.pm(message);
    }
    await main();
    //# sourceMappingURL=topstreak.js.map

Hooks 1

Code that runs in reaction to a game or Takaro event.

  • dailyLoginCheck

    Hook for player-connected events

    Hook source
    import { data, takaro } from '@takaro/helpers';
    import { getLastClaim } from './utils.js';
    async function main() {
        const { pog, gameServerId, module: mod } = data;
        const prefix = (await takaro.settings.settingsControllerGetOne('commandPrefix', gameServerId)).data.data.value;
        const lastClaim = await getLastClaim(gameServerId, pog.playerId, mod.moduleId);
        // First time player
        if (!lastClaim) {
            await pog.pm(`Welcome! Use ${prefix}daily to claim your first daily reward and start your streak!`);
            return;
        }
        const now = new Date();
        const nextClaimTime = new Date(lastClaim.getTime() + 24 * 60 * 60 * 1000);
        if (now >= nextClaimTime) {
            await pog.pm(`Your daily reward is ready! Use ${prefix}daily to claim it!`);
        }
    }
    await main();
    //# sourceMappingURL=dailyLoginCheck.js.map

Functions 1

Shared helpers the module's commands, hooks and cron jobs import.

  • utils

    Function source
    import { takaro, checkPermission } from '@takaro/helpers';
    export const DAILY_KEY = 'daily_timestamp';
    export const STREAK_KEY = 'daily_streak';
    export async function getMultiplier(pog) {
        const perm = checkPermission(pog, 'DAILY_REWARD_MULTIPLIER');
        if (perm) {
            return perm.count;
        }
        return 1;
    }
    export async function getPlayerStreak(gameServerId, playerId, moduleId) {
        const streakRes = await takaro.variable.variableControllerSearch({
            filters: {
                key: [STREAK_KEY],
                gameServerId: [gameServerId],
                playerId: [playerId],
                moduleId: [moduleId],
            },
        });
        return streakRes.data.data.length ? parseInt(JSON.parse(streakRes.data.data[0].value)) : 0;
    }
    export async function getLastClaim(gameServerId, playerId, moduleId) {
        const lastClaimRes = await takaro.variable.variableControllerSearch({
            filters: {
                key: [DAILY_KEY],
                gameServerId: [gameServerId],
                playerId: [playerId],
                moduleId: [moduleId],
            },
        });
        return lastClaimRes.data.data.length ? new Date(JSON.parse(lastClaimRes.data.data[0].value)) : null;
    }
    //# sourceMappingURL=utils.js.map

Permissions 2

Roles you can grant to decide who may use what.

  • Claim Daily Rewards

    Allows the player to claim daily rewards

  • Multiplier

    Control the multiplier per role. This is useful to give your donors a little extra. Count is an integer multiplier.