TB-ScoreTime

📜 ScoreTime Wiki - Official Documentation

🌟 Introduction

ScoreTime is an advanced, high-performance leaderboard and reward system built specifically for modern Paper servers (1.20 - 1.21+). Designed with the "Convention over Configuration" philosophy, the system fully automates complex score-tracking logic. You no longer need to set up any cumbersome third-party storage systems; TB-ScoreTime handles everything flawlessly under the hood.

Key Features

  • Smart Tracking: Automatically routes the score calculation logic through a single reset-after-reward toggle.
    • Enabled (true): Automatically calculates a "Virtual Score" (Delta Tracking) starting from 0 for Weekly/Monthly racing events.
    • Disabled (false): Directly fetches and displays the "Real Score" (All-time permanent stats) from the system.
  • Accumulative Delay Broadcast: An exclusive sequential announcement algorithm. Leaderboards that conclude at the exact same time will automatically "queue up" and display in the chat second-by-second, completely eliminating the "Spaghetti Chat" (overlapping text) issue.
  • Fully Asynchronous Database: All SQLite/MySQL queries and reward calculations run exclusively on an Async Thread via the HikariCP Connection Pool, providing absolute protection for your server's TPS.
  • Universal Placeholder Output: By simply using a single syntax %scoretime_score_<id>%, the system will automatically know whether to return the virtual or real score of the player for any specified leaderboard.
  • Offline Compensation & Safe-Reload: Score baselines and reward schedules are persistently hard-saved. Whether the server crashes, restarts, or an Admin types /st reload mid-event, the system flawlessly restores the entire event flow.

💻 Commands & Permissions

Admin Commands (Permission: scoretime.admin or OP)

Command

Description

/st reload

Reloads configs and caches. Automatically reroutes data if switched from Virtual to Real data.

/st moveholo <id>

Moves a leaderboard hologram to your current location.

/st hidestat <player> <id>/<all>

Hides a player from a specific leaderboard (or all).

/st unhidestat <player> <id>/<all>

Unhides a player.

/st debug

Toggles detailed debug mode in the console.

Player Commands (/claim)

Permission: None required (Default for everyone).

Note: The command name can be changed in config.yml

Command

Description

/claim check

Check available pending rewards.

/claim <code_id>

Claim the reward for a specific leaderboard.

⚙️ Configuration

config.yml

# ==========================================================
#                 TB-SCORETIME CONFIGURATION
#                     Author: TienBut
# ==========================================================

# Enable/Disable debug mode.
debug: false

# Configure the default timezone used by the entire reward distribution system.
# https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
# Examples: "Asia/Ho_Chi_Minh" (Vietnam), "UTC", "America/New_York"
timezone: "Asia/Ho_Chi_Minh" #Default: "Asia/Ho_Chi_Minh"

# Customize the command players use to claim leaderboard rewards.
# Don't forget to restart the server if you change the main command.
claim-command:
  command: "claim" # Main command (e.g: /claim)
  aliases: ["reward", "claim-reward"] # Aliases (e.g: /reward)

# Automatic reward expiration system.
reward-expiration:
  # If true: Rewards will expire after the time specified below.
  # If false: Rewards will accumulate permanently until claimed.
  enabled: true
  # Expiration time (in hours).
  # Example: 24 = 1 day.
  expire-after-hours: 24

# If enabled (true), whenever a leaderboard period ends,
# the plugin will generate a snapshot (.yml) file storing all winners
# in the folder plugins/TB-ScoreTime/database-reward/ for easier tracking and verification.
log-rewards-to-yml: true

# If true:
# The plugin will store reward distribution timestamps in the database.
#
# After the server comes back online from maintenance or downtime,
# missed rewards will be automatically compensated
# (only once per missed schedule).
#
# If false:
# Reward timing data will only be stored in memory (RAM), and all schedules will reset after a server restart.
offline-compensation: true

# DATABASE
database:
  type: "sqlite" # Choose "sqlite" or "mysql"
  mysql:
    host: "localhost"
    port: "3306"
    database: "minecraft"
    username: "root"
    password: ""

holograms.yml

# Configuration Guide:
# - placeholder: PlaceholderAPI variable used to retrieve data (must be installed on the server).
# - location: Hologram location (use /st moveholo <id> to set it).
#
# Time system (reward-schedule -> type):
# - DAILY: Rewards are distributed daily at 'time'.
# - WEEKLY: Rewards are distributed weekly on 'day-of-week' at 'time'.
# - MONTHLY: Rewards are distributed monthly on 'day-of-month' at 'time'.
# - FIXED: Rewards are distributed once at 'date' and 'time'.
# ==========================================================

