Skip to content
Now live — sign in to your guild dashboard
Guild Butler
EN
Sign in Add to Discord
Killboard

Raids

Raids & signupsAttendance & stats

Economy

Loot & settlementRegearSiphoned energy

Management

Recruitment & applicationsRoles & nicknamesRoster upkeep

Extras

GiveawaysDashboard & white-labelFeatures Pricing Docs
Sign in Add to Discord

Features Attendance & stats

Who actually shows up, and what that is worth

Every settled raid writes attendance points — weighted, so hard content counts more — to a ledger that is never edited. The points split the season pool, set giveaway odds and fill the stats cards. Ratings are opt-in, per raid.

Discord

Only you can see this

📊 Stats — @Ravn
• Raids attended: 34 · benched: 6
• Attendance points: 51
• Total earned: 48,300,000 · paid out: 40,000,000
• Current balance: 8,300,000
• Ratings: as caller 4.6⭐ (12) · as crew 4.3⭐ (28)
• Regears received: 5 · 6,400,000 (avg 1,280,000)
• Alliance raids: 7 (11 pts)

/stats me — the private reply any member can pull up. The regear and alliance lines only appear when they apply.
×1 – ×5
Attendance weight per raid
One click on the ⚖️ counter cycles it and wraps. A casual raid always publishes 0, so its counter is disabled rather than showing a number that will not be paid.
0
Ledger rows ever deleted
An undo appends compensating negative rows. Nothing is edited, nothing is removed, and the sum nets to zero on its own.
28 days
Giveaway ticket window
The trailing window a weighted draw reads: 1 ticket, plus 1 per attendance point, capped at 10.
2
Rating averages, kept apart
As caller and as crew are never blended on /stats. Being reliable crew and being a good shotcaller are different skills.

01 · Why it exists

The spreadsheet you can delete

Ask an officer who turned up for the last ten CTAs. The honest answer is a guess, a spreadsheet somebody keeps up by hand, or a scroll back through months of Discord.

What guessing costs you

Without a record, a ZvZ call-to-arms and a fifteen-minute gank squad count the same. The people who turn up for the hard content get nothing extra for it, and after a few months they stop turning up.

When a season payout or a loyalty reward is due, somebody reconstructs months of history from memory. Every disagreement about it is unanswerable, because there is nothing to point at.

Caller performance is pure opinion. Nobody can say which caller runs clean raids and which one burns a fifth of the loot on repairs, so the argument is settled by whoever talks loudest.

And attendance is the one thing that genuinely cannot be backfilled. If it was not captured at the moment the raid settled, the data does not exist. That is why the ledger was in the very first schema of this bot, before a single command displayed it.

Discord

Only you can see this

🗓️ Season Autumn · pool 10,000,001 · your points 5 / 12 (~4,166,667)

/season status — any member, any time. Their share is computed live from the ledger, so nobody has to trust a spreadsheet or an officer’s memory.

02 · How a point is earned

One counter, one settle, one row per member

