StewardAI

Eunice · StewardAI

· 6 min read

Loop Habit Tracker: How the Score Algorithm Beats Streaks

Loop Habit Tracker skips the streak counter — its open-source score algorithm decays instead of resetting, and the formula is public code you can read.

A hand-written daily checklist and planner page, the paper version of the streak-based habit tracking most apps still copy

Most habit trackers run on the oldest mechanic in the app store: a streak counter that snaps back to zero the moment you miss a day. Loop Habit Tracker throws that mechanic out. Miss a day and nothing resets. Your score just gets a little weaker — the output of a scoring algorithm sitting in the app's own public source code as a formula, not a black box you have to trust.

That's the whole idea worth stealing. Loop ships under the GPLv3 license with its entire scoring engine in a public GitHub repo, so "more forgiving than a streak" isn't a marketing claim here — it's two lines of math anyone can open and read.

What Loop Habit Tracker actually is

Per its own README: "Loop is a mobile app that helps you create and maintain good habits, allowing you to achieve your long-term goals." It's also, in the project's own words, "completely ad-free and open source." In the README's own words, that means:

  • "All features are available to all users. There are no in-app purchases."
  • There are "no advertisements, annoying notifications or intrusive permissions."
  • The app "doesn't require an Internet connection or online account registration."
  • "Your confidential data is never sent to anyone."

It's distributed through Google Play and F-Droid, with APKs also posted on the project's GitHub releases page.

The repo itself has 10.2k stars and 1.3k forks — plenty of people have looked at this code, not just the maintainer.

The mechanism: a scoring algorithm that decays instead of resets

The part worth reading directly is Score.kt, the file that computes the number Loop shows you instead of a streak count:

fun compute(
    frequency: Double,
    previousScore: Double,
    checkmarkValue: Double
): Double {
    val multiplier = 0.5.pow(sqrt(frequency) / 13.0)
    var score = previousScore * multiplier
    score += checkmarkValue * (1 - multiplier)
    return score
}

Every day, the new score is a blend: mostly yesterday's score (weighted by multiplier), plus a little of today's checkmark (weighted by 1 - multiplier). There's no if streak broken, set to 0 branch anywhere in that logic. A single missed day just nudges the number down slightly instead of erasing it — which is exactly the behavior the README promises: "A few missed days after a long streak, however, will not completely destroy your progress."

Do the algebra: the constant 13 is a hidden half-life

The 13.0 in that formula isn't arbitrary — run the numbers and it turns out to be a half-life in disguise. For a daily habit, frequency works out to 1.0, so the multiplier is 0.5^(1/13). Raise that multiplier to the 13th power and the exponents cancel: 0.5^(13 × 1/13) = 0.5^1 = 0.5. In plain terms: if you stop doing a daily habit entirely (checkmarkValue stays at 0), its score algebraically halves every 13 days — not an estimate, just what the formula does.

For a habit scheduled three times a week (frequency ≈ 0.43), the same algebra (half-life = 13 / √frequency) stretches that half-life to roughly 20 days, so rarer habits decay more slowly. That 0.43 isn't a guess: Frequency.kt defines frequency as numerator / denominator, and its own THREE_TIMES_PER_WEEK constant is 3/7 — which is exactly 0.42857..., the number Score.kt receives.

That slower decay for less-frequent habits is consistent with a separate comment in the code, in ScoreList.kt, noting that non-daily habits get their numerator and denominator doubled "to smooth out irregular repetition schedules (for example, weekly habits performed on different days of the week)."

Who wrote it, and it shows

The maintainer behind most of this, Alinson S. Xavier (iSoron), has 582 followers and otherwise builds optimization-research tools: UnitCommitment.jl, "an extensible Julia/JuMP optimization package for the Security-Constrained Unit Commitment problem," used to help clear day-ahead electricity markets — power-grid scheduling — and MIPLearn, "an extensible framework for solving discrete optimization problems using a combination of Mixed-Integer Programming (MIP) and Machine Learning." That background is visible in the design choice itself: Loop doesn't wrap the same underlying problem in XP, HP, or gold the way Habitica does. It styles it as a decaying weighted average — the kind of smoothing you'd write for noisy time-series data, not a game.

