VoteMilestones
VoteMilestones allow you to run rewards when a player’s vote totals, points, or site counts reach specific conditions.
This system replaces legacy milestone systems such as FirstVote, Cumulative, and MileStones. VotingPlugin 7.1.1 remains backward-compatible by compiling legacy sections into runtime milestones when the configuration loads.
This page explains how VoteMilestones really work, followed by lots of real examples.
Where VoteMilestones are configured
All VoteMilestones are configured in:
plugins/VotingPlugin/SpecialRewards.yml
They live under two root sections:
VoteMilestonesOptions:
VoteMilestones:
How VoteMilestones work
On every vote, VotingPlugin:
- Updates the relevant total (votes, points, sites, etc.)
- Evaluates all VoteMilestones
- Determines which milestones match
- Applies group selection rules
- Applies limits (cooldowns / windows)
- Executes rewards
VoteMilestones are not automatically one-time unless you use a Limit.
VoteMilestonesOptions (group selection)
Groups control how many milestones can trigger per vote.
VoteMilestonesOptions:
Groups:
Default: ALL
RankRewards: HIGHEST
Group modes
| Mode | Meaning |
|---|---|
ALL |
All matching milestones in the group run |
FIRST |
Only the first matching milestone (file order) |
HIGHEST |
Only the “best” milestone runs |
HIGHEST rules
Atmilestones beatEvery- Higher matched value wins
- Earlier file order breaks ties
If a milestone has no Group, it automatically uses Default.
VoteMilestone fields
Basic structure:
VoteMilestones:
ExampleId:
Enabled: true
Total: ALLTIME_VOTES
At: 100
Group: Default
Limit:
Type: NONE
Rewards:
Commands:
- "say %player% hit %amount%"
Core keys
| Key | Purpose |
|---|---|
Enabled |
Enable/disable milestone |
Total |
What value is checked |
At |
Exact totals (supports ranges & lists) |
Every |
Repeating trigger |
Group |
Group selection bucket |
Limit |
Prevents re-triggering |
Rewards |
What runs when matched |
Supported totals (Total:)
| Value | Meaning |
|---|---|
ALLTIME_VOTES |
Lifetime votes |
DAILY_VOTES |
Votes today |
WEEKLY_VOTES |
Votes this week |
MONTHLY_VOTES |
Votes this month |
POINTS |
Vote points |
ALLSITES_TODAY |
Unique sites voted today |
Friendly aliases like AllTime, Daily, Weekly, Monthly, and Points also work.
Triggers: At vs Every
Every (multiples)
Every: 25
Triggers when the total is divisible by 25 (25, 50, 75, …)
At (exact totals)
Single value
At: 50
List
At:
- 25
- 50
- 100
Ranges (with optional steps)
At:
- "10..100 step 10"
- "250..500 step 50"
Ranges are expanded safely and automatically.
Limits
Limits control how often a milestone can trigger.
Limit:
Type: COOLDOWN
Duration: 12h
Limit types
| Type | Behavior |
|---|---|
NONE |
No limit |
WINDOW_DAY |
Once per day |
WINDOW_WEEK |
Once per week |
WINDOW_MONTH |
Once per month |
COOLDOWN |
Once per duration |
Duration supports:
30m, 12h, 1d, 2w, 1mo
Examples
Example: First-ever vote
VoteMilestones:
FirstVote:
Enabled: true
Total: ALLTIME_VOTES
At: 1
Rewards:
Messages:
Player: "&aThanks for your first vote!"
Commands:
- "eco give %player% 100"
Example: First vote of the day
VoteMilestones:
FirstVoteToday:
Enabled: true
Total: DAILY_VOTES
At: 1
Rewards:
Messages:
Player: "&eThanks for voting today!"
Example: Every 10 total votes
VoteMilestones:
Every10Votes:
Enabled: true
Total: ALLTIME_VOTES
Every: 10
Rewards:
Commands:
- "crate give %player% vote 1"
Example: Multiple exact milestones
VoteMilestones:
BigMilestones:
Enabled: true
Total: ALLTIME_VOTES
At:
- 25
- 50
- 100
Rewards:
Broadcast:
Message: "&6%player% reached %amount% total votes!"
Example: Range + step milestones
VoteMilestones:
SteppedMilestones:
Enabled: true
Total: ALLTIME_VOTES
At:
- "10..100 step 10"
- "250..500 step 50"
Rewards:
Commands:
- "eco give %player% %amount%"
Example: Monthly milestone
VoteMilestones:
Monthly50:
Enabled: true
Total: MONTHLY_VOTES
At: 50
Rewards:
Commands:
- "points give %player% 25"
Example: Vote points rewards
VoteMilestones:
PointRewards:
Enabled: true
Total: POINTS
At:
- 100
- 500
- 1000
Rewards:
Commands:
- "lp user %player% parent add vip"
Example: All vote sites today
VoteMilestones:
AllSitesToday:
Enabled: true
Total: ALLSITES_TODAY
At: 5
Limit:
Type: WINDOW_DAY
Rewards:
Messages:
Player: "&aYou voted on all sites today!"
Example: Cooldown-based milestone
VoteMilestones:
VoteBonusCooldown:
Enabled: true
Total: ALLTIME_VOTES
Every: 50
Limit:
Type: COOLDOWN
Duration: 12h
Rewards:
Commands:
- "eco give %player% 250"
Example: Rank rewards (HIGHEST group)
VoteMilestonesOptions:
Groups:
RankRewards: HIGHEST
VoteMilestones:
Rank50:
Group: RankRewards
Total: ALLTIME_VOTES
At: 50
Rewards:
Commands:
- "lp user %player% parent add bronze"
Rank100:
Group: RankRewards
Total: ALLTIME_VOTES
At: 100
Rewards:
Commands:
- "lp user %player% parent add silver"
Legacy migration
VotingPlugin 7.1.1 interprets the following legacy sections as runtime
milestones when SpecialRewards.yml loads:
FirstVote
FirstVoteToday
Cumulative
MileStones
AllSites
AlmostAllSites
This compatibility step does not rewrite or remove the legacy YAML. It is a
runtime mapping, not a file migration. A restart or reload therefore leaves the
old sections in SpecialRewards.yml.
The generated runtime mappings include:
| Legacy section | Runtime behavior |
|---|---|
AllSites |
ALLSITES_TODAY at the number of enabled vote sites, minimum 1, limited once per day |
AlmostAllSites |
ALLSITES_TODAY at one fewer than the number of enabled vote sites, minimum 1, limited once per day |
New configurations should use VoteMilestones. To convert an existing
configuration, back up SpecialRewards.yml, create an equivalent
VoteMilestones entry, test it, and then remove or empty the legacy reward
section. Leaving both versions configured can run both rewards when their
conditions match.
Placeholders
| Placeholder | Meaning |
|---|---|
%player% |
Player name |
%amount% |
Matched milestone value |
%total% |
Same as amount |
%votemilestone% |
Milestone ID |
%total_type% |
Total type enum |