Life In Character
A Habitica-inspired RPG habit tracker, built as a personal engineering study in gamification, sprite layering, and Redux-at-scale.
- Role
- Solo — design, engineering
- Timeframe
- 2025 – 2026
- Stack
- React NativeExpo SDK 54TypeScriptRedux ToolkitRedux PersistAsyncStorageReact Navigation (Material Top Tabs)
- Links
- GitHub repo

Why this exists
Life In Character is a personal engineering build — not a product. It's a Habitica-inspired RPG habit tracker I built to push on three things: a feature-based Redux architecture large enough to feel real, a sprite-layered avatar system with hundreds of assets, and the gamification mechanics (XP, gold, health, daily reset) that make Habitica work.
The sprite assets are from the open-source Habitica project, licensed CC-BY-NC-SA 3.0. That license is the reason this app can't be commercialized — and it's also the reason the case study exists in the first place. It freed me to build the thing honestly as a study, without product pressure.
Interesting calls
- 01
Feature-based Redux slices, not a single store
Six separate slices — habits, dailies, todos, player, character, inventory — each with their own selectors and reducers. Easier to reason about, easier to test in isolation, and surfaced a real insight: player state (XP, gold, health) needs to react to events from three other slices, so thunks became the clear boundary.
- 02
Redux Persist + AsyncStorage, no backend
Everything lives on-device. No account system, no cloud sync. The build rule was 'if it doesn't need a server, it doesn't get one' — which kept the project scope honest and let me focus on the mechanics rather than the plumbing.
- 03
Three task archetypes from Habitica's model
Habits (flexible positive/negative), Dailies (scheduled with streaks), Todos (one-shot). Tried collapsing them during prototyping — regretted it. The three archetypes exist because they model genuinely different behaviors; merging them made the UI worse, not simpler.
- 04
Sprite map with 460+ keys, layered avatar renderer
The avatar is a stack of sprite layers — skin, hair, shirt, armor, helmet, weapon, pet — each driven by equipment state in the inventory slice. CharacterAvatar.tsx composes the layers in Z-order so equipping an item updates the render automatically.
- 05
Daily reset with missed-task penalties
Dailies lose health when missed, which is the single most motivating mechanic in Habitica. Implementing it meant a scheduled check on app open: diff last-reset timestamp against today, apply penalties, reset streaks. Small feature, huge behavior impact.
Five screens, five decisions
01Character
The avatar is the product. Equipment from the inventory slice renders as Z-ordered sprite layers in real time — buy a helmet, see it immediately.
02Habits
Flexible behaviors with +/- buttons and unlimited interactions per day. Hits the player slice on every tap — XP and gold for positive, health damage for negative.
03Dailies
Scheduled recurring tasks with streak tracking. The real mechanic is what happens when you don't check them: health loss on next app open.
04To-Dos
One-shot tasks with optional due dates. Rewards are bigger than habits or dailies because the cost of completion is higher.
05Rewards Shop
56 purchasable items across four categories — armor, head, weapons, pets. Closes the loop: effort becomes gold becomes avatar becomes motivation to keep going.
How the pieces fit
There is no backend. State lives in six slices, persists to AsyncStorage via Redux Persist, and rehydrates on app open. The sprite renderer reads from inventory slice and composes layers automatically — equipping an item is a single dispatch.
Honest outcome
The biggest lesson was about scope. Habitica has been shipping for over a decade; my version is a system study, not a rival. Keeping that straight meant resisting feature creep — I don't need parties, challenges, or sync, because the point was to understand how the mechanics hold together, not to compete.
The sprite-layering system was the unexpected win. Building it forced a clean separation between "what's equipped" (inventory slice) and "what's rendered" (presentation layer), and that separation turned out to be the cleanest architecture decision in the project.
Attribution: Sprite and pixel-art assets are from the Habitica project (HabitRPG), licensed under CC-BY-NC-SA 3.0. This project is non-commercial and shares the same license. Source: LeoZai613/Life-In-Character.