No attendance command to run, no register to take. It rides on the raid you were posting anyway and the settle you were doing anyway.

  1. Set what the raid counts for officer

    In the raid builder, open the 🧩 Roles sub-panel. A counter button reads ⚖️ Attendance: ×1. Each click cycles ×1 → ×2 → ×3 → ×4 → ×5 → ×1. A muted line under it states the current value: "⚖️ Attendance weight: ×3 (max ×5) — points each attendee earns at settle." On a casual raid the counter is disabled and the line reads "⚖️ Attendance weight: 0 — casual raids earn no attendance", because casual publishes 0 whatever the button says.

  2. Members see the weight before they sign up member

    Above ×1, the public raid card carries its own line under the mode line: "⚖️ Counts ×3 for attendance — each raider earns 3 points instead of 1." A raid worth more is a reason to come, so people are told up front rather than discovering it later in their stats. At ×1 the line is suppressed — that is the baseline every raid would otherwise announce.

  3. Re-weight it after posting if the night turns out heavier officer

    The posted raid’s officer console carries its own 🧩 Roles panel with the same ⚖️ counter, so a raid can be re-weighted without reopening the builder — including a raid that has already been closed, since a closed raid is still settleable. A successful change refreshes the public card, so the promise and the stored value cannot drift apart.

  4. Settle the raid officer

    On settle, every taxed guild member on the roster gets one row in attendance_ledger worth the raid’s weight. Outsiders — pugs and allies — get nothing: they are untaxed and untracked by design. If the guild set Caller bonus points above 0, the caller gets an extra row on top of whatever they earned as a participant. Nothing else in the raid lifecycle writes attendance.

  5. Anyone checks their own numbers member

    /stats me replies privately with raids attended, raids benched, attendance points, lifetime earned and paid out, current balance, ratings received, and regears received. /menu → 🙋 Me → 📊 My stats shows the same card minus the regear line. Officers can look up another member with /stats player. Members cannot look each other up that way — only caller efficiency is open to everyone.

  6. Rate the raid, if the officer turned it on member

    When ⭐ Ratings was enabled in the builder, the settled raid post keeps one button: ⭐ Rate this raid. A confirmed crew member gets a single row of 1⭐ to 5⭐ buttons for the caller. The caller gets a "Pick a member…" dropdown of the crew, then a score row for whoever they picked. Scores are upserts, so anybody can click again and revise.

  7. The points get spent bot

    Weighted attendance is the divisor for the season pool: /season end splits the accumulated pool in proportion to each member’s season points, floors every payout, and sweeps the rounding remainder into the regear bank. The same points feed weighted giveaway odds and the fairness figures on /stats.

  8. Undo without deleting anything officer

    /unsettle never removes an attendance row. It appends compensating negative rows with reason='undo', so the sum nets to zero and the full history survives. This is why a member whose raid was undone still floors at one giveaway ticket rather than dropping to zero, and why the ledger can always be replayed.

03 · Weighting a raid

Hard content counts more

A counter on the 🧩 Roles panel, ×1 to ×5, on both the builder and the posted raid. Above ×1 the number is printed on the public card, so the promise and the stored value cannot disagree.

Why a counter and not a number field

The weight lives next to the roster controls because that is where an officer already is when they decide what kind of night this is. It cycles and wraps: five clicks takes you back to ×1, so there is no wrong value to type and nothing to validate.

The muted line under the buttons always states the current value in words, so a click has a visible before and after. On a casual raid the button is disabled with the reason shown rather than hidden — casual publishes 0 attendance whatever the counter says, and a live-looking control that changes nothing is how settings stop being trusted.

Once the raid settles the button locks and the line changes to say why: the points are already on the ledger. The guard is in the database update’s own WHERE clause, so a panel opened before a settle cannot race one through.

Discord

Only you can see this

🧩 Comp: Tank×2, Healer×4, Support×2, DPS×12
Columns: 1 (max 3) · Density: full
⚖️ Attendance weight: ×3 (max ×5) — points each attendee earns at settle.

Edit roles Roster: full Columns: 1 Attendance: ×3 Save & back
The builder’s 🧩 Roles panel. The posted raid’s console carries the same ⚖️ counter and the same state line, with ➕ Add role and ➕ Add slots in place of Edit roles and Save & back — and there the ⚖️ button is officer-only while its neighbours are open to the raid’s caller, because attendance points are economics.
Discord
🛡️
Guild Butler ✓ APP Today at 17:12
📣 Hideout Defend (4/6 · +2 🪑)
🕒 Tue 4 Aug · 20:00 · in 3 hours
🧭 Gather 19:45 · 🔊 Staging
⏳ 120m · 👑 Ravn
🏛️ Taxed — shares are credited to guild balances when this settles.
⚖️ Counts ×3 for attendance — each raider earns 3 points instead of 1.
Tanks
🛡️ Main tank — Ravn
🛡️ Off tank — Dain
Healers
💚 Holy — Nadiya
💚 Holy — *open*
Damage
⚔️ Fire — Kira
⚔️ Frost — *open*
The public raid card. The ⚖️ line appears only above ×1 — at the baseline it would be noise on every raid the guild ever posts.

Once it has settled

The panel stops offering a change and says what the raid actually paid. The value is history at that point, not a setting.

Discord

Only you can see this

⚖️ Attendance weight: ×3 — locked; this raid has settled and its points are awarded.

The same panel after the raid settles.

And what the bench gets

Silver and attendance are two independent axes, stored as one policy so a content profile inherits the whole thing or none of it. It resolves guild default → content profile → per-raid snapshot, frozen when the raid is created. A policy change tomorrow can never rewrite what a raid promised last week.