It's a live argument, not a settled decision

The score-over-streak design isn't uncontested even inside Loop's own community. On August 24, 2026, contributor chrismit3s opened pull request #2393, titled "Optionally display streak instead of score." Its stated purpose: "Add the option to display the current streak (consecutive days the habit was marked done) instead of the score." As of this writing it's still open, with one commit and no reviews — proof that some users want the older, simpler number back, at least as an option alongside the decay curve.

Honest maintenance status

The most recent tagged release is v2.3.1, and the commit history shows that release shipped on August 14, 2025 — over a year before this was checked, with no version bump since. That's worth saying plainly rather than glossing over.

What hasn't slowed down is everything around the code. The repo carries 41 open issues and 11 open pull requests, including issues filed as recently as September 13–14, 2026. Its Discussions board — five active categories, from feature requests to technical discussion — shows posts from that same week. This looks like a project between formal releases rather than an abandoned one — the same commit-graph-and-issue-tracker check worth running on any "for good" open-source tool, like Electricity Maps' carbon-intensity engine, before trusting an "open source" label.

It's also making a different bet than its closest competitor. Loop's own contribution guidelines say: "AI-assisted pull requests are welcome, however, since they typically require additional review time to ensure code quality, they should follow the project guidelines even more strictly." The same document adds a limit: "Large (500+ line) AI-assisted pull requests from first-time contributors that implement new features without prior discussion will be closed without consideration."

Habitica went the opposite way: its iOS repo README states flatly: "This repository prohibits the submission of code generated by large language models (LLMs), AI coding assistants, or automated generation tools." That came after the same repo paused public code contributions "as of August 4, 2026." Two small open-source habit-tracking teams, two opposite answers to the same 2026 problem.

What this generalizes to

The transferable idea isn't "use exponential decay." It's the question the formula forces you to answer when you design any accountability product: does missing a day erase everything the user built, or does it just cost a little compounding interest? A streak counter is a cliff — one missed day and you fall off the whole thing. Loop's score is a slope — you can slide back down it, but climbing back up doesn't mean starting from the bottom.

The same tension shows up anywhere a system tracks momentum over time, from a spaced-repetition algorithm deciding when you'll forget a flashcard to a credit score. If you're building anything that has to represent "consistency" as a number, Loop's Score.kt is a two-line reminder that decay and reset are two different design decisions — and most apps default to the harsher one without ever questioning it.

Sources

Every link below was fetched and checked before publishing.

  1. 1.GitHub — iSoron/uhabits (Loop Habit Tracker, main repo) · checked
  2. 2.GitHub raw — uhabits README.md · checked
  3. 3.GitHub raw — uhabits LICENSE.txt (GPLv3) · checked
  4. 4.GitHub — uhabits latest release (v2.3.1) · checked
  5. 5.GitHub — uhabits commit history (master) · checked
  6. 6.GitHub — uhabits open issues · checked
  7. 7.GitHub — uhabits open pull requests · checked
  8. 8.GitHub — uhabits PR #2393 ("Optionally display streak instead of score") · checked
  9. 9.GitHub raw — Score.kt (the scoring formula source file) · checked
  10. 10.GitHub raw — Frequency.kt (defines frequency = numerator/denominator, incl. THREE_TIMES_PER_WEEK = 3/7) · checked
  11. 11.GitHub raw — ScoreList.kt (non-daily habit smoothing comment) · checked
  12. 12.GitHub raw — GUIDELINES.md (contribution and AI-assisted-PR policy) · checked
  13. 13.GitHub — uhabits Discussions · checked
  14. 14.GitHub — iSoron (Alinson S. Xavier) profile · checked
  15. 15.GitHub — ANL-CEEESA/UnitCommitment.jl (Alinson S. Xavier, co-author) · checked
  16. 16.GitHub — ANL-CEEESA/MIPLearn (Alinson S. Xavier, co-author) · checked
  17. 17.GitHub raw — HabitRPG/habitica-ios README (AI-generated-code policy, for contrast) · checked

한국어 버전 읽기 →