AjdnikovRewards++ Documentation
AjdnikovRewards++ tracks playtime (with AFK detection), monitors staff moderation actions, and grants configurable rewards — automatically, or by letting players claim them. It integrates with Discord for account linking, role sync, reward DMs and announcements, and weekly reports. Everything is configurable in-game: run /ptr.
Overview
- Playtime tracking with AFK detection — all-time, today, this week and this month.
- Rewards for playtime, for staff moderation actions, or both — one-time or repeating, given automatically or claimed by players.
- Staff moderation tracking from any punishment plugin, staff streaks and automatic promotions.
- A Discord bot with account linking, role sync, reward DMs, announcements and a weekly report.
- In-game editors for every reward, setting and message — no YAML editing needed.
- PlaceholderAPI placeholders for playtime, ranks, rewards and streaks.
What's New in 2.0
Upgrading from 1.x
Drop in the new jar and restart. Nothing needs to be deleted.
- New options are added automatically to your existing
config.yml— only missing keys; nothing you set or removed is touched. - New database tables are created automatically (
ptr_playtime_daily,ptr_pending_rewards,ptr_meta). - Your
rewards.yml/staff-rewards.ymlkeep working unchanged. New optional keys:icon,permission,playtime-period,claim-mode,minecraft.broadcast. - Daily/weekly/monthly playtime starts counting from the moment 2.0 is installed (there was no per-day data before).
- If you use staff streaks, give your staff the
ptr.staffpermission (default: op). Only players with it are evaluated now.
Highlights
- Full in-game editors: a dashboard, a reward editor for every field, create/duplicate/delete rewards, test a reward on yourself, a settings editor for every
config.ymloption, a messages editor with live preview, a promotions editor, and a player browser with profiles. /rewardsis now a menu with status, progress bars, requirements and click-to-claim, plus manual claiming (claim-mode: MANUAL).- Calendar-period playtime (
playtime-period: DAILY | WEEKLY | MONTHLY): "play 1 hour today" rewards that reset each day, week or month. - Leaderboards menu (
/playtimetop) for all-time, this month, this week and today. - PlaceholderAPI placeholders are now implemented, all served from a cache.
- Tab completion everywhere, including offline player names and reward IDs.
Notable fixes
- Discord slash commands, buttons and role sync never fired in the obfuscated release jar — fixed.
- AFK time was never actually recorded or excluded, and with
exclude-afk: truerewards could be granted too early — fixed. - Rewards given to offline players lost their money, commands and ranks. The whole payout is now queued and delivered on next join.
- Discord staff commands were usable by anyone when
discord.staff-role-idwas empty. Now Discord administrators only. - Staff streaks were rewritten: they now measure playtime in the period, read points from the right file, and only evaluate staff.
- MySQL 8 failed on start-up; repeating rewards could be granted twice;
/ptr reloaddid not reloadstaff-rewards.yml; heads in menus no longer block the main thread.
Quick Start
- Put
AjdnikovRewards-2.0.0.jarinplugins/and start the server. - Put your licence key in
plugins/AjdnikovRewards/config.yml→license.keyand restart. Keys are issued in the Discord with/claim. - In game, run
/ptr:- Settings → Discord: set the bot token and guild ID (restart after setting these).
- Player Rewards / Staff Rewards: edit the bundled rewards or click + Create Reward.
- Players use
/rewardsto see their progress and claim rewards.
AnziLock License
AjdnikovRewards++ is protected by AnziLock. Insert the key you received in the Discord into config.yml:
license:
key: "YOUR_LICENSE_KEY_HERE"
In-Game Editors
/ptr opens the admin dashboard:
| Button | What it does |
|---|---|
| Stats | Online/tracked players, linked accounts, rewards today, integration status (Vault, LuckPerms, PlaceholderAPI, Discord, database) |
| Player Rewards / Staff Rewards | Paged reward lists — filter, sort, create, duplicate (Q), toggle (Shift-click), delete (Right-click) |
| Players | Online / recently seen / search → player profiles |
| Leaderboards | All-time, this month, this week, today |
| Staff Activity | Staff ranked by moderation actions (24h / 7d / 30d) |
| Settings | Every config.yml option, grouped by category |
| Messages | Every chat message, with preview and reset |
| Reload | Reload all files from disk |
Reward editor
Every field of a reward is editable, grouped into rows:
- General — display name, description, icon (click with an item on your cursor, or use the item in your hand), enabled, trigger type, one-time/repeating, claim mode
- Requirements — playtime required, which playtime counts (all-time/today/this week/this month), repeat interval, cooldown, moderation requirements, required prior reward, permission
- Payouts — money, items (drag-and-drop editor that keeps NBT, enchantments and names), commands, LuckPerms groups, broadcast, staff points
- Discord — roles, DM message, announcement channel and message
- Actions — test on yourself, enable/disable, duplicate, delete
Changes save to disk immediately. When a value is typed in chat you get a title prompt, [Insert] to put the current value in your chat box, examples, validation with retry, cancel to abort, clear to remove optional values, and a 2-minute timeout. Your input is never shown to other players.
Durations accept 30m, 1h 30m, 1.5h, 2d, 1w, 2 hours 15 minutes. Money accepts 500, 2.5k, 1m.
Settings editor
Every option shows its current value and a description. Toggles flip on click, numbers use Left/Right (±) or Shift-click to type, choices cycle, text is typed in chat, and lists open a list editor. Q resets an option to its default. Options marked restart required (bot token, guild ID, database) take effect after a restart; everything else applies immediately.
Player profiles
Playtime (total, today, week, month, stored AFK), Discord link (force-link / unlink), rewards received (with revoke), give reward, set/add/remove/reset playtime, moderation stats with recent actions, re-check rewards, and "view their /rewards menu" to see exactly what they see.
Player Experience
/rewards— a menu of every reward: ready, a progress bar while in progress, claimed, cooldown until the next period, or locked (with the reason). It shows what each reward gives. Click to claim, or Claim All when several are ready. Staff (ptr.staff) can switch to the staff rewards tab./playtime— total, today, this week, this month and progress to the next milestone./playtimetop [all|month|week|today]— the leaderboard menu, with player heads.- Rewards play a title, a sound and an optional harmless firework (all configurable), and can broadcast to the server.
/linkgives a 6-digit code with a click-to-copy button.
Configuration Files
All three files — config.yml, rewards.yml and staff-rewards.yml — can be edited in game. Editing by hand and running /ptr reload also works. New options are added to existing configs automatically on start-up.
config.yml
| Section | Key | Default | Description |
|---|---|---|---|
| License | license.key | — | Your AnziLock licence key |
| Discord | bot-token | — | Discord bot token (restart) |
guild-id | — | Discord server ID (restart) | |
discord.staff-role-id | — | Role for staff slash commands (empty = Discord administrators only) | |
discord.announcement-channel | — | Default channel for announcements | |
discord.bot-status | Watching {online} players online | Bot activity | |
| Linking | linking.require-link | false | Require a Discord link to play (bypass: ptr.bypasslink) |
linking.link-code-expiry | 600 | Link code validity (seconds) | |
linking.limbo-world | limbo | World for unlinked players (empty = kick) | |
linking.tab-suffix | true | [Linked] / [Unlinked] in the tab list | |
| Playtime | playtime.afk-detection | true | Detect AFK players |
playtime.afk-threshold | 300 | Seconds of no movement or looking around before AFK | |
playtime.exclude-afk | true | AFK time doesn't count | |
playtime.autosave-interval | 5 | Minutes between saves | |
playtime.check-interval | 60 | Seconds between reward checks | |
playtime.timezone | "" | Time zone for daily/weekly/monthly playtime, e.g. Europe/Berlin (empty = server). Weeks start on Monday. | |
| Rewards | rewards.claim-mode | AUTO | AUTO = given instantly, MANUAL = players claim in /rewards |
rewards.notify-unclaimed | true | Notify players about claimable rewards, and on join | |
rewards.effects.title | true | Title on reward | |
rewards.effects.sound | entity.player.levelup | Sound key (empty = none) | |
rewards.effects.firework | false | Harmless firework on reward | |
| Database | database.* | sqlite | sqlite or mysql, plus connection and pool settings (restart) |
| Moderation | moderation-tracking.enabled | true | Track bans/warns/mutes/kicks |
moderation-tracking.track-commands | [...] | Extra command names to track | |
| Staff Streaks | staff-streaks.enabled | true | Enable streaks |
staff-streaks.staff-permission | ptr.staff | Who counts as staff | |
staff-streaks.interval-days | 7 | Period length | |
staff-streaks.playtime-goal-seconds | 72000 | Playtime needed per period (20 hours) | |
staff-streaks.points-goal | 0 | Staff points needed per period (0 = off) | |
staff-streaks.promotions | — | Streak count → commands | |
| Weekly Report | weekly-report.enabled / day / time / channel | true / SUNDAY / 00:00 / — | Automatic Discord summary |
| GUI | gui.click-sounds | true | Menu sounds |
| Messages | messages.* | — | All messages (MiniMessage; legacy & codes work) |
rewards.yml / staff-rewards.yml
rewards:
example_reward:
enabled: true
icon: DIAMOND # Menu icon (optional)
type: PLAYTIME # PLAYTIME | MODERATION | COMBINED
one-time: true # false = repeating
playtime-required: 3600 # Seconds
playtime-period: TOTAL # TOTAL | DAILY | WEEKLY | MONTHLY
repeat-interval: 0 # Repeating TOTAL rewards: extra playtime between grants (0 = same as requirement)
cooldown: 0 # Minimum seconds between grants (repeating)
display-name: "<aqua>Example</aqua>"
description: "Shown to players"
value: 0 # Staff points
requires: other_reward_id # Must be earned first (optional)
permission: rewards.vip # Only players with this permission (optional)
claim-mode: DEFAULT # DEFAULT | AUTO | MANUAL
moderation: # MODERATION / COMBINED
bans: 0
warns: 0
mutes: 0
kicks: 0
period: WEEKLY # DAILY (24h) | WEEKLY (7d) | MONTHLY (30d) - rolling window
minecraft:
money: 1000 # Vault
roles: [vip] # LuckPerms groups
commands: # Console; {player}, {uuid}, {reward_id}
- "give {player} diamond 5"
items: [] # Exact items - use the in-game item editor
broadcast: "<gold>{player}</gold> earned {reward_name}!"
discord:
roles: ["123456789012345678"] # Role IDs or exact names
dm-message: "Congrats!"
announcement-channel: "" # Empty = default channel
announcement-message: "{discord_mention} earned **{reward_name}**!"
Bundled player rewards: playtime_1h → playtime_10h → playtime_24h → playtime_50h → veteran_player (500h, chained with requires), plus daily_playtime (1h today, once per day) and weekly_playtime (10h this week, once per week).
Bundled staff rewards: active_moderator, warning_duty, mute_master, swift_justice, ban_hammer_monthly, dedicated_staff (10h this month + 5 bans), staff_of_the_month (50h this month + 15 bans).
Reward System
Types
| Type | Trigger |
|---|---|
PLAYTIME | Playtime reaches the requirement |
MODERATION | Moderation action counts reach the requirements (rolling window) |
COMBINED | Both playtime and moderation requirements |
Which playtime counts
playtime-period | Counts | Repeats |
|---|---|---|
TOTAL (default) | All-time playtime | One-time, or every repeat-interval of extra playtime |
DAILY | Playtime today | Once per day |
WEEKLY | Playtime this week (Mon–Sun) | Once per week |
MONTHLY | Playtime this month | Once per month |
Calendar periods use playtime.timezone. When exclude-afk is on, AFK time doesn't count.
Claiming
AUTO— granted withincheck-intervalseconds (and shortly after join).MANUAL— players are notified and click the reward in/rewards. Eligibility is re-checked on claim.- A reward's own
claim-modeoverrides the global setting;DEFAULTfollows it.
Payouts
A reward can pay any combination of Vault money, exact items, console commands (with {player}, {uuid} and {reward_id}), LuckPerms groups, a server broadcast, staff points (value), Discord roles, a Discord DM and an announcement.
Offline players
Rewards given to offline players (/ptr give) are recorded immediately; the in-game payout (money, items, commands, ranks) is delivered on their next join. Discord payouts happen immediately.
Prerequisites & permissions
requires locks a reward until another is earned; permission limits it to players with a permission. Locked rewards show the reason in /rewards.
Commands
Players
| Command | Description | Permission |
|---|---|---|
/rewards | Rewards menu (progress, claim). Alias /reward | ptr.rewards |
/rewards claim | Claim everything that's ready | ptr.rewards |
/rewards <player> | View another player's rewards | ptr.rewards.others |
/playtime [player] | Playtime stats. Alias /pt | ptr.playtime (ptr.playtime.others for others) |
/playtimetop [all|month|week|today] | Leaderboards. Aliases /pttop, /ptop | ptr.playtime |
/link · /unlink | Discord linking | ptr.link |
Admin — /ptr
Aliases: /ptrconfig, /playtimerewards, /ajdnikovrewards.
| Command | Description | Permission |
|---|---|---|
/ptr | Admin dashboard | ptr.admin |
/ptr help | Clickable command list | ptr.admin |
/ptr rewards [player|staff] | Reward manager | ptr.admin |
/ptr create <id> [player|staff] | Create a reward and open its editor | ptr.admin |
/ptr edit <reward> | Open a reward's editor | ptr.admin |
/ptr give <player> <reward> | Give a reward (alias forcepayout) | ptr.admin.reward |
/ptr revoke <player> <reward> | Revoke a reward | ptr.admin.reward |
/ptr player <name> · /ptr players | Player profile / browser | ptr.admin |
/ptr playtime <set|add|remove|reset> <player> [time] | Change playtime | ptr.admin.setplaytime |
/ptr check [player] | Run the reward check now | ptr.admin |
/ptr staff | Staff activity | ptr.admin |
/ptr settings · /ptr messages | Editors | ptr.admin |
/ptr link <player> <discordId|unlink> | Force-link (also /stafflink) | ptr.admin.link |
/ptr linkrole <group> <roleId> | Link a LuckPerms group to a Discord role | ptr.admin.linkrole |
/ptr reload | Reload everything | ptr.admin.reload |
/rewardgive · /rewardrevoke | Same as /ptr give / revoke | ptr.admin.reward |
/weeklyreport | Send the weekly report now | ptr.admin.report |
All commands tab-complete subcommands, player names (including offline players) and reward IDs.
Discord slash commands
| Command | Who | Description |
|---|---|---|
/link <code> | Players | Link your Minecraft account using the 6-digit code |
/unlink | Players | Unlink your Minecraft account |
/playtime [username] | Players | Your or someone's playtime |
/rewards [username] | Players | Earned and pending rewards |
/leaderboard | Players | The playtime leaderboard |
/profile | Players | Your linked profile |
/stafflink <username> <discord_user> | Staff | Force-link a Minecraft account to a Discord user |
/rewardgive · /rewardrevoke <username> <reward_id> | Staff | Grant or revoke a reward (reward IDs autocomplete) |
/setplaytime <username> <time> | Staff | Set a player's playtime (e.g. 2d 5h 30m) |
/playerinfo <username> | Staff | Detailed player info |
/ptrreload | Staff | Reload the plugin configuration |
/syncall | Staff | Re-check all online players for rewards |
/weeklyreport | Staff | Trigger the weekly report |
/linkrole <role> <group> | Staff | Link a Discord role to a LuckPerms group |
Staff commands need the role in discord.staff-role-id, or Discord Administrator. With no role set, only Discord administrators can use them.
Permissions
| Permission | Default | Description |
|---|---|---|
ptr.link | everyone | Link/unlink Discord |
ptr.playtime | everyone | /playtime, leaderboards |
ptr.playtime.others | everyone | Others' playtime |
ptr.rewards | everyone | /rewards, claiming |
ptr.rewards.others | OP | Others' rewards |
ptr.staff | OP | Counts as staff (streaks, staff tab in /rewards) |
ptr.bypasslink | OP | Bypass require-link |
ptr.admin | OP | Dashboard and editors |
ptr.admin.reward | OP | Give/revoke rewards (ptr.admin.forcepayout is a legacy alias) |
ptr.admin.link | OP | Force link/unlink |
ptr.admin.linkrole | OP | Link groups to Discord roles |
ptr.admin.reload | OP | Reload |
ptr.admin.setplaytime | OP | Change playtime |
ptr.admin.report | OP | Weekly report |
ptr.* | OP | Everything |
Placeholders
PlaceholderAPI
Requires PlaceholderAPI. Values are cached and refreshed every minute; live playtime is instant.
| Placeholder | Description |
|---|---|
%ptr_playtime% / _short / _raw / _hours | Total playtime |
%ptr_playtime_today% / _week / _month (+ _raw) | Period playtime |
%ptr_rank% | All-time leaderboard position (100+ beyond the top 100) |
%ptr_top_<n>_name% / _time / _raw | Leaderboard entry n (1–100) |
%ptr_next_reward% / %ptr_next_reward_remaining% | Next playtime milestone |
%ptr_rewards_earned% | Distinct rewards received |
%ptr_rewards_claimable% | Rewards waiting to be claimed |
%ptr_afk% / %ptr_linked% / %ptr_discord_id% | Status |
%ptr_streak% | Staff streak |
Message and payout placeholders
| Placeholder | Where |
|---|---|
{player} | Messages, reward commands, broadcasts, staff promotions |
{uuid} · {reward_id} | Reward commands |
{reward_name} | Reward messages, broadcasts and Discord announcements |
{discord_mention} | Discord announcement messages |
{online} | discord.bot-status |
Messages support MiniMessage formatting; legacy & and § codes are also accepted.
Staff Moderation Tracking
Moderation commands are detected from any punishment plugin (Essentials, LiteBans, AdvancedBan, LibertyBans, vanilla): ban, tempban, ipban, banip, unban, pardon, warn, mute, tempmute, unmute, kick, including plugin:command forms. Add more names under Settings → Moderation Tracking → Extra Commands (or moderation-tracking.track-commands).
Tracked actions feed MODERATION and COMBINED rewards, the Staff Activity view and the weekly report.
Staff Streaks & Promotions
Every interval-days, each player with staff-permission (checked via LuckPerms when offline) who was active in the period is evaluated. The period is met when their playtime in that period reaches playtime-goal-seconds and the staff points (reward value) they earned in it reach points-goal. Met → streak +1 and the commands for that streak level run; missed → the streak resets to 0. The timer is stored in the database.
staff-streaks:
enabled: true
staff-permission: "ptr.staff"
interval-days: 7
playtime-goal-seconds: 72000 # 20 hours
points-goal: 0 # 0 = disabled
promotions:
2:
- "lp user {player} parent add sr_mod"
4:
- "lp user {player} parent add admin"
Edit levels in game under Settings → Staff Streaks → Promotions.
Discord Integration
Bot setup
- Create an application at discord.com/developers and add a bot.
- Enable the Server Members intent.
- Invite the bot with the
botandapplications.commandsscopes. - Set Bot Token and Server (Guild) ID in
/ptr→ Settings → Discord, then restart.
Account linking
/link in Minecraft gives a 6-digit code (with a copy button) → /link <code> in Discord. Staff can force-link with /ptr link or /stafflink. With linking.require-link: true, unlinked players are sent to limbo-world or kicked.
Role sync
/ptr linkrole <group> <roleId> (or /linkrole in Discord) stores the Discord role on the LuckPerms group as discord_role_id metadata, replacing any previous mapping.
Weekly report
An automatic summary is posted on weekly-report.day at time to channel (or the default announcement channel). Configure it in Settings → Weekly Report, or send one now with /weeklyreport.
Database
SQLite by default (plugins/AjdnikovRewards/data.db), or MySQL/MariaDB through HikariCP. Database settings need a restart.
| Table | Purpose |
|---|---|
ptr_players | Username, total playtime, AFK time, first join, last seen |
ptr_playtime_daily | Active playtime per player per day (daily/weekly/monthly features) |
ptr_reward_history | Every reward granted |
ptr_pending_rewards | Payouts waiting for offline players |
ptr_staff_actions | Moderation log |
ptr_staff_streaks | Staff streaks |
ptr_linked_accounts | Minecraft ↔ Discord links |
ptr_meta | Plugin state |
MySQL / MariaDB
database:
type: mysql
host: localhost
port: 3306
name: playtimerewards
username: root
password: ""
pool:
maximum-pool-size: 10
minimum-idle: 2
connection-timeout: 30000
idle-timeout: 600000
max-lifetime: 1800000
Dependencies
| Dependency | Required | Purpose |
|---|---|---|
| Paper 1.21+ | Yes | Server platform |
| Vault + an economy | Optional | Money rewards |
| LuckPerms | Optional | Rank rewards, role sync, offline staff checks |
| PlaceholderAPI | Optional | %ptr_...% placeholders |
| Essentials / LiteBans / AdvancedBan / LibertyBans | Optional | Moderation tracking (command interception) |
JDA, HikariCP, the SQLite driver and Jackson are downloaded by the server on first start (Paper libraries). The dashboard shows which integrations are active.
Full config.yml
The default configuration shipped with 2.0.0. Most of it can be edited in game under /ptr → Settings and Messages.
# ============================================================
# AjdnikovRewards++ Configuration
# Plugin by Ajdnikov
#
# TIP: Almost everything in this file can be edited in-game.
# Run /ptr and click "Settings" or "Messages".
# ============================================================
# ---- AnziLock License ----
license:
# Insert the license key you received via Discord here (see /claim).
key: ""
# ---- Discord Bot Settings ----
# Your Discord bot token (from https://discord.com/developers/applications)
bot-token: "YOUR_BOT_TOKEN_HERE"
# The Discord server (guild) ID the bot operates in
guild-id: "YOUR_GUILD_ID"
# ---- Account Linking ----
linking:
# If true, players MUST link their Discord to play.
# Unlinked players will be kicked or sent to the limbo world.
require-link: false
# How long a link code stays valid (in seconds). Default: 600 (10 minutes)
link-code-expiry: 600
# World to teleport unlinked players to (only used if require-link is true).
# Set to "" to kick instead of teleporting.
limbo-world: "limbo"
# Show [Linked] / [Unlinked] suffix in the tab list
tab-suffix: true
# ---- Playtime Tracking ----
playtime:
# Enable AFK detection. Players who are AFK can optionally have their time excluded.
afk-detection: true
# Seconds of no movement (position or look direction) to be considered AFK
afk-threshold: 300
# If true, AFK time will NOT count towards playtime
exclude-afk: true
# How often (in minutes) to auto-save playtime data to the database
# Lower = safer against crashes, higher = less DB writes
autosave-interval: 5
# How often (in seconds) to check online players for reward eligibility
check-interval: 60
# Time zone used for daily / weekly / monthly playtime (e.g. "Europe/Berlin").
# Leave empty to use the server's time zone. Weeks start on Monday.
timezone: ""
# ---- Reward Behaviour ----
rewards:
# AUTO = rewards are given automatically as soon as they are earned
# MANUAL = players are notified and claim rewards by clicking them in /rewards
# Individual rewards can override this with "claim-mode: AUTO|MANUAL".
claim-mode: AUTO
# In MANUAL mode, tell players when a reward becomes claimable (and on join).
notify-unclaimed: true
# Feedback when a player receives a reward
effects:
# Show a title on screen (text: messages.reward-title / reward-subtitle)
title: true
# Sound key to play, e.g. "entity.player.levelup" or "ui.toast.challenge_complete". Empty = none.
sound: "entity.player.levelup"
# Launch a small firework at the player
firework: false
# ---- Database ----
database:
# "sqlite" or "mysql"
type: sqlite
# --- MySQL / MariaDB settings (only used if type is "mysql") ---
host: localhost
port: 3306
name: playtimerewards
username: root
password: ""
# HikariCP pool settings
pool:
maximum-pool-size: 10
minimum-idle: 2
connection-timeout: 30000
idle-timeout: 600000
max-lifetime: 1800000
# ---- Discord Settings ----
discord:
# Discord role ID required for staff commands (e.g., /stafflink, /rewardgive)
staff-role-id: "YOUR_STAFF_ROLE_ID"
# Default channel ID for reward announcements (can be overridden per-reward)
announcement-channel: ""
# Bot status message. Use {online} for online player count.
bot-status: "Watching {online} players online"
# ---- Moderation Tracking ----
moderation-tracking:
# Enable tracking of staff moderation actions (bans, warns, mutes, kicks)
# Used for moderation-based rewards and the weekly report.
enabled: true
# Which commands should be tracked as moderation actions?
# The plugin automatically supports LiteBans, Essentials, AdvancedBan, and LibertyBans.
# Add any custom command aliases here.
track-commands:
- "ban"
- "tempban"
- "mute"
- "tempmute"
- "warn"
- "kick"
# ---- Staff Streaks / Promotions ----
staff-streaks:
enabled: true
# Only players with this permission are evaluated (checked via LuckPerms for offline players).
staff-permission: "ptr.staff"
# Check interval in days (e.g., 7 for weekly, 1 for daily)
interval-days: 7
# Playtime goal in seconds that they must hit during the interval (e.g., 72000 = 20 hours)
playtime-goal-seconds: 72000
# Staff points (the "value" of rewards earned during the interval) also required. 0 = disabled.
points-goal: 0
# Rewards for reaching certain streaks
# format: <streak_count>:
# - "command to run"
promotions:
2:
- "lp user {player} parent add sr_mod"
4:
- "lp user {player} parent add admin"
# ---- Weekly Report ----
weekly-report:
# Enable sending an automated weekly summary report to Discord
enabled: true
# Day of the week to send the report (MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY)
day: "SUNDAY"
# Time of day to send the report in 24-hour HH:MM format (server time)
time: "00:00"
# Channel ID to send the report to.
# If left empty (""), it will use the default announcement-channel from the discord section above.
channel: ""
# ---- GUI ----
gui:
# Play click sounds in menus
click-sounds: true
# ---- Messages ----
# These support MiniMessage format (https://docs.advntr.dev/minimessage/format.html)
# Legacy §-codes are also accepted for convenience.
messages:
prefix: "<dark_gray>[<gold>PTR</gold>]</dark_gray> "
link-success: "<green>Your account has been linked to <white>{discord_tag}</white>!</green>"
link-pending: "<yellow>Use this code in Discord to link: <white>{code}</white> (expires in 10 minutes)</yellow>"
link-code-expired: "<red>That link code has expired. Generate a new one with /link</red>"
link-code-invalid: "<red>Invalid link code. Please check and try again.</red>"
link-already-linked: "<red>Your account is already linked! Use /unlink first.</red>"
unlink-success: "<green>Your account has been unlinked.</green>"
unlink-not-linked: "<red>Your account is not linked to any Discord account.</red>"
not-linked: "<red>You must link your Discord account first! Use <white>/link</white></red>"
require-link-kick: "<red>You must link your Discord account to play on this server!\nUse /link to get started.</red>"
reward-earned: "<gold>You earned a reward: <yellow>{reward_name}</yellow>!</gold>"
reward-given: "<green>Reward <yellow>{reward_name}</yellow> given to <white>{player}</white>.</green>"
reward-revoked: "<green>Reward <yellow>{reward_name}</yellow> revoked from <white>{player}</white>.</green>"
playtime-self: "<gray>Your playtime: <white>{playtime}</white></gray>"
playtime-other: "<gray>{player}'s playtime: <white>{playtime}</white></gray>"
reward-claimable: "<green>A reward is ready to claim: <yellow>{reward_name}</yellow>! <click:run_command:/rewards><hover:show_text:'Open your rewards'><gold><u>[Click to claim]</u></gold></hover></click></green>"
reward-claimed: "<green>Claimed <yellow>{reward_name}</yellow>!</green>"
reward-not-available: "<red>That reward is not available to claim right now.</red>"
reward-title: "<gold><b>Reward Unlocked!</b></gold>"
reward-subtitle: "<yellow>{reward_name}</yellow>"
reward-broadcast: "<gold>{player}</gold> <gray>earned</gray> <yellow>{reward_name}</yellow><gray>!</gray>"
unclaimed-reminder: "<yellow>You have <white>{count}</white> reward(s) waiting! <click:run_command:/rewards><hover:show_text:'Open your rewards'><gold><u>[Open /rewards]</u></gold></hover></click></yellow>"
playtime-header: "<gold><b>Playtime</b></gold> <dark_gray>»</dark_gray> <white>{player}</white>"
playtime-line: "<gray>{label}: <white>{value}</white></gray>"
next-reward: "<gray>Next reward: <yellow>{reward_name}</yellow> <dark_gray>(</dark_gray><white>{remaining}</white> <gray>left</gray><dark_gray>)</dark_gray></gray>"
no-next-reward: "<gray>You've unlocked every playtime reward. Legend!</gray>"
input-cancelled: "<gray>Input cancelled.</gray>"
input-timeout: "<gray>Input timed out.</gray>"
no-permission: "<red>You don't have permission to do that.</red>"
player-not-found: "<red>Player not found: <white>{player}</white></red>"
reload-success: "<green>Configuration reloaded successfully!</green>"
# ---- Debug ----
# Enable verbose debug logging (useful for troubleshooting)
debug: false
Troubleshooting
"No enum constant … STAFF_ACTION" / unknown reward type
2.0 logs a warning and falls back to the file's default type instead of failing. Fix the type: in the reward, or edit it in game.
Discord bot not starting
Check the token and guild ID (Settings → Discord), the Server Members intent, and that the bot was invited with applications.commands.
Rewards not granting
The reward must be enabled; in MANUAL claim mode players claim rewards in /rewards; open the player's profile → View Their Rewards Menu to see exactly which requirement is missing; use /ptr check <player> to check immediately.
Staff streaks never increase
Since 2.0 only players with ptr.staff (or your staff-permission) are evaluated. Give it to your staff group.
MySQL connection issues
Verify the credentials, that the database exists, and that port 3306 is reachable.
Need more help?
Join the Discord server for support and bug reports.