Bench policyLoot shareAttendance pointsWhat the settle board states
no reward no no 🪑 Bench (7): no share of the loot
silver a full, taxed share no 🪑 Bench (7): shares the loot
attendance only no yes 🪑 Bench (7): earns attendance, no loot
silver + attendance a full, taxed share yes 🪑 Bench (7): shares the loot and earns attendance

The disclosure is half the change. A guild settled a raid believing its bench was included; every figure on the board was correct and none of them mentioned the seven people who were not in any of them. The board now states the bench’s fate whenever a raid has one — including when the answer is "nothing" — and the count is in the line, because "Bench (7)" is what makes an officer stop and check where a bare policy name would not.

One subtlety worth knowing if you audit the data: the attendance award is filtered by the points axis specifically, not by who ended up in the silver split. Deriving it from the split would silently re-weight everyone’s season payout the moment bench silver was switched on, and would award nothing at all under an attendance-only policy, where the bench is in no split.

04 · The ledger

Rows go in. Nothing comes out.

One row per member per settled raid. Nothing is edited. Nothing is deleted. An undo writes the opposite row and leaves the original standing.

ColumnWhat it holds
guild_id, user_idWho earned it, in which server. Every read is scoped by guild.
party_idWhich raid it came from, so a settle and its undo can be matched exactly.
pointsThe raid’s weight — or its negative, on an undo row.
reasonsettlement or undo. Those are the only two the bot writes.
season_idSet for pool-mode raids, so a season split reads exactly the points earned inside it.
created_atThe timestamp the 28-day giveaway window reads.

Undo is a compensating entry, never a delete

/unsettle reverses balances, banks and attendance the same way: it writes the negative of each original row. The sums net to zero, the original rows are still there, and anybody auditing later can see both that the raid was settled and that it was reversed.

That has a pleasant side effect on the weighted giveaway draw. Because an undo’s negative row simply nets out in the SUM, the ticket calculation needs no special case for it — and the floor of one ticket means a member whose raid was undone can never be dropped to zero chance.

Written at settle, and only at settle

There is exactly one place in the codebase that creates attendance rows: the settle transaction, alongside the silver. That rule has its own regression test, because the auto-close reaper runs unattended and a bug there would quietly hand out points nobody asked for.

How a raid endsAttendance written
Settled (taxed or pool)One row per taxed member, worth the raid’s weight. Plus a caller-bonus row when the guild set one.
🛑 End · no splitNone.
Called off before it ranNone. Nobody raided.
Auto-closed by the reaperNone — and settling it afterwards still awards its points exactly once.
/unsettleA negative row per member. The originals stay.

The practical consequence of "only at settle" is worth saying out loud: a raid that ran but looted nothing still has to be settled to count. Enter a gross of 0, optionally with a participation bonus, and the settle becomes pure attendance pay funded by the guild rather than by the loot.

05 · The stats cards

Two cards: the member, and the caller

Both are private replies, computed live from the ledgers. Neither card flatters.

Earned and paid out are split by sign, not by reason

They therefore reconcile by construction: earned minus paid out always equals the current balance.

That fix exists because the earlier version filtered by reason and hid regear, manual adjustments, imports and season payouts entirely. A member holding 9,471,729 was shown as having earned 1,111,729 — an 8.3 million gap that did not exist, and that reads exactly like missing silver to whoever is looking at it.

Attended-versus-benched comes from the frozen settlement snapshot taken at settle time, so later edits to a roster never rewrite history.

Casual raids are excluded from caller stats

On purpose. A casual raid’s gross is typed by whoever ran it with no officer review, and a non-officer can both call and settle their own — so counting them would let anybody inflate their own caller reputation at will.

The two regear lines are deliberately never merged. One counts regear this person approved as an officer; the other counts what their own raids cost the guild. Two similar numbers under one label is how a stats card stops being trusted.

Discord

Only you can see this

🎯 Caller stats — @Ravn
• Raids called: 12
• Gross total: 96,400,000 · avg/raid: 8,033,333
• Repair: 4,820,000 (5.0%)
• Avg participants: 18.5
• Outcomes: success: 9, wipe: 2, partial: 1
• Ratings: as caller 4.6⭐ (12)
• Regears issued: 9 · 12,000,000 (12.4% of gross)
• Regear on raids you called: 6 · 7,300,000 (7.6% of gross)

