Seasons
Season definitions are stored as individual JSON files in configs/kyuubisoft_seasonpass/seasons/. Each file defines one season with its tiers, challenges, shop items and XP configuration.
File Structure
seasons/
├── season_1.json # First season
├── season_2.json # Second season (add as needed)
└── ...
The plugin automatically discovers all .json files in the seasons/ folder.
Metadata
| Field | Type | Default | Description |
|---|---|---|---|
id | string | — | Unique season ID (matches filename without .json) |
name | string | — | Display name (e.g., "Season 1: Explorer") |
description | string | — | Season description |
iconItem | string | — | Item ID for the season icon |
themeColor | string | "#ffd700" | Theme color (hex) |
Timing
| Field | Type | Default | Description |
|---|---|---|---|
startDate | string | — | Start date (set automatically by /spadmin start) |
endDate | string | — | End date (calculated from startDate + durationDays) |
durationDays | int | 30 | Season duration in days |
Seasons don't start/end automatically based on dates. Use /spadmin start <id> and /spadmin end to control the season lifecycle. The durationDays field is used for display and the auto-end check.
Tier System
| Field | Type | Default | Description |
|---|---|---|---|
tiers | array | — | List of 30 standard tier definitions |
bonusTiers | array | — | List of 10 bonus tier definitions |
baseXpPerTier | int | 1000 | Base XP required for tier 1 |
tierXpScaling | double | 1.08 | Exponential scaling factor |
XP Curve Formula
The XP required for each tier follows an exponential curve:
XP for Tier N = baseXpPerTier * (tierXpScaling ^ (N - 1))
Example with defaults (base: 1000, scaling: 1.08):
| Tier | XP Required | Cumulative XP |
|---|---|---|
| 1 | 1,000 | 1,000 |
| 5 | 1,360 | 5,867 |
| 10 | 1,999 | 14,487 |
| 15 | 2,937 | 27,152 |
| 20 | 4,316 | 45,762 |
| 25 | 6,341 | 73,106 |
| 30 | 9,317 | 113,283 |
Tier Definition
Each tier in the tiers and bonusTiers arrays:
| Field | Type | Description |
|---|---|---|
tier | int | Tier number (1-30 for standard, 31-40 for bonus) |
iconItem | string | Item ID for the tier icon |
freeRewards | array | Rewards available to all players |
premiumRewards | array | Rewards for premium pass holders only |
See Rewards for reward type details.
XP Sources
The xpSources object defines how much XP each gameplay action grants:
| Field | Default | Description |
|---|---|---|
blockBroken | 1 | XP per block broken |
blockPlaced | 1 | XP per block placed |
mobKill | 10 | XP per mob killed |
pvpKill | 25 | XP per player killed |
playtimePerMinute | 5 | XP per minute played |
zoneDiscovered | 50 | XP per zone discovered |
blockHarvested | 2 | XP per crop harvested |
flowerPicked | 3 | XP per flower picked |
questCompleted | 100 | XP per quest completed |
achievementUnlocked | 50 | XP per achievement unlocked |
dailyLogin | 25 | XP for daily login |
loginStreakPerDay | 10 | Bonus XP per login streak day |
loginStreakMaxDays | 30 | Maximum streak days counted |
Set any XP source to 0 to disable it. For example, set pvpKill to 0 on PvE-only servers.
XP Caps
| Field | Type | Default | Description |
|---|---|---|---|
dailyXpCap | int | 0 | Hard daily XP limit (0 = unlimited) |
dailyXpSoftCap | int | 0 | XP threshold for reduced earning (0 = disabled) |
softCapMultiplier | double | 0.25 | XP multiplier after soft cap (0.25 = 75% reduction) |
Soft Cap Example
With dailyXpSoftCap: 5000 and softCapMultiplier: 0.25:
- First 5,000 XP earned at full rate
- After 5,000 XP: every 100 XP earned only grants 25 XP
- Prevents no-life grinding while still rewarding continued play
Premium Pass
| Field | Type | Default | Description |
|---|---|---|---|
premiumEnabled | boolean | true | Enable the premium track |
premiumCost | int | 1000 | Cost in server currency |
premiumCurrencyId | string | "gold" | Currency ID (via Core ShopService) |
premiumXpBoost | double | 1.5 | XP multiplier for premium holders |
premiumCommandOnly | boolean | false | Premium only via admin command (no /sp buy) |
premiumHintText | string | null | Custom hint text for non-premium lock boxes |
Set premiumEnabled to false to completely hide the premium track, purchase button, and lock overlays. All tiers become free-track only.
Token System
| Field | Type | Default | Description |
|---|---|---|---|
seasonTokenXpRatio | int | 100 | XP per token earned (100 XP = 1 token) |
firstLoginBonusXp | int | 25 | XP bonus on first login of the season |
firstLoginBonusTokens | int | 5 | Token bonus on first login of the season |
Challenge Slots
| Field | Type | Default | Description |
|---|---|---|---|
dailyChallengeSlots | int | 3 | Number of free daily challenges |
weeklyChallengeSlots | int | 3 | Number of free weekly challenges |
premiumDailyChallengeSlots | int | 2 | Extra daily challenges for premium |
premiumWeeklyChallengeSlots | int | 1 | Extra weekly challenges for premium |
Shop Slots
| Field | Type | Default | Description |
|---|---|---|---|
dailyShopSlots | int | 4 | Number of free shop slots |
premiumDailyShopSlots | int | 2 | Extra shop slots for premium |
Login & Streaks
Login streaks reward consistent daily play:
- Each consecutive login day grants
loginStreakPerDaybonus XP - Streak XP =
min(currentStreak, loginStreakMaxDays) * loginStreakPerDay - Missing a day resets the streak to 0
- First season login grants
firstLoginBonusXp+firstLoginBonusTokens
Teaser Rewards
| Field | Type | Description |
|---|---|---|
teaserRewards | array | List of reward names shown in season preview |
Used for marketing/preview purposes in the UI. Example:
"teaserRewards": [
"Grand Explorer Lootbag",
"Premium Tools",
"Exclusive Titles"
]
Prestige System
| Field | Type | Default | Description |
|---|---|---|---|
prestigeEnabled | boolean | false | Enable the prestige system |
prestigeXpBoostPercent | double | 5.0 | XP boost per prestige level (%) |
maxPrestigeLevel | int | 10 | Maximum prestige level |
prestigeRewards | array | [] | Rewards per prestige level |
When a player reaches the maximum tier and prestigeEnabled is true, they can prestige to reset their tier progress while keeping a permanent XP boost. Each prestige level adds prestigeXpBoostPercent to the player's XP multiplier.
Configure prestigeRewards as an array of reward objects (same format as tier rewards). Each entry corresponds to a prestige level (index 0 = prestige 1, etc.).
Full Example (Abbreviated)
{
"id": "season_1",
"name": "Season 1: Explorer",
"description": "Explore the world, fight monsters, and earn exclusive rewards!",
"iconItem": "Deco_Map",
"themeColor": "#00bcd4",
"durationDays": 30,
"baseXpPerTier": 1000,
"tierXpScaling": 1.08,
"dailyXpCap": 0,
"dailyXpSoftCap": 0,
"softCapMultiplier": 0.25,
"premiumEnabled": true,
"premiumCost": 1000,
"premiumCurrencyId": "gold",
"premiumXpBoost": 1.5,
"premiumCommandOnly": false,
"premiumHintText": null,
"premiumDailyChallengeSlots": 2,
"premiumWeeklyChallengeSlots": 1,
"premiumDailyShopSlots": 2,
"prestigeEnabled": false,
"prestigeXpBoostPercent": 5.0,
"maxPrestigeLevel": 10,
"prestigeRewards": [],
"seasonTokenXpRatio": 100,
"firstLoginBonusXp": 25,
"firstLoginBonusTokens": 5,
"dailyChallengeSlots": 3,
"weeklyChallengeSlots": 3,
"dailyShopSlots": 4,
"xpSources": {
"blockBroken": 1,
"blockPlaced": 1,
"mobKill": 10,
"pvpKill": 25,
"playtimePerMinute": 5,
"zoneDiscovered": 50,
"blockHarvested": 2,
"flowerPicked": 3,
"questCompleted": 100,
"achievementUnlocked": 50,
"dailyLogin": 25,
"loginStreakPerDay": 10,
"loginStreakMaxDays": 30
},
"tiers": [
{
"tier": 1,
"iconItem": "Ingredient_Bar_Copper",
"freeRewards": [
{ "type": "item", "itemId": "Food_Bread", "amount": 5, "description": "5x Bread" }
],
"premiumRewards": [
{ "type": "tokens", "tokens": 10, "description": "10 Season Tokens" }
]
}
],
"bonusTiers": [
{
"tier": 31,
"iconItem": "Ingredient_Bar_Cobalt",
"freeRewards": [
{ "type": "lootbag", "lootbagId": "explorer_bonus", "description": "Bonus Lootbag" }
],
"premiumRewards": []
}
],
"dailyChallenges": [],
"weeklyChallenges": [],
"shopItems": [],
"teaserRewards": ["Grand Explorer Lootbag", "Premium Tools", "Exclusive Titles"]
}
Copy season_1.json, change the id and customize tiers, challenges and shop items. Then start it with /spadmin start <new_id>.