PerfectFit includes a comprehensive gamification system designed to increase player engagement and retention. The system consists of daily/weekly challenges, streaks with freeze tokens, a season pass with tiered rewards, achievements, cosmetics, and personalized goals.
Challenges provide short-term goals that refresh regularly.
- Refresh: Every day at midnight UTC
- Count: 3 active daily challenges
- Duration: 24 hours to complete
- Examples:
- Score 500 points in a single game
- Clear 10 lines total
- Achieve a 3x combo
- Refresh: Every Monday at midnight UTC
- Count: 3 active weekly challenges
- Duration: 7 days to complete
- Examples:
- Score 5,000 total points
- Clear 100 lines across all games
- Play 10 games
| Type | Description |
|---|---|
Score |
Achieve a target score (single game or cumulative) |
LinesCleared |
Clear a number of lines |
Combo |
Achieve a specific combo multiplier |
GamesPlayed |
Play a certain number of games |
Accuracy |
Achieve high placement accuracy |
PerfectGame |
Complete a game with perfect moves |
Encourages daily play by tracking consecutive days of activity.
- Start: Play any game to begin a streak
- Maintain: Play at least once per day (based on your timezone)
- Lose: Missing a day resets your streak to 0
- Protect: Use a Streak Freeze Token to skip a day without losing progress
- Source: Earn from achievements and season pass rewards
- Usage: Automatically applied when you miss a day (if available)
- Limit: Maximum 3 tokens stored at once
- Manual Use: Can be used proactively via the UI
| Streak Days | Bonus |
|---|---|
| 7 days | 10% XP bonus |
| 14 days | 15% XP bonus |
| 30 days | 25% XP bonus |
| 100 days | 50% XP bonus |
Users can set their preferred timezone for streak reset calculations:
POST /api/gamification/timezone
{
"timezone": "America/New_York"
}A 7-day rotating season with tiered progression.
- Duration: 7 days per season
- Tiers: 50 tiers per season
- Progression: Earn XP to advance through tiers
- Reset: New season starts automatically when current ends
| Activity | XP Earned |
|---|---|
| Complete a game | 10-50 XP (based on score) |
| Complete daily challenge | 50-100 XP |
| Complete weekly challenge | 200-500 XP |
| Unlock achievement | 100-1000 XP |
| Maintain streak | Bonus multiplier |
Rewards are distributed at key milestones:
| Tier | Reward Type | Example |
|---|---|---|
| 1 | XP Bonus | +100 XP |
| 5 | Cosmetic | Bronze Frame |
| 10 | Streak Freeze | 1 Token |
| 15 | Cosmetic | Ocean Theme |
| 20 | XP Bonus | +500 XP |
| 25 | Cosmetic | Pro Badge |
| 30 | Streak Freeze | 2 Tokens |
| 40 | Cosmetic | Gold Frame |
| 50 | Cosmetic | Champion Badge |
POST /api/gamification/season-pass/claim-reward
{
"rewardId": 15
}Long-term goals that unlock cosmetics and bragging rights.
| Category | Description |
|---|---|
| Progression | Games played, total score milestones |
| Skill | Combos, accuracy, speed achievements |
| Dedication | Streak milestones, season completions |
| Collection | Unlock all items in a category |
| Special | Limited-time or unique achievements |
| Rarity | Color | XP Reward |
|---|---|---|
| Common | Gray | 100 XP |
| Uncommon | Green | 250 XP |
| Rare | Blue | 500 XP |
| Epic | Purple | 1000 XP |
| Legendary | Gold | 2500 XP |
| Achievement | Description | Rarity |
|---|---|---|
| First Win | Complete your first game | Common |
| Combo Master | Achieve a 5x combo | Rare |
| Century Club | Maintain a 100-day streak | Legendary |
| Speed Demon | Complete a game in under 60 seconds | Epic |
| Perfectionist | Play 10 perfect games | Epic |
| Collector | Own all cosmetics in a category | Legendary |
Achievements use a JSON-based condition system:
{
"Type": "TotalWins",
"Value": 100
}Supported condition types:
TotalWins- Total games completedStreakDays- Current streak lengthSeasonTier- Highest tier reached in a seasonWinStreak- Consecutive winsPerfectGames- Games with 100% accuracyHighAccuracyGames- Games with 95%+ accuracyGamesUnderTime- Fast completionsNightOwlGames- Games played midnight-4AM
Visual customizations unlocked through gameplay.
| Theme | Unlock Method |
|---|---|
| Classic | Default |
| Ocean | Season Pass Tier 15 |
| Forest | Achievement: 50 Games |
| Sunset | Season Pass Tier 30 |
| Night Sky | Achievement: 7-Day Streak |
| Galaxy | Season Pass Tier 50 |
| Frame | Unlock Method |
|---|---|
| Bronze | Season Pass Tier 5 |
| Silver | Achievement: 100 Games |
| Gold | Season Pass Tier 40 |
| Diamond | Achievement: 30-Day Streak |
| Champion | Season completion |
| Badge | Unlock Method |
|---|---|
| Rookie | Default |
| Pro | Season Pass Tier 25 |
| Elite | Achievement: 1000 Score |
| Legend | Achievement: 100-Day Streak |
| Grandmaster | Complete all achievements |
POST /api/gamification/cosmetics/equip
{
"cosmeticId": 5
}Dynamic goals generated based on player history.
| Type | Description |
|---|---|
| BeatAverage | Score higher than your average |
| ImproveAccuracy | Place more accurately than usual |
| NewPersonalBest | Set a new high score |
Goals appear as toast notifications at game start with:
- Target description
- Current progress percentage
- Motivational message
GET /api/gamificationReturns complete gamification state including streaks, challenges, achievements, season pass progress, and cosmetics.
GET /api/gamification/challengesReturns active daily and weekly challenges with progress.
GET /api/gamification/achievementsReturns all achievements with unlock status.
GET /api/gamification/season-passReturns current season info, tier progress, and available rewards.
GET /api/gamification/cosmeticsReturns owned cosmetics and equipped items.
GET /api/gamification/goalsReturns current personal goals.
POST /api/gamification/streak-freezeManually use a streak freeze token.
POST /api/gamification/timezone
{
"timezone": "Europe/London"
}Achievement- Achievement definitions with conditionsUserAchievement- User's unlocked achievementsChallenge- Challenge definitionsUserChallenge- User's challenge progressSeason- Season definitions with durationSeasonReward- Rewards for each tierClaimedSeasonReward- User's claimed rewardsCosmetic- Cosmetic item definitionsUserCosmetic- User's owned cosmeticsPersonalGoal- User's current goals
StreakService- Streak calculation and freeze logicChallengeService- Challenge progress trackingAchievementService- Achievement unlock detectionSeasonPassService- Tier progression and rewardsCosmeticService- Cosmetic managementPersonalGoalService- Goal generation and tracking
| Job | Schedule | Purpose |
|---|---|---|
DailyChallengeRotationJob |
Midnight UTC | Rotate daily challenges |
WeeklyChallengeRotationJob |
Monday midnight | Rotate weekly challenges |
SeasonTransitionJob |
Daily | Check for season end/start |
StreakExpiryNotificationJob |
Hourly | Notify users of expiring streaks |
| Component | Description |
|---|---|
StreakDisplay |
Animated flame/ice streak counter |
StreakFreezeButton |
Use streak freeze token |
ChallengeCard |
Challenge progress with radial indicator |
ChallengesList |
Tabbed daily/weekly challenges |
AchievementBadge |
Achievement with rarity glow |
AchievementsPanel |
Filterable achievement grid |
AchievementUnlockModal |
Celebration modal with confetti |
SeasonPassTrack |
Horizontal tier progression |
SeasonRewardCard |
Claimable reward card |
PersonalGoalCard |
Goal progress display |
PersonalGoalPrompt |
Game-start goal notification |
CosmeticSelector |
Tabbed cosmetic picker |
BoardThemePreview |
Theme preview display |
GameEndSummary |
Post-game XP and rewards |
GamificationDashboard |
Combined overview widget |
The gamification system uses a dedicated Zustand store:
// src/stores/gamificationStore.ts
interface GamificationStore {
// State
streakData: StreakData | null;
challenges: Challenge[];
achievements: Achievement[];
seasonPass: SeasonPass | null;
cosmetics: Cosmetic[];
personalGoals: PersonalGoal[];
// Actions
fetchGamificationStatus(): Promise<void>;
processGameEndGamification(result: GameEndResult): void;
useStreakFreeze(): Promise<void>;
claimSeasonReward(rewardId: number): Promise<void>;
equipCosmetic(cosmeticId: number): Promise<void>;
}{
"GamificationSettings": {
"SeedOnStartup": true,
"DailyChallengeCount": 3,
"WeeklyChallengeCount": 3,
"SeasonDurationDays": 7,
"MaxSeasonTiers": 50,
"MaxStreakFreezeTokens": 3,
"StreakNotificationCooldownHours": 24
}
}On startup (in development), the system seeds:
- 18 achievements across 5 categories
- 23 cosmetics (8 themes, 7 frames, 8 badges)
- 20 challenge templates (10 daily, 10 weekly)
- Initial season with tier rewards
- Unit Tests: Service logic, achievement conditions
- Integration Tests: API endpoints, database operations
- Component Tests: UI rendering, interactions
- Hook Tests: State management, API integration
Total: 1,400+ tests covering the gamification system.