/stats caller — open to anyone, on themselves or on a named caller. Someone who has never called a settled non-casual raid gets a one-line reply saying so instead of a card of zeroes.
Discord

Only you can see this

Taxed: by role
🪑 Bench (7): earns attendance, no loot

🔎 Settlement preview — Hideout Defend
Gross
24,000,000
Participants
18
Base share
1,266,666
Outsiders (2)
paid out 2,533,332
Members (16)
pool 20,266,668
Repair
− 1,200,000
Per-member share
1,266,666
Merchant collected
2,026,656
Regear collected
2,026,668
How did it go? (optional)
Confirm & post Recompute
The settle preview board. The outcome picker sits here rather than in the modal, and the two lines above the embed state the tax mode and the bench’s fate before anything is committed.

Why the outcome is a dropdown

It used to be a free-text box in the settle modal that expected one of three magic words and silently recorded unknown for anything else. The statistic it fed was therefore mostly unknown, which is a statistic about the input box rather than about the guild.

One click costs nothing and gets answered. The choices are ✅ Success, ➖ Partial and 💀 Wipe. An unanswered picker still stores unknown — the point was never to invent a result, only to make the honest one cheap to give.

The picker carries the payer and the participation bonus inside its own id, because a select menu’s value is gone the moment its interaction ends. Picking an outcome must not silently drop the other two things you already chose.

06 · Ratings

Crew rate the caller, the caller rates the crew

Off by default. Turned on for a specific raid with the ⭐ toggle in the builder, and then the settled post keeps one button.

The panel knows who you are

A confirmed crew member gets one row of 1⭐ to 5⭐ buttons for the caller. The caller gets a "Pick a member…" dropdown of the crew, then a score row for the person they picked — and the picker stays on screen, so they can work through the roster without reopening anything.

Somebody who was not on the raid is told so plainly. A caller with no crew to rate is told that too, rather than being shown an empty dropdown.

Each score is a single upsert keyed on the raid, the rater and the person rated. Clicking again revises your score; it never stacks a second vote.

Two averages, never one

Every rating is classified by whether the person being rated was that raid’s caller, so a member can carry "as caller 4.6⭐ (12) · as crew 4.3⭐ (28)" and both numbers stay meaningful. One average across both would tell you neither. Someone with no ratings yet reads "no ratings yet" rather than a fake zero.

Discord

Only you can see this

Rate your caller @Ravn — pick a score:

1⭐ 2⭐ 3⭐ 4⭐ 5⭐
What a crew member sees after pressing ⭐ Rate this raid on the settled post.
Discord

Only you can see this

Rating @Kira — pick a score:

Pick a member…
1⭐ 2⭐ 3⭐ 4⭐ 5⭐
The caller’s version, with a crew member picked: the score row joins the dropdown rather than replacing it.
Discord

Only you can see this

⭐ Rated @Kira 5/5. Pick another, or close.
Rate your crew — pick a member, then a score:

Pick a member…
And after a score is saved — the same panel, headed by the confirmation, with the picker still there for the next person.
Discord

Only you can see this

⭐ Rating leaderboard
1. @Nadiya — 4.9⭐ (17)
2. @Ravn — 4.6⭐ (12)
3. @Rukavytsia — 4.4⭐ (31)

/rating board — up to 25 opted-in members, ranked by average with the number of ratings in brackets. Posted as a private reply, never as a permanent message in a channel.

Nobody is on the board by default

/rating public state:on puts you there; /rating public state:off takes you off again at any time. The preference is stored per server, so opting in for one guild does not opt you in anywhere else.

It is a private reply on purpose. A leaderboard posted into a channel becomes a permanent message ranking your own members by how much people like them, which is a different and much worse product than the one we wanted to build.

An empty board tells you how to opt in rather than showing nothing at all.

07 · What points buy

A season payout, and better odds in a draw

Points are not a scoreboard for its own sake. Two things divide real silver by them — the season pool and the weighted giveaway draw — and both show their working.

The season pool

While a season is open, guild raids settle into a pool instead of paying out per raid. Outsiders are still paid immediately per content — they have no balance to defer into — and the member shares go into the pot.

Attendance rows written during a season carry that season’s id, so the split reads exactly the points earned inside it and nothing from before it started.

At the end, every payout is floored so silver stays whole, and the rounding remainder is swept into the regear bank. Nothing is created and nothing is lost — the same rule the per-raid settlement math follows.

