serenity

Daily Streaks

Members hit a message goal every day and keep a run going, with milestone roles.

Replace [prefix] with your server's prefix.

A streak is a run of days a member turned up and said something. They send enough messages to meet the day's goal, the day is claimed, and the number goes up. Miss a day and it goes back to one — unless the server sells them a way out.

The day that matters is the member's own day, not the server's. Somebody in Auckland finishes their Tuesday while somebody in Los Angeles is still in the middle of theirs, and both get counted for the day they actually lived through.

Turning It On

// Syntax
[prefix]streak enable [goal]

// Example
;streak enable 10

Needs Manage Server. The goal is optional — leave it off and it starts at 10 messages a day.

;streak disable    // stops counting, keeps every streak

Disabling only flips the switch. Nobody's run is lost, so turning it back on picks up where the server left off.

Members need a timezone. A streak day ends at each member's own midnight, so anyone who hasn't run /timezone set is not counted at all — not a message, not a day. It takes an IANA zone like Europe/Berlin, or just a city name.

This is the one thing that isn't discoverable from the commands, and a server where nobody has set one looks broken rather than unconfigured.

What Counts as a Message

Not every message earns progress, or holding down enter would be a strategy:

DefaultCommand
Messages per day10[prefix]streak set goal
Seconds between two that both count8[prefix]streak set cooldown
Shortest message that counts3 characters[prefix]streak set minlength
;streak set goal 15
;streak set cooldown 8
;streak set minlength 3

The cooldown is per member — one message every eight seconds counts, the rest are free to send and simply don't move the number. minlength 0 counts everything, including a bare k.

Claiming the Day

Meeting the goal is not the same as having the day. By default the member collects it themselves:

;streak claim

That is deliberate — a streak somebody has to show up and take is worth more than one that accrues in the background. Their profile turns orange the moment there is a claim waiting.

Claims have to be 4 hours apart in real time ([prefix]streak set claimgap). Hopping timezones manufactures new local days in minutes, and the gap is what stops that being worth doing. 0 turns the guard off.

Autoclaim

If you would rather nobody had to remember a command, hand it to the bot:

;streak toggle autoclaim

With autoclaim on, the message that meets the goal claims the day by itself, and Serenity says so in the channel it happened in — who it was, and where their streak went:

🔥 @member met today's goal - streak 6 -> 7

[prefix]streak claim is switched off while this is on. The two are mutually exclusive on purpose: running both would have members racing an automation they can't see.

Autoclaim suits servers where the streak is a background reward for turning up. Leave it off if you want claiming to be the deliberate little ritual — that is what makes a long run feel earned.

Keeping a Run Alive

// Syntax
[prefix]streak set grace [days]

// Example
;streak set grace 1

Grace is how many days a member may miss without losing the run. 0 is strict — one missed day and they start again at one. 1 forgives a single miss, which is usually the difference between a streak system people enjoy and one they give up on after the first weekend away. The ceiling is 7.

Restores

A run that has already lapsed can be bought back:

;streak restore

Restores are off until you configure them, and there are three numbers:

SettingDefaultWhat it does
[prefix]streak set freerestores0Free restores each member gets per month
[prefix]streak set restorecost0Currency per missed day, 0 disabling paid restores
[prefix]streak set restoredays1How many missed days one restore may cover
;streak set freerestores 1
;streak set restorecost 5000
;streak set restoredays 2

Free restores are spent before currency, and the month is the member's own local month — someone in Auckland gets their allowance back when their month turns over. Paid restores come out of the economy balance.

A restore buys continuity, not rank. The missed days are bridged so the calendar stays contiguous and the run survives, but the streak number itself doesn't move — which is what keeps the leaderboard unbuyable.

A run that lapsed longer ago than restoredays allows is gone for good. That window is the whole point of the setting: without it, currency would undo any absence at all.

Reward Roles

// Syntax
[prefix]streak rewards add [days] [role]

// Example
;streak rewards add 30 @Regular
;streak rewards remove 30 @Regular
;streak rewards list
;streak rewards reset      // deletes all of them, with a confirmation

A member's profile shows how far they are from the next one, so the ladder is visible before they reach it.

Three switches decide what happens to those roles afterwards:

ToggleDefaultWhat it does
[prefix]streak toggle removeloweroffTake the 7-day role away when the 30-day one is earned
[prefix]streak toggle stripbreakoffTake reward roles back when a run breaks
[prefix]streak toggle rejoinrolesonGive them back to a member who leaves and returns

Reward roles need Manage Roles, and Serenity's own role has to sit above every role it hands out. A reward role above the bot is silently never granted.

Looking At It

;streak              // your own
;streak @member
;streak calendar     // the last 30 days
;streak leaderboard  // the longest runs here

The profile shows the current run, the personal best, total days claimed, the server rank and a progress bar for today. The calendar is a colour grid:

🟩Claimed
🟦Restored
🟨Turned up, didn't meet the goal
🟥Missed entirely

The leaderboard ranks by the run that is still alive, so a 200-day streak somebody dropped last month doesn't sit at the top forever.

Every Setting

;streak settings
CommandDefaultRange
[prefix]streak set goal101–1000
[prefix]streak set grace00–7
[prefix]streak set cooldown8s0–3600
[prefix]streak set minlength30–500
[prefix]streak set claimgap4h0–23
[prefix]streak set restorecost00–1000000000
[prefix]streak set freerestores00–31
[prefix]streak set restoredays11–30

Wiping It

;streak reset member @member    // one member's run and history
;streak reset all               // everyone, with a confirmation

Neither can be undone, and reset all takes every member's history with it — best streaks and total days included, not just the runs currently going.