Dashboard

Ranks & XP

Mira's flagship system. Divisions, ranks, XP, and quotas โ€” everything a Roblox community needs to organize members into a real chain of command with automatic promotions from in-game playtime.

Full loop: players play โ†’ 10 minutes of active playtime = 1 XP โ†’ hit an XP threshold โ†’ auto-promoted in Discord AND in your Roblox group. Configure once; it runs on its own.

Divisions

A division is an organizational unit โ€” Special Forces, Recon, Intelligence, etc. Every member belongs to at most one division, and divisions can have their own rank ladder separate from the server-wide one.

Each division has:

  • Name โ€” displayed everywhere
  • Color โ€” used in embeds and the dashboard
  • Discord role โ€” auto-assigned when a member is added to the division
  • Parent division โ€” optional; for chains of command like "Alpha Squad" under "Special Forces"

Ranks

A rank is a position on the ladder. Ranks have:

  • Name and abbreviation (e.g. "Sergeant" / "SGT")
  • XP required โ€” the threshold that triggers auto-promotion
  • Display order โ€” higher number = more senior. Auto-promotion always moves to the highest rank the member qualifies for.
  • Division scope โ€” if set, only members in that division are eligible. Ranks with no division are server-wide.
  • Discord role โ€” auto-granted on promotion, removed from previous rank
  • Roblox group rank number โ€” the 0-255 number of the matching role in your Roblox group. If set, promotions here also fire in the actual Roblox group.
  • Auto-promotable โ€” if off, promotions to this rank become pending and require manual approval from the Audit tab.
Rank order matters. Ranks are ordered by displayOrder, highest first. When a member's XP crosses a threshold, Mira finds the highest-order rank they qualify for and promotes them there โ€” jumping multiple ranks at once if the XP jump was big.

XP system

XP flows into Mira from three sources:

  1. Playtime (main source) โ€” the Lua bridge script reports each player's active seconds every 30 seconds. Mira converts 10 minutes of active playtime into 1 XP by default. Idle players (no input for 2+ minutes) don't accumulate.
  2. Manual grants โ€” /xp add @user 100 or the "Manual XP grant" form in the XP tab of the dashboard.
  3. Game events โ€” your game can call the /api/roblox/bridge/xp-gain endpoint directly for specific in-game actions (event wins, milestones, etc). Documented in the Roblox page.

XP is tracked per (guild, Roblox user). Discord user XP is derived by joining through the roblox_links table, so a Roblox account not linked to Discord will still accumulate XP โ€” it just won't trigger Discord promotions until the account is linked via /verify.

Auto-promotion

Every XP grant checks whether the member now qualifies for a higher rank. If yes:

  1. A rank_changes row is written with changeType: "auto_promotion"
  2. The member's division_members.rankId is updated
  3. Their old Discord role is removed and the new one added
  4. If the new rank has robloxGroupRank set, Mira calls the Roblox Open Cloud Groups API to promote them in the actual group
  5. The Audit tab records the whole chain

If the target rank has Auto-promotable turned off, the promotion is queued as pending in the Audit tab instead of applying immediately. You approve or reject it manually.

Quotas

Quotas are activity targets per period. A quota has:

  • Name โ€” e.g. "Weekly patrols"
  • Target โ€” the minimum number of events required (e.g. 5)
  • Activity type โ€” patrols, events, trainings, or a custom type
  • Reset period โ€” weekly, monthly, or never
  • Scope โ€” optional division and/or rank filters, so an "Officer patrol quota" only applies to officers

Activity events are logged either from Discord (/quota log @user patrols 2) or from your game via the bridge's /api/roblox/bridge/activity endpoint. At the top of each period, Mira snapshots the previous period's totals into quota_periods for reporting, then starts fresh.

Members who don't meet quota aren't auto-punished โ€” Mira just tracks it. The Audit tab surfaces the roster, and you decide what to do (nudge, demote, ignore).

Commands

  • /xp add @user amount [reason] โ€” grant XP
  • /xp view @user โ€” see current XP + rank
  • /xp leaderboard โ€” top XP earners
  • /rank set @user rank โ€” manual promotion or demotion
  • /division assign @user division โ€” assign a member to a division
  • /quota log @user activity amount โ€” record activity
  • /quota view @user โ€” see progress against all quotas

Setup checklist

  1. Create your divisions in the Divisions tab
  2. Build your rank ladder in the Ranks tab โ€” highest displayOrder = most senior. Set XP requirements.
  3. Link Roblox group ranks: for each rank that should map to your Roblox group, set its robloxGroupRank number.
  4. Assign existing members in the Members tab or via /division assign
  5. Configure Roblox integration (Universe ID, Group ID, API key) on the Roblox page
  6. Paste the bridge script into your game and set the constants