Discord

Only you can see this

End season Autumn? Pool 10,000,001 will be split among members by attendance and credited to balances.

End season & pay out
/season end asks first. The confirm states the pool and what is about to happen to it.
Discord

Only you can see this

🏁 Season Autumn ended. Pool 10,000,001 split among 3 member(s); 1 remainder → regear.

And reports the remainder rather than quietly absorbing it.
Season “Autumn” — three raids settled into the poolPoints
ZvZ CTA ⚖️ ×3 — Ravn, Kira and Dain attend+3 each
Roads clear ⚖️ ×1 — Ravn and Kira attend+1 each
Gank squad ⚖️ ×1 — Ravn attends+1
Ravn3 + 1 + 1 = 5
Kira3 + 1 = 4
Dain3 = 3
Season total12
Pool at /season end = 10,000,001CalculationPaid
Ravn — 5 ptsfloor(10,000,001 × 5 / 12)4,166,667
Kira — 4 ptsfloor(10,000,001 × 4 / 12)3,333,333
Dain — 3 ptsfloor(10,000,001 × 3 / 12)2,500,000
Paid out10,000,000
Remainder → regear bank10,000,001 − 10,000,0001

Giveaway tickets from the same points

A giveaway’s ⚖️ Odds panel can weight the draw by attendance. The rule is one sentence on purpose: an opaque weighting is exactly what makes a draw feel rigged, so the rule is on the public card and each entrant is told their own ticket count when they enter.

The card says: "⚖️ Recent raiders get better odds — 1 ticket each, +1 per attendance point (max 10)." The officer-facing ⚖️ Odds panel spells out the 28-day window in full.

Points rather than a raid count is the whole point: points already carry content weight, so a ZvZ counts more than a gank squad without anyone maintaining a second rule. Weights are resolved at the draw in one grouped query, so a raid attended after entering still counts.

Attendance in the last 28 daysTicketsChance on the first pick
Ravn — 12 pts10 (capped)50%
Kira — 4 pts525%
Dain — 2.9 pts3 (fractions floor)15%
Newcomer — 0 pts15%
Undone raid — −5 pts1 (never zero)5%
Total tickets in the draw20

Both ends of that table are load-bearing. The floor of one ticket means a newcomer with no history can still win, and it means an undo can never zero somebody out. The cap of ten is the fairness lever: without it a single dedicated raider would own every draw, and everyone else would stop entering — which costs you far more than the prize.

08 · Allied guilds

Allies share attendance. Silver never crosses.

A hub guild runs the CTAs; the member guilds want their own players credited for turning up. Consent-gated, role-scoped, and with no money columns anywhere in the shared data.

Two acts, in two servers

A source officer runs /alliance, picks the Discord role in their server that marks the other guild’s players, and gets a one-time code: 12 characters of readable base32 with no 0, O, 1 or I in it, so it can be retyped out of a chat message. It expires in 24 hours and works once.

A subscriber officer opens /alliance → Follow with a code and enters it. Neither side gains anything unilaterally, which is the whole design: sharing your members’ activity with another server is not something one officer should be able to switch on alone.

From then on, when the alliance settles a raid, every attendee holding that role is credited into their own guild’s records. Members see an "Alliance raids" line on their own /stats, and the subscriber’s officers get an attendance board of their players.

Attribution can never block a settle

The whole attribution step — a bounded member fetch by explicit user ids, then a pure, unit-tested matcher — sits inside a try/catch that returns an empty list on any error and logs a line saying the settle was unaffected. When rows are produced they go in inside the settlement transaction, atomic with the silver.

A cross-guild convenience must never be able to stop an officer paying their own members. That is why this shipped before it had ever been proven against a live alliance: the worst case is that it does nothing.

Discord

Only you can see this

🤝 Alliance attendance sharing
Share your alliance’s raid attendance with member guilds — or follow an alliance to receive your players’ attendance.

Pick the role that marks the guild's players
Manage shares Follow with a code Alliances I follow Attendance board Raid rosters
The /alliance hub. Source controls and subscriber controls in one panel, officer-gated.
Discord

Only you can see this

✅ Share ready. Give this one-time code to that guild’s officer:
K7RQ2WMD4XZP
Role: @VITRYLA · expires in 24h. They’ll receive attendance for members holding that role here.

The code the source officer hands over. One use, 24 hours, bound to the role they picked.

One honest expansion since this first shipped: attendance is no longer the only thing that can cross. A source officer can separately opt an individual link into sharing raid rosters as well — default off, per link — which lets the subscriber’s killboard recognise a death on the hub’s CTA and offer that member a regear claim in their own guild. Roster rows are operational state rather than history: replaced in place, pruned about 48 hours after the raid, and deleted outright when the share is switched off. Still nothing financial crosses, in either direction.

09 · Everything else

The rest of it

Append-only attendance ledger

Every point ever awarded is a row that is never edited or deleted. Every total is just a sum over those rows.

One row per member per settled raid: guild, user, party, points, reason, an optional season id, and a timestamp. Rows are only appended — the two reasons the bot writes are settlement and undo, and an undo does not delete the original, it writes the negative of it. This was in the very first schema, before anything displayed it, because attendance is the one thing that genuinely cannot be backfilled: if it was not captured when the raid settled, the data does not exist. Everything downstream reads a SUM over this one table.

The ⚖️ counter, ×1 to ×5

One click on the 🧩 Roles panel says this raid counts for more. Same button in the builder and on the live raid.

Each raid stores a weight, and every attending member earns that many points at settle. The cap is deliberate: high enough to mark a CTA as worth a handful of gank squads, low enough that one raid cannot dominate a season split or a weighted draw. On the posted raid’s console the button is officer-gated even though its neighbours are open to the raid’s caller — attendance points are economics, and a caller may be a non-officer.

The weight is printed on the raid card

Above ×1 the public post says "⚖️ Counts ×3 for attendance — each raider earns 3 points instead of 1."

A weighted raid is a recruiting argument, so members are told before they sign up rather than afterwards. The line is suppressed at ×1 and on casual raids, whose mode line already says nothing is tracked. It renders the raw stored weight rather than a rounded one — a legacy raid stored at 1.5 shows ×1.5, because settle awards exactly what is stored and the card must promise what settle does.

Awarded at settle, and only at settle

Closing a raid, calling it off, or letting the reaper auto-close it writes zero attendance rows.

There is exactly one place attendance points are created: the settle transaction, alongside the silver. It has its own regression test — an auto-closed raid that an officer later settles awards its points exactly once, no more. The practical consequence is that a raid which ran but looted nothing still has to be settled to count. Enter a gross of 0, optionally with a participation bonus, and the settle becomes pure attendance pay.

Bench attendance policy

Decide whether standbys earn attendance points, independently of whether they get silver.

The bench is the flex pool: people who turned up but held no slot because the comp was full. What they get is one stored policy with two independent axes — silver and attendance — so a guild can pay a standby without letting them bank season weight for a fight they did not take, or grant the points without the silver. /settings → Raids shows the current answer as a Bench gets line and carries a button per axis, each labelled with what a press would turn on (🪑 Bench: share loot, 🪑 Bench: count attendance) or off. The policy resolves guild default → content profile → per-raid snapshot frozen at creation, so a change can never rewrite what a live raid already promised.

Caller bonus points

An optional flat attendance bonus for whoever led the raid, on top of any member award.

Set per guild in /settings → Economy as Caller bonus points, default 0. Above zero, the settle writes one extra attendance row for the raid’s caller in addition to whatever they earned as a participant. Leading a raid is work a plain participation count does not capture, and this is the attendance half of caller compensation — the silver half is a separate off-the-top caller cut. It applies to both immediate and season-pool settles.

/stats me and /stats player

Raids attended, raids benched, attendance points, lifetime earned, paid out, balance and ratings, in one private reply.

/stats me is open to anyone; /stats player <user> is officers only and refuses a non-officer with a pointer to /stats me. Attended-versus-benched counts come from the frozen settlement snapshot, so later edits to a roster never rewrite history. Earned and paid out are split by the SIGN of each ledger entry rather than by reason, which makes them reconcile by construction: earned minus paid out always equals the current balance.

/stats caller — caller efficiency

Raids called, gross total and average, repair as a percentage of gross, average party size, and the outcome tally.

Anyone can run /stats caller on themselves or name another caller. Casual raids are excluded from every figure on purpose: a casual raid’s gross is typed by whoever ran it with no officer review, and a non-officer can both call and settle their own — counting them would let anyone inflate their own caller reputation at will. Two regear lines are shown when they apply: regear the person approved as an officer, and regear their own raids cost the guild. They are never merged, because two similar numbers under one label is how a stats card stops being trusted.

Raid outcome captured at settle

A one-click ✅ Success / ➖ Partial / 💀 Wipe picker on the settle board, feeding the per-caller record.

The outcome sits on the settle preview board as a dropdown, not in the modal. It used to be a free-text field expecting one of three magic words and silently coercing anything else to "unknown", which meant the statistic it fed was mostly "unknown". One click costs nothing and gets answered. An unanswered picker still stores "unknown" rather than inventing a result.

Mutual post-raid ratings

Crew rate the caller, the caller rates the crew, 1 to 5. Opt-in per raid via the builder’s ⭐ toggle.

Ratings are off by default and turned on for a specific raid in the builder. When on, the settled raid post keeps a single ⭐ Rate this raid button. Who you are decides what the ephemeral panel shows: a confirmed crew member gets one row of 1⭐ to 5⭐ buttons for the caller; the caller gets a dropdown of the crew, then a score row for the person they picked, and the picker stays so they can work through the roster. Someone who was not on the raid is told "You weren’t part of this raid." Each score is one upsert keyed on raid, rater and ratee, so clicking again revises rather than stacking.

Ratings split by the role you held

Your average as a caller and your average as crew are reported separately, never blended, on /stats.

The summary query classifies each rating by whether the person being rated was that raid’s caller. So one member can carry "as caller 4.6⭐ (12) · as crew 4.3⭐ (28)" and the two numbers stay honest — one average over both would tell you neither. Someone with no ratings yet simply reads "no ratings yet" rather than a fake zero.

Opt-in public rating leaderboard

/rating public state:on puts you on /rating board. Off is the default and stays off until you choose.

Nobody appears on the public board without explicitly opting in, stored per guild. /rating public state:off removes you again at any time. The board lists up to 25 opted-in members ranked by average score with the number of ratings in brackets, ties broken by the number of ratings, and it is posted as a private reply so it never becomes a permanent wall-of-shame message in a channel. An empty board tells you how to opt in rather than showing nothing.

Season pool split by weighted attendance

Loot accrues over a season and is divided at the end in proportion to each member’s points.

While a season is open, guild raids settle into a pool instead of paying out per raid. Outsiders are still paid immediately per content; member shares go into the pot. Attendance rows written during a season carry that season’s id, so the split reads exactly the points earned inside it. /season end divides the pool proportionally, floors every payout so silver stays whole, and sweeps the rounding remainder into the regear bank. /season status shows any member their own points, the guild total, and what their share would be right now.

Attendance-weighted giveaway odds

One ticket, plus one per attendance point in the last 28 days, up to ten. The rule is on the card and your own ticket count is shown when you enter.

A giveaway’s ⚖️ Odds panel can weight the draw by attendance. Points rather than a raid count is the point: points already carry content weight, so a ZvZ counts more than a gank squad. The floor of one ticket is load-bearing twice — a newcomer with no history can still win, and negative points from an undo can never zero somebody out. The cap of ten is the fairness lever: without it a single dedicated raider would own every draw and everyone else would stop entering. Weights resolve at the draw, so a raid attended after entering still counts.

Alliance attendance sharing

A hub guild can credit member guilds with their own players’ attendance from alliance CTAs. No money ever crosses.

Linking takes two acts in two servers, so neither side gains anything unilaterally. A source officer runs /alliance, picks the Discord role in their server that marks the other guild’s players, and gets a one-time code. A subscriber officer opens /alliance → Follow with a code and enters it. From then on, when the alliance settles a raid, each attendee holding that role is credited into their own guild’s records. Balances, banks and the settlement reconciliation invariant are per guild and untouched.

Alliance attribution can never block a settle

The whole attribution step is wrapped so that any failure yields nothing and the money settle proceeds.

Attribution happens inside the settle: the bot resolves attendees’ roles with a bounded member fetch by explicit user ids — no privileged intent needed — and runs a pure matcher whose rules are unit-tested. That entire block sits inside a try/catch that returns an empty list on any error and logs a line saying the settle was unaffected. When rows are produced they are inserted inside the settlement transaction, so they are atomic with the silver. A cross-guild convenience must never be able to stop an officer paying their members.

Kill activity beside raid attendance

/killboard activity pairs each linked member’s kills and deaths with their attendance points.

The question an officer actually has is who is showing up and who is only showing up on the killboard — an active ganker with no raid attendance, or a loyal raider whose PvP never registers. Neither number means anything alone. The query LEFT JOINs throughout so a member with attendance and no kills, or kills and no attendance, both appear; those are precisely the interesting rows. No standalone killbot can produce this pairing, because it has never heard of the attendance ledger.

10 · Commands

Almost none of this needs a command

The counter is a button on a panel you are already in, and the points are written by a settle you were already doing. These exist for the people who prefer typing.

/stats me/stats player/stats caller/rating public/rating board/season start/season status/season end/alliance/unsettle/killboard activity/menu/settings

11 · What it cannot do

The limits, stated plainly

Attendance decides who gets paid, so being wrong about it costs real silver and real goodwill. These are the constraints we chose and the ones we have not solved.

12 · Questions

Questions officers actually ask

Do pugs and allies earn attendance points?
No. Attendance is only written for taxed guild members. Outsiders are untaxed and untracked by design: they take their full share of the loot in game and have no balance or attendance record in the bot. Who counts as a member on a given raid is decided by the guild’s tax mode, snapshotted per raid at creation.
We ran the raid but got nothing. Does it still count?
Only if you settle it. Attendance is written in the settle transaction and nowhere else, so a raid ended with 🛑 End · no split, called off, or auto-closed awards zero. To credit attendance for a raid that looted nothing, settle it with a gross of 0. You can pair that with a participation bonus, which makes the settle pure attendance pay funded by the guild.
An officer typed the wrong loot total. Does undoing it wreck attendance?
No. /unsettle appends compensating negative rows rather than deleting anything, so the sum nets to zero and the audit trail survives. Re-settling then writes fresh rows at the raid’s weight. Season-pool settlements are the exception: their silver is already in the pool, so they cannot be undone at all.
Can a member see somebody else’s stats?
Mostly not. /stats me is open to everyone and /stats player <user> is officers only, refusing a non-officer with a pointer to /stats me. The exception is /stats caller <user>: caller efficiency is deliberately open to anyone, and it includes that caller’s rating averages, because leading raids is a public role. Everything else — balances, ledgers, the rating leaderboard — stays private until you opt in with /rating public state:on.
What stops people trading 5-star ratings with a friend?
Nothing, and we would rather say so than pretend otherwise. Ratings are one score per rater per ratee per raid, upserted so nobody can stack votes, and only people who were actually confirmed on the raid can rate its caller. Beyond that there is no collusion detection and no minimum number of ratings before you appear on the board. Treat ratings as a soft signal, not a metric to pay people on.
Does alliance sharing move silver between guilds?
Never. The shared tables have no money columns at all. Balances, banks and the settlement reconciliation invariant are per guild and untouched. A subscriber guild receives attendance rows for its own players, plus — only if the source separately opts that link in — the pre-raid roster rows for its own tagged players, which the killboard death-card regear gate uses and which are pruned about 48 hours after the raid. It still cannot enumerate the alliance roster or look up anyone the alliance did not tag with the linked role.
Can we share attendance with an alliance running a different bot install?
No. Both guilds have to be served by the same deployment and database, which in practice means a white-label alliance bot that also serves the member guilds. Cross-deployment sharing would need a network API and authentication between two databases, and that is explicitly out of scope.
What happens to the weight if I change it after people have signed up?
An officer can change it any time before settle, from the builder or from the posted raid’s 🧩 Roles panel, and the public card refreshes so it always states the current value. Once the raid settles the button locks and the panel says so — the points are already in the ledger, and letting the number drift afterwards would leave the raid claiming a weight its awarded points never used. The guard lives in the database update’s own WHERE clause, so a stale panel cannot race a settle.
Does the bench count?
That is your decision, on two separate axes. /settings → Raids carries a loot toggle and an attendance toggle independently, so standbys can be paid without banking season weight, or credited with attendance without taking silver. Whatever the policy is when the raid is created is frozen onto that raid, and the settle board always states what this raid’s bench is about to get — including when the answer is nothing.

See it running before you install

The community server runs the bot in the open — a live killboard, real boards to press, and humans who answer questions.

Watch it live

Delete the spreadsheet

One counter on the raid, one row per member at settle, and a record nobody keeps by hand.