Track your real-life skills like a character in a LitRPG novel.
The Inspiration
If you've read LitRPG fiction (Cradle, Dungeon Crawler Carl, etc.), you know the appeal of watching numbers go up. Stats, levels, skill trees - there's something satisfying about quantified progress. This app brings that feeling to real-world skill development.
How It Works
Log Your Practice - Did something that improved a skill? Log it. Spent an hour learning TypeScript? That's XP in software.frontend.typescript. Practiced guitar? XP in music.instrument.guitar. The system uses dot notation for hierarchical skills.
Watch Skills Level Up - As you accumulate XP, skills level up with satisfying visual feedback. Higher levels require exponentially more XP, mimicking the learning curve of real skills.
Skill Hierarchy - Skills are organized in trees:
software
backend
python
golang
frontend
react
typescript
devops
kubernetes
terraform
Parent skills automatically reflect your best child. If your Python is level 15 and your Go is level 8, your Backend skill shows level 15.
The Decay Mechanic
Here's where it gets interesting: inactive skills decay. Not using a skill? It gradually loses XP over time. And the decay accelerates - a skill you haven't touched in a week decays slowly, but one you've ignored for months decays rapidly.
This isn't punishment - it's motivation. The decay creates urgency to maintain skills you care about and lets unimportant skills naturally fade. It also reflects reality: use it or lose it.
Activity History
Every XP gain is logged with timestamp and notes. Browse your recent activity to see patterns: Are you neglecting certain skills? Overinvesting in others? The history tells the story of your learning journey.
Privacy First
Your skill data is yours. Google OAuth for login (no passwords to manage), but all data stays on the server - no third-party analytics, no tracking. Self-hosted friendly.
Why 'Status'?
In LitRPG novels, checking your 'status' shows your character sheet. This app is your real-life status screen. Pull it up, see where you stand, and decide what to work on next.
A Starlette backend demonstrating hierarchical data structures, time-based calculations, and file-based persistence.
Skill System Architecture
Hierarchical Skill Tree - Skills stored as flat map with dot-notation keys, but operations traverse the implicit tree:
class Skill(AppModel):
path: str # 'software.backend.python'
xp: float
level: int # Calculated from XP
last_activity: datetime
# Parent lookup:
def get_parent(path: str) -> str | None:
parts = path.rsplit('.', 1)
return parts[0] if len(parts) > 1 else None
Parent Constraint Propagation - When child XP changes, parent recalculates as max(children_xp):
def update_skill(path: str, xp_delta: float):
skill = skills[path]
skill.xp += xp_delta
# Propagate to parents
parent = get_parent(path)
while parent:
children = get_children(parent)
skills[parent].xp = max(c.xp for c in children)
parent = get_parent(parent)
Decay System
Accelerating Decay Formula - Decay rate increases with time since last activity:
def calculate_decay(skill: Skill) -> float:
days_inactive = (now - skill.last_activity).days
# Base decay: 1% per day
# Acceleration: compounds after 7 days
if days_inactive <= 7:
decay_rate = 0.01 * days_inactive
else:
base = 0.07 # First week
extra_days = days_inactive - 7
acceleration = 1.05 ** extra_days # 5% compound
decay_rate = base + (0.01 * extra_days * acceleration)
return skill.xp * min(decay_rate, 0.5) # Cap at 50%
Decay-on-Load Semantics - Decay isn't calculated continuously. When user loads their status, decay is computed from last_activity to now and applied. This keeps storage simple.
XP and Leveling Curves
XP to Level - Soft exponential (Fibonacci-ish):
def xp_for_level(level: int) -> float:
return 100 * (1.5 ** (level - 1))
# Level 1: 100 XP
# Level 5: 506 XP
# Level 10: 3,844 XP
# Level 20: 221,073 XP
Authentication Flow
Google OAuth via standard OAuth2 flow:
1. User clicks 'Sign in with Google'
2. Redirect to Google consent screen
3. Google redirects back with auth code
4. Backend exchanges code for tokens
5. Session created using itsdangerous signed cookies
Access Control Options:
- Open enrollment (anyone can sign up)
- Allowlist (only specific emails)
- Max enrollment cap (first N users)
Data Storage
Per-User JSON Files:
data/
{user_id}/
user_data.json # Skills, XP, levels
activities.json # Activity log (capped at 100)
_core/
default.json # Default skill catalog
_meta/
users.json # User registry
Activity Log - Most recent first, capped at 100 entries. Older entries are pruned on save.
Frontend Architecture
Modular Render System:
public/js/
main.js # Entry point, router
state.js # Application state management
store.js # API client
curves.js # XP/level calculations (shared with backend)
render/
status.js # Main status screen
skills.js # Skill tree visualization
activity.js # Activity log view