leaderboards:
  # ================= RICH LIST LEADERBOARD =================
  top_richest:
    title: "&e&lRICH LIST LEADERBOARD"
    placeholder: "%essentials_money%"
    location: ""
    reward-schedule:
      type: "DAILY"
      time: "00:01"
      reset-after-reward: false
    # Global broadcast settings
    # (These messages will only be shown to rewarded players.)
    broadcast:
      enabled: true
      delay: 1 # Delay 1 Second
      header:
        - "&6&m================================="
        - "&e&l⏳ RICH LIST RANKING HAS BEEN FINALIZED"
      player-format: "&a⭐ Congratulations &f%player% &a(Top %rank%) for receiving Rich List leaderboard rewards!"
      footer:
        - "&7&oType &e&o/claim top_richest_all &7&oto claim your reward!"
        - "&6&m================================="
    # Rewards by rank (executed via console commands)
    rewards:
      '1':
        - 'eco give %player% 100000'
        - 'broadcast &e%player% has reached Top 1 Richest!'
      '2':
        - 'eco give %player% 50000'
    # Hologram display lines
    lines:
      - "&6&lTop 1: &e%player% &7- &a$%score%"
      - "&f&lTop 2: &b%player% &7- &a$%score%"
      - "&c&lTop 3: &c%player% &7- &a$%score%"

  # ================= LEVEL LEADERBOARD =================
  top_level:
    title: "&b&lLEVEL LEADERBOARD"
    placeholder: "%player_level%"
    location: ""
    reward-schedule:
      type: "WEEKLY"
      time: "06:00"
      day-of-week: "MONDAY" # Must be uppercase English: MONDAY, TUESDAY...
      reset-after-reward: false
    broadcast:
      enabled: true
      delay: 1
      header:
        - "&6&m================================="
        - "&e&l⏳ LEVEL RANKING HAS BEEN FINALIZED"
      player-format: "&a⭐ Congratulations &f%player% &a(Top %rank%) for receiving Level leaderboard rewards!"
      footer:
        - "&7&oType &e&o/claim top_level &7&oto claim your reward!"
        - "&6&m================================="
    rewards:
      '1':
        - 'give %player% netherite_ingot 5'
        - 'broadcast &b%player% is the level grinding champion!'
    lines:
      - "&b&lRank 1: &f%player% &7- &3Lv.%score%"
      - "&3&lRank 2: &f%player% &7- &3Lv.%score%"

  # =============== SUMMER EVENT (FIXED) ===============
  top_summer_event:
    title: "&c&lSUMMER EVENT"
    placeholder: "%event_score%"
    location: ""
    reward-schedule:
      type: "FIXED"
      time: "18:30"
      date: "2026-06-01" # Format: yyyy-MM-dd
      reset-after-reward: false
    broadcast:
      enabled: true
      delay: 1
      header:
        - "&6&m================================="
        - "&e&l⏳ SUMMER EVENT RANKING HAS ENDED"
      player-format: "&a⭐ Congratulations &f%player% &a(Top %rank%) for receiving Summer Event leaderboard rewards!"
      footer:
        - "&7&oType &e&o/claim top_summer &7&oto claim your reward!"
        - "&6&m================================="

messages.yml

prefix: "&8[&eScoreTime&8] &r"

errors:
  no_permission: "%prefix%&cYou do not have permission to use this command."
  player_only: "%prefix%&cOnly players can execute this command."
  invalid_code: "%prefix%&cThis claim code does not exist!"

claim:
  usage: "%prefix%&cUsage: /claim <code_id> or /claim check"
  no_rewards: "%prefix%&cYou do not have any pending rewards here!"
  inventory_full: "%prefix%&cYour inventory is full! Please clear some space."
  check_none: "%prefix%&cYou have no pending rewards."
  check_header: "&6&m=================================\n&e&lYOUR PENDING REWARDS:"
  check_format: "  &7- &f%title% &a(x%amount%)\n    &7➥ Claim command: &a/claim %code%"
  check_footer: "&6&m================================="

claim-settings.yml

# Reward claim messages and custom claim command settings
# Guide:
# - <custom_command_name>: Command keyword used after /claim (e.g: /claim top_richest_all)
#   - leaderboard-id: Target leaderboard ID (must match the leaderboards ID in holograms folder)
#   - message: Message displayed when the reward is claimed. Supports %rank% placeholder.
claims:
  top_richest_all:
    leaderboard-id: "top_richest"
    message: "&aCongratulations! You claimed your &eTop %rank% Wealth Ranking&a reward!"
  top_level:
    leaderboard-id: "top_level"
    message: "&aCongratulations! You claimed your &eTop %rank% Level Ranking"

🆘 Support & Community

If you need help with installation, found a bug, or want to suggest new features, feel free to join our development community on Discord:

👉 [TB DevSpace Discord Server]: https://discord.gg/MgMySjwnq