Skip to main content
This module requires the Manage Roles permission if any reward roles are configured. Otherwise, it does not require any special permissions.
The XP module lets you track member activity and grant automatic rewards at certain activity thresholds. Members receive a semi-random amount of XP for each minute or so of activity. Voice XP is tracked over time and text XP is tracked when a message is sent with a cooldown such that spamming will not give extra XP. The XP level curve is the same as MEE6’s; see below for more details.

Restrictions & Bonuses

You can restrict channels and roles to prevent XP from being granted for any activity in those channels or by members with those roles. This can be useful for preventing people from gaining XP in spam/counting channels (e.g. if you want to reward access to certain channels based on real activity/engagement) or from AFK-farming XP in voice channels in combination with an inactive channel (Server Settings > Engagement > Inactive Channel), although be aware that bypassing this and avoiding being moved is possible. Bonus XP channels/roles can be used to increase the amount of XP given in certain channels (to incentivize their use) or to members with certain roles (e.g. as an incentive for supporters). You can set a multiplier of as low as 0x (a multipler of less than 1 will decrease the amount of XP granted) and as high as 10x. You can also set @everyone as a bonus XP role for things like server-wide events to incentivize overall activity. Note that XP bonuses and restrictions are not readily apparent to members, so make sure you are communicating these changes if you want to influence member activity/behavior with them.

Level-Up Announcements & Rank Cards

You can configure level-up announcements which will notify users when their combined level (the level derived from the sum of their text and voice XP) increases. If you set it to announce in the channel where they leveled up, they will be pinged in the channel in which they sent the message that caused the level-up or in the text-in-voice channel where they were active at the time that they leveled up. You can customize the background image for level-up announcements and the XP cards generated by the /rank command. You need to host these on an external service. Note that Discord image links will not work due to media links having expiration dates (Discord does not want people to host images using files uploaded to it and have taken steps to prevent this).

Level-Up Rewards

You can configure level-up rewards to apply when members reach specified text, voice, and/or combined XP levels. If a reward has multiple thresholds set (a threshold of 0 prevents it from being rewarded based on that XP type), it will be granted when any of those thresholds is reached. The bot will automatically assign any roles that are removed at a specific level to new members upon joining. Importing XP or resetting XP for the server or for a user will re-synchronize reward roles for all affected user(s).

XP Curve

Without any bonuses, members receive a random amount of XP uniformly distributed between 15 and 25 per minute of activity (approximately). The following table can be used to estimate reward thresholds based on target amount of time.
Level ThresholdTime
15 minutes
51 hour
104 hours
2020 hours (~1 day)
3056 hours (~2 ⅓ days)
40121 hours (~5 days)
50223 hours (~9 ¼ days)
The amount of XP (xx) required to reach a certain level (LL) follows this formula (same as MEE6): 6x=10L3+135L2+455L6x = 10 L^3 + 135 L^2 + 455 L Equivalently, the level (LL) corresponding to a specified amount of XP (xx) follows this formula: u3=11664x2+874800x621075108x4050u^3 = \sqrt{11664 x^2 + 874800 x - 621075} - 108 x - 4050 2L=u/453u/451/39/22L = -u/\sqrt[3]{45} - u/45^{1/3} - 9/2 The following code can be used to make this conversion.
# python

import math

def levelToXP(level):
    return 5 / 3 * level ** 3 + 135 / 6 * level ** 2 + 455 / 6 * level

def XPToLevel(xp):
    if xp < 1: return 0
    u = math.cbrt(math.sqrt(11664 * xp ** 2 + 874800 * xp - 621075) - 108 * xp - 4050)
    level = -u / 2 / math.cbrt(45) - 61 * math.cbrt(5 / 3) / 2 / u - 9 / 2
    return round(level, 3)
// typescript

export function levelToXp(level: number): number {
    return (5 / 3) * level ** 3 + (135 / 6) * level ** 2 + (455 / 6) * level;
}

export function xpToLevel(xp: number): number {
    if (xp < 1) return 0;

    const u = Math.cbrt(Math.sqrt(11664 * xp ** 2 + 874800 * xp - 621075) - 108 * xp - 4050);
    const level = -u / 2 / Math.cbrt(45) - (61 * Math.cbrt(5 / 3)) / 2 / u - 9 / 2;
    return Math.round(level * 1000) / 1000;
}
Last modified on February 1, 2026