Content generated with AI — it may contain mistakes.

Systems

Statistics

The profile, the records per drill, the session and duel history, and the leaderboards built on top.

Four tables hold what a player has done. Each answers a different question, and none is rebuilt from another, which is what makes the two history tables safe to prune.

TableOne row perAnswers
aim_profilesPlayerLifetime numbers, the duel record, the overall rating and the player's settings
aim_recordsPlayer and drillThe bests, which is what a drill's leaderboard ranks
aim_sessionsFinished solo runThe session history a player scrolls through
aim_matchesParticipant per duelThe duel history

The fifth table, aim_arenas, holds the arenas and is covered on Arenas.

The profile

The row is loaded when the player joins, written on every change and again when they quit. A player whose row is still loading plays with the default settings.

FieldMoved by
SessionsEvery stored solo run. Duels do not count here.
Total hits, total shots, accuracySolo runs and duels. A shot is a hit or a miss; an expired target is neither. Accuracy is stored as a percentage so the overall board can sort on it.
Total time trainedSolo runs and duels.
Fastest flick, fastest reactionThe lowest non-zero time, from solo runs and duels alike.
Overall ratingSolo runs only: raised by however much the run raised the player's best rating in its drill.
Matches, wins, losses, win rateA decided duel.
Rounds, round wins, round lossesA decided duel, from the final series score.
Current streak, best streakDuel win streak: up by one on a win, back to zero on a loss.
Size, distance, colour, style, the five togglesThe settings screen.
Last drill, last best-ofThe last picks made in a menu, so the pickers open where the player left them.

The profile row also carries a freeze column. It is always written as true and nothing reads it; it stays so an existing table needs no migration.

/aim profile, or /aim stats, opens the profile screen: rating, accuracy, sessions and duels on the head; hits, shots, fastest flick and reaction and time trained; duels played, wins, losses, win rate and rounds; the current and best duel streak; and buttons to Records, Sessions, Duel history and Leaderboards. /aim profile <player> opens someone else's, read from the database when they are offline. The name has to be one ExyliaLib's player cache knows; otherwise the command answers player-not-found.

Records

One row per player and drill, keyed uuid:drill. A run is merged into its row when it did anything: a hit, a miss, an expired target, a false start or a single tracked tick. A run that ended during the countdown stores nothing.

A run counts whether it ran its course or not. Leaving mid-run, quitting, being taken back by ExyliaPracticeCore or pressing Play again mid-run all store the run as far as it got.

FieldMerge rule
sessionsPlus one
bestRatingThe higher. The rating is the score times the difficulty; see Scoring.
ratingSize, ratingDistanceThe size and distance multipliers the player had set, only when the rating was beaten
bestScoreThe higher
bestAccuracyThe higher, counting only a run with at least leaderboard.accuracy-min-shots shots
bestStreakThe higher. A streak is hits in a row; a miss, an expired target or a false start ends it.
mostHitsThe higher
bestComboThe higher. Only a COMBO drill builds one.
bestReactionMillisThe lower non-zero single reaction. Only a REACTION drill sets one.
bestFlickMillisThe lower non-zero time between two hits
bestOnTargetThe higher percentage of the run spent on target. Only a TRACK drill sets one.
totalHits, totalShots, totalTimeMillisAdded up

When the rating beats the old best, the difference is added to the profile's overall rating, the result screen and chat call it a personal best, and the cached boards are dropped so the player sees themselves on the board they just climbed.

Duels set no records

A duel moves the profile — the duel record, the lifetime hits, shots, time and fastest times — and writes two history rows. It never touches aim_records, so it cannot put anybody on a drill's board or raise their overall rating.

The Records screen, reached from the profile, lists every row the player holds in the order the drills appear in config.yml; a row for a drill no longer in the file goes last. Each row shows the best rating and the size and distance it was set at, the other bests, and the drill's lifetime sessions, accuracy and time.

Leaderboards

There is one board per drill, sorted by one of seven categories, and one overall board.

CategorySorts byDefault name
ratingbestRating, highest firstRating
scorebestScore, highest firstBest score
accuracybestAccuracy, highest firstAccuracy
streakbestStreak, highest firstBest streak
hitsmostHits, highest firstMost hits
reactionbestReactionMillis, lowest firstFastest reaction
combobestCombo, highest firstBest combo

Names and icons live in messages.yml under menu.categories.

A player appears once per drill board, since the records are one row per player and drill. A zero never takes a place: an unset reaction, a combo in a drill that has none, an accuracy from runs below the shot floor. So the reaction board of a flick drill and the combo board of anything but a fight stay empty.

Rating is the fair one

Only rating compares two players who set their targets up differently: it carries the difficulty of the size and distance each played at. The other categories are raw bests. Every row shows the size and distance its rating was set at, whichever category the board is sorted by.

The overall board

Everybody by the sum of their best rating in every drill, read from aim_profiles. It sorts by rating or by accuracy (lifetime accuracy) and nothing else: the category row on that board offers those two, and asking for another category shows the rating board.

Opening a board

/aim leaderboard, or /aim top, opens the board picker: the overall board first, then every drill in config order. /aim leaderboard <drill> opens that drill's board sorted by rating, and /aim leaderboard <drill> <category> by that category; overall works as the drill. An unknown drill opens the picker instead of an empty board, and an unknown category falls back to rating. Inside, the category buttons re-sort the open board in place, and the top three rows wear medals.

The same boards are readable through PlaceholderAPI, as %exyliaaimtrainer_top_<drill>_<category>_<n>% and its _value. See Placeholders.

The cache

plugins/ExyliaAimTrainer/config.yml
leaderboard:
  entries: 10
  cache-seconds: 300
  accuracy-min-shots: 20
KeyDefaultWhat it does
entries10Rows per board.
cache-seconds300How long a board is kept before the database is asked again. Anything below 5 is treated as 5. Read when the plugin starts: a reload does not change it.
accuracy-min-shots20Shots a run needs before its accuracy may become a best. Ten out of ten is not a record.

Every board keeps two copies: a fresh one, which expires after cache-seconds, and the last one ever read. A menu waits for a fresh read; a placeholder shows the last copy while the fresh read runs in the background, so a hologram never blinks back to Loading… once it has shown a board.

The fresh copies are dropped when a run beats a rating, and when a player is reset. A run that improves only another best — accuracy, hits, a streak — does not drop them: that board catches up within cache-seconds.

History

Two lists, each reached from the other: Sessions (/aim sessions) and Duel history (/aim history). Both show the newest rows first.

A session row is one stored solo run: the drill and its kind, the score, rating and difficulty, hits, misses, accuracy, precision, best streak and combo, the average flick and reaction, time on target, the duration, the average ping and the date. A run that set a personal best is drawn with a star.

A duel writes two rows to aim_matches, one per participant, so "my duels" is a one-column query. Each carries the opponent, whether the player won, the drill, the best-of, the rounds for and against, the points for and against, the hits, the accuracy, the duration and when it ended. Only a duel that has a winner writes them; a cancelled duel writes nothing.

plugins/ExyliaAimTrainer/config.yml
history:
  entries: 20
  retention-days: 30
  prune-interval-minutes: 60
KeyDefaultWhat it does
entries20Rows shown, in each of the two lists.
retention-days30Session and duel rows older than this are deleted. 0 keeps everything.
prune-interval-minutes60How often the prune runs. Read when the plugin starts. The first duel sweep runs a minute after start, the first session sweep ninety seconds after.

A sweep looks at the oldest 500 rows of its table and deletes the ones past the cutoff, so a backlog drains over several sweeps rather than one long transaction.

Resetting a player

From /aimtraineradmin → Players, behind a confirmation. A reset:

  • puts the profile back to zero — lifetime numbers, the duel record and the overall rating — while keeping the player's settings and last picks;
  • deletes every record the player holds, so they leave every drill board;
  • deletes their session history;
  • drops the leaderboard cache.

Their rows in aim_matches are not deleted: the duel history screen still lists past duels until retention removes them, even though the confirmation reads "Every record, session and duel".

Something missing on this page? Tell us on Discord