AstroPlayerStats Documentation
Complete configuration guide for AstroPlayerStats v1.0.0. Setup, commands, permissions, integrations with EssentialsX / CMI / LuckPerms / PlaceholderAPI, troubleshooting, and FAQ.
Overview
AstroPlayerStats is a lightweight statistics tracker that records core gameplay metrics per player and exposes them as PlaceholderAPI placeholders. Storage is SQLite by default (no external DB required) with optional MySQL for multi-server networks. The plugin records playtime, joins, mob kills, deaths, blocks broken, blocks placed, and distance walked.
Why pick this. The Spigot ecosystem has dozens of stats plugins, most of them either require expensive setup (MySQL + Redis), bundle a web dashboard nobody uses, or have not been updated since 2018. AstroPlayerStats is one JAR, one config, SQLite by default, with batched writes so it does not blow up your TPS.
Server types
- Survival SMP
- Skyblock
- Faction servers
- Network hubs
- Minigame backends
- Adventure / RPG servers
Problems it solves
- Vanilla Minecraft scoreboard is per-world and not persistent across worlds
- No easy way to show 'top playtime this week' to motivate engagement
- Other stats plugins block the main thread on every event (TPS spikes during fights)
- Existing PAPI stats placeholders require a MySQL setup that is overkill for a 50-player SMP
- Need cross-server stats but most plugins lock you into MySQL clusters
Installation
- 1
Download the plugin
Get AstroPlayerStats-1.0.0.jar from the download page.
- 2
Upload to your server
Place AstroPlayerStats-1.0.0.jar in your server's plugins/ folder.
- 3
Restart the server
Run /stop to shut down, then start the server again. Do not use /reload.
- 4
Verify installation
Check the console for "[AstroPlayerStats] Enabled" or run /plugins.
- 5
Configure
Edit plugins/AstroPlayerStats/config.yml. Use the reload command to apply changes.
Requirements: Paper, Purpur, or Folia server running Minecraft 1.20+. Java 21+.
Configuration
The default config.yml is generated on first run. Edit and reload to apply changes. Below are 4 example configs for different server types.
Default SQLite (single server)
Recommended for solo SMPs up to ~200 players. Zero external dependencies.
storage:
type: sqlite
sqlite-file: "stats.db"
tracking:
playtime: true
joins: true
mob-kills: true
player-kills: true
deaths: true
blocks-broken: true
blocks-placed: true
distance-walked: true
distance-flown: false # disable on non-elytra servers
flush:
interval-seconds: 5
max-events-per-flush: 200
placeholders:
prefix: "astrostats" # %astrostats_playtime_<player>%
# Per-stat tracking exclusions
ignore-blocks:
- GRASS_BLOCK # don't track grass break/place spam
- DIRT
- COBBLESTONEMySQL for BungeeCord network
Shared stats across multiple backend Paper servers via one MySQL DB.
storage:
type: mysql
mysql:
host: "10.0.0.5"
port: 3306
database: "astrostats"
username: "astrostats_user"
password: "<set via env>"
use-ssl: false
table-prefix: "astro_"
flush:
interval-seconds: 10
max-events-per-flush: 500
tracking:
playtime: true
joins: true
mob-kills: true
player-kills: true
deaths: true
blocks-broken: true
blocks-placed: true
distance-walked: trueMinimal tracking (just playtime + joins)
For servers that only care about activity metrics, not gameplay.
storage:
type: sqlite
tracking:
playtime: true
joins: true
mob-kills: false
player-kills: false
deaths: false
blocks-broken: false
blocks-placed: false
distance-walked: falseSkyblock-focused config
On Skyblock, block-break/place is constant. Sample only mob kills and playtime.
storage:
type: sqlite
tracking:
playtime: true
joins: true
mob-kills: true
player-kills: false
deaths: true
blocks-broken: false # too noisy on skyblock
blocks-placed: false
distance-walked: false
flush:
interval-seconds: 30 # slower flush = less DB writesConfig location
plugins/AstroPlayerStats/config.ymlUse Cases
Real scenarios with step-by-step setup. Pick the closest match to your server and adapt.
Display top playtime in /list or sidebar scoreboard
Scenario: You want a 'most active players' sidebar in spawn.
- Install AstroPlayerStats with default SQLite config.
- Install PlaceholderAPI.
- Install a scoreboard plugin (FeatherBoard, ScoreboardEX).
- In your scoreboard config, use %astrostats_top_playtime_1% through _5% to display the top 5 players by playtime.
- Reload the scoreboard plugin to pick up the placeholders.
Weekly leaderboard reset for events
Scenario: You run a 'most mob kills this week' competition.
- Use the built-in /astrostats reset weekly command (or set 'auto-reset.weekly: true' in config).
- Stats reset every Monday at 00:00 server time by default.
- Display via placeholder %astrostats_weekly_mob_kills_<player>%.
- Pair with a rewards plugin to grant rewards to top 3 at end of week.
Anti-AFK farming with deaths/distance combination
Scenario: You suspect some players are AFK-farming mobs in a farm while idle. You can detect this by comparing playtime to distance-walked.
- Pull a per-player CSV: /astrostats export <player>.
- Calculate playtime/distance-walked ratio.
- Players with very high playtime but near-zero distance are likely idle in a farm.
- Combine with your AFK plugin's logs to confirm.
Donor benefit: see your lifetime stats
Scenario: Donors want a /stats command that shows their lifetime metrics.
- Install AstroPlayerStats.
- Run /astrostats stats <player> to display the player's stats in chat (any player can run on themselves).
- Restrict the lookup of other players' stats to a permission node (astrostats.lookup.others) so it is donor-only.
Discord bot integration showing live stats
Scenario: Your Discord bot shows '<player> has 142h playtime, 12,450 mob kills'.
- Set up MySQL storage so your Discord bot can read directly.
- Bot queries the SELECT directly from the astrostats table.
- Or hit the read-only HTTP endpoint AstroPlayerStats exposes on port 8090 when 'http-api.enabled: true'.
Commands
| Command | Description | Permission |
|---|---|---|
/stats | Show your own stats | astrostats.see |
/stats <player> | Show another player's stats | astrostats.see.others |
/astrostats reload | Reload config | astrostats.admin |
Permissions
| Node | Description | Default |
|---|---|---|
astrostats.see | Use /stats command | true |
astrostats.see.others | View other players' stats | true |
astrostats.admin | Use reload | op |
Recommended LuckPerms group setups
default
Regular player — can see own stats only
/lp group default permission set astrostats.lookup.self truedonor
Can see other players' stats too
/lp group donor permission set astrostats.lookup.self true
/lp group donor permission set astrostats.lookup.others truestaff
Full admin: reset, export, debug
/lp group staff permission set astrostats.lookup.* true
/lp group staff permission set astrostats.reset true
/lp group staff permission set astrostats.export true
/lp group staff permission set astrostats.debug trueTip: Use LuckPerms to manage permissions per player or group.
Integrations with other plugins
How AstroPlayerStats works alongside common Spigot/Paper plugins.
PlaceholderAPI
Hard dependency. All public placeholders use the PAPI registry: %astrostats_playtime_<player>%, %astrostats_mob_kills_<player>%, %astrostats_top_playtime_1% (top-N), %astrostats_weekly_mob_kills_<player>%.
FeatherBoard / ScoreboardEX
Use AstroPlayerStats placeholders inside scoreboard configs to display per-player or top-N leaderboards.
# FeatherBoard config snippet
top-playtime:
- "&6&lTop Playtime"
- "&71. %astrostats_top_playtime_1%"
- "&72. %astrostats_top_playtime_2%"
- "&73. %astrostats_top_playtime_3%"LuckPerms
Used for permission-gating: astrostats.lookup.others (see others' stats), astrostats.export (CSV export), astrostats.reset (per-player or global reset).
Vault
Optional. If Vault is present and you set 'reward-currency: true', AstroPlayerStats can grant currency rewards on milestone (e.g., 100h playtime = $1000). Without Vault, milestone rewards are just chat broadcasts.
MythicMobs
MythicMob kills count toward mob-kills if 'count-mythic: true'. Custom mob names are recorded in the per-mob breakdown.
Jobs Reborn
Block-break/place counts include Jobs-tracked blocks. If you want to avoid double-counting, set 'ignore-jobs-blocks: true'.
Troubleshooting
/astrostats stats <player> says 'No stats found' for a player who has played
Cause: Storage backend not initialized, or player joined before AstroPlayerStats was installed.
Fix:
- Check console for 'AstroPlayerStats SQLite initialized' or 'MySQL connected' at startup.
- Players need to log in once after installation to be tracked.
- Verify the stats.db file exists in plugins/AstroPlayerStats/ and is non-empty.
- Run /astrostats debug <player> for diagnostic output.
TPS drops every 5 seconds (flush interval)
Cause: Too many events queued between flushes, or SQLite write blocking the main thread.
Fix:
- Increase 'flush.interval-seconds' to 30+ to spread writes.
- Lower 'max-events-per-flush' to 50 so each flush is shorter.
- Switch storage to MySQL on an SSD for write throughput.
- Disable tracking of high-frequency events (blocks-broken on skyblock).
MySQL connection drops after 8 hours
Cause: Default MySQL wait_timeout is 8h. Connection sits idle and gets killed.
Fix:
- Enable connection pooling: AstroPlayerStats uses HikariCP if Vault is present (auto-enabled).
- Or set 'storage.mysql.keep-alive-seconds: 1800' to send a ping every 30 min.
- On the MySQL side, raise wait_timeout to 86400 (1 day).
Placeholder %astrostats_playtime_<player>% returns blank
Cause: PlaceholderAPI not installed or AstroPlayerStats failed to register the expansion.
Fix:
- Install PlaceholderAPI plugin.
- Restart the server.
- Run /papi info astrostats to see if the expansion is registered.
- Check the AstroPlayerStats log for 'Registered PlaceholderAPI expansion'.
Stats reset unexpectedly after a server restart
Cause: Database file corrupt or got overwritten by a backup restore.
Fix:
- Check plugins/AstroPlayerStats/backups/ for daily snapshots.
- Restore the most recent backup: stop server, copy backup over stats.db, start server.
- On the next restart, set 'storage.snapshot-on-shutdown: true' for safer recovery.
Distance-walked is way too high (millions of blocks)
Cause: Elytra flight counted as walking, or a bug in PlayerMoveEvent calculation.
Fix:
- Set 'tracking.distance-flown: false' to exclude elytra distance from the walking metric.
- We split elytra into its own metric — use %astrostats_distance_flown_<player>%.
- If using a teleport plugin, /tp does not count toward distance (we filter pre/post teleport).
FAQ
Can I run AstroPlayerStats on multiple servers and share stats?
Yes. Switch storage to MySQL in config.yml and point all servers to the same database. The plugin uses Bukkit's UUID as the player key, so a player's stats follow them across servers in your network.
How accurate is the playtime tracking?
Granularity is 1 second. The plugin checks online status every 20 ticks and increments. AFK time is INCLUDED in playtime by default. To exclude AFK from playtime, set 'tracking.exclude-afk: true' — requires AstroSimpleAFK or compatible AFK plugin.
Does it track stats while a player is in spectator mode?
By default, no. Spectator mode is excluded from playtime and movement counters. Set 'tracking.include-spectator: true' to count spectator playtime.
What is the database size after 1 year on a 100-player server?
SQLite: roughly 10-30 MB. The table is normalized: one row per player per stat type. MySQL with InnoDB: similar size. Backups are gzip compressed and average 1-2 MB.
Can I reset stats for a specific player without affecting others?
Yes. Run /astrostats reset player <name>. The command requires astrostats.reset permission. There is a 5-second confirmation prompt to prevent accidents.
Are mob kills counted by mob type?
Yes. Each mob kill is recorded with the mob's EntityType. You can query per-type: %astrostats_mob_kills_<player>_ZOMBIE% gives just zombie kills. The top-N placeholders aggregate across all mob types.
Does it work with WorldGuard regions to track stats per region?
Not in 1.0. We plan a per-region stats expansion in 2.0 that lets you track 'kills in the_nether' or 'blocks broken in pvp_arena'.
What permissions do I need for the basic /astrostats stats command?
By default, any player can run /astrostats stats with no arguments and see their own stats. astrostats.lookup.others is required to see another player's stats. Permission defaults are OP for reset/admin commands, true for lookup-self.
Can I export stats to CSV for analysis?
Yes. /astrostats export player <name> writes a CSV to plugins/AstroPlayerStats/exports/<name>.csv. /astrostats export all writes one CSV per stat type for all players.
How does the weekly reset work — server timezone?
By default, weekly reset runs at server local time on Monday 00:00. Set 'auto-reset.timezone: UTC' in config to override. The reset preserves lifetime totals — only the 'weekly' counter resets.
Is there an HTTP API for external dashboards?
Optional. Set 'http-api.enabled: true' to start a read-only HTTP server on port 8090 (configurable). Endpoints: /api/player/<uuid>, /api/top/playtime, /api/all. Use it for external dashboards or Discord bots.
Does it support Geyser / Floodgate (Bedrock) players?
Yes. Bedrock players get a stable UUID through Floodgate, and stats are tracked the same way. Their join.username field is preserved for display.
Changelog
v1.0.02026-05-13
- Initial public release
- Tracks playtime, joins, mob kills, player kills, deaths, blocks broken, blocks placed, distance walked, distance flown
- SQLite storage (default) + MySQL option for multi-server
- PlaceholderAPI expansion with per-player and top-N placeholders
- /astrostats stats / reset / export / debug commands
- Batched async writes via configurable flush interval
- Weekly auto-reset support
- Optional read-only HTTP API on configurable port