Gamification
Softly uses a gentle, anxiety-free leveling system. Progress is cumulative and never decreases. There are no daily quotas or penalties.
10-Level System
The levels follow a nature/growth metaphor:
| Level | Name | Icon | Points Required | ~Tasks |
|---|---|---|---|---|
| 1 | Seedling | 🌱 | 0 | 0 |
| 2 | Sprout | 🌿 | 10 | 7 |
| 3 | Budding | 🌾 | 30 | 20 |
| 4 | Growing | 🌲 | 75 | 50 |
| 5 | Rooted | 🌳 | 150 | 100 |
| 6 | Thriving | 🌴 | 300 | 200 |
| 7 | Steady | 🏔️ | 500 | 330 |
| 8 | Flourishing | ⭐ | 800 | 530 |
| 9 | Masterful | 🌟 | 1,200 | 800 |
| 10 | Enlightened | 👑 | 2,000 | 1,300 |
Early levels come fast (first week of use), then gaps widen gradually. This gives new users quick wins while keeping long-term users engaged.
Points
| Action | Points |
|---|---|
| Complete a regular task | +1 |
| Complete a recurring task | +1.5 |
Recurring tasks earn more because they represent ongoing commitments. Points are awarded via User#add_points! which uses a database lock to prevent race conditions.
Level-Up Detection
When a task is completed, the mark_complete! method checks if the user crossed a level threshold. If so, the API response includes level_up: true and the mobile app shows a celebratory toast with the new level name and icon.
Streaks
The dashboard tracks daily completion streaks:
- A streak increments for each consecutive day with at least one task completion
- Today is allowed to not have completions yet (yesterday's streak still counts)
- The backend tracks both current and best-ever streak
Streak Freeze (Pro/Family)
Pro and Family users get a streak freeze that automatically activates when they miss a single day:
- One freeze per 7 days
- Applied automatically during streak calculation
- The dashboard response includes
streak_freeze_availableso the UI can show the freeze status
TIP
Streak freeze is passive -- users don't need to activate it. The system automatically preserves their streak if they miss one day.
Celebrations
The mobile app includes several celebration moments:
- Confetti overlay -- plays on task completion (ConfettiOverlay component)
- Level-up toast -- shown when crossing a level threshold
- Week complete card -- appears when all tasks for the week are done (WeekCompleteCard component)
UI Placement
Level information appears in the Settings screen as a badge below the user's name, with a progress bar showing points toward the next level. The full level journey is viewable in the LevelJourneySheet bottom sheet.
The /auth/me and task completion responses both include level data so the UI stays in sync without extra API calls.