Leveling & Stats System
Relevant source files
The following files were used as context for generating this wiki page:
The Leveling & Stats System is a core engagement feature in Amina designed to track user activity within a guild and reward them with experience points (XP) and levels. It monitors messages, voice channel participation, and command usage to provide a comprehensive overview of member statistics. This encourages participation and allows for friendly competition through a leaderboard.
The system is composed of a central handler for tracking statistics, a database schema for storing data, and several user-facing commands to view stats and rankings. Its behavior is configurable at both the bot and guild level.
System Configuration
The stats system can be enabled or disabled globally and has several configurable parameters that control its behavior.
Sources: types/config.d.ts:70-74, src/handlers/stats.ts:46-52, src/commands/admin/settings/status.ts:89-97
| Option | Type | Default Value | Description | Source File |
|---|---|---|---|---|
STATS.ENABLED | boolean | true | A global flag to enable or disable the entire stats tracking system. | types/config.d.ts:71 |
STATS.XP_COOLDOWN | number | 60 (seconds) | The cooldown period in seconds between messages that grant XP. This is used to prevent spamming for points. | types/config.dts:72, handlers/stats.ts:46-52 |
STATS.DEFAULT_LVL_UP_MSG | string | "Congrats {member:mention}, you are now level {level}!" | The default message sent when a user levels up. This can be customized per guild. | types/config.d.ts:73 |
settings.stats.xp.channel | string | null | The guild-specific channel ID where level-up messages are sent. If not set, messages are sent in the channel where the user leveled up. | handlers/stats.ts:68-71 |
settings.stats.xp.message | string | (uses DEFAULT_LVL_UP_MSG) | The guild-specific level-up message. Supports placeholders like {member:mention} and {level}. | handlers/stats.ts:66 |
Data Model: MemberStats
User statistics are stored in the member-stats collection in MongoDB. Each document represents a member's stats within a specific guild. The schema is defined in src/database/schemas/MemberStats.ts (inferred from usage).
Sources: src/handlers/stats.ts, src/commands/stats/stats.ts
ER Diagram
This diagram shows the structure of the MemberStats document.
Schema Fields
| Field | Type | Description - |
| guild_id | String | The Discord Guild ID. Part of the composite primary key. - |
| member_id | String | The Discord Member ID. Part of the composite primary key. - |
| xp | Number | The total experience points the member has accumulated. Defaults to 0. - |
level| Number | The member's current level. Defaults to1. - |
|messages| Number | The total number of messages sent by the member. Defaults to0. a- |
|voice| Object | An object containing voice channel statistics. a- |
|commands| Object | An object containing command usage statistics. a- |
|contexts| Object | An object containing context menu usage statistics. a- |
Core Logic: Stats Tracking
The stats handler (src/handlers/stats.ts) is responsible for tracking all user activities and updating the database.
Message & XP Tracking
The trackMessageStats function is triggered for every message sent by a user.
This diagram illustrates the flow for processing a user's message to grant XP.
- XP Gain: When a user sends a message and is not on cooldown, they gain a random amount of XP between 1 and 20.
Sources: src/handlers/stats.ts:12, src/handlers/stats.ts:55 - Cooldown: To prevent spam, a cooldown is enforced. The duration is defined by
STATS.XP_COOLDOWN(defaulting to 60 seconds). AcooldownCachemap stores the timestamp of the last XP-gaining message for each user.
Sources: src/handlers/stats.ts:10, src/handlers/stats.ts:44-53, types/config.d.ts:72 - Leveling Up: A user levels up when their accumulated XP exceeds the amount needed for the next level. The formula for required XP is
level * level * 100.
Sources: src/handlers/statsts:58-60 - Level-Up Notifications: When a user levels up, a customizable message is sent. The message content and target channel can be configured at the guild level. The
parsefunction replaces placeholders like{member:mention}and{level}with actual values.
Sources: src/handlers/stats.ts:17-26, src/handlers/stats.ts:66-73
Interaction Tracking
The trackInteractionStats function increments counters for specific interactions:
- Slash Commands (
isChatInputCommand) - User Context Menus (
isUserContextMenuCommand) - Message Context Menus (
isMessageContextMenuCommand)
This data is stored in the commands and contexts objects within the MemberStats document.
Sources: src/handlers/stats.ts:80-88
Voice Channel Tracking
The trackVoiceStats function monitors voiceStateUpdate events to track time spent in voice channels.
- Connections: When a user joins a voice channel, their
voice.connectionscount is incremented.
Sources: src/handlers/stats.ts:104-107 - Time: The system records the timestamp when a user joins a voice channel using a
voiceStatesmap. When they leave, the duration is calculated in seconds and added to theirvoice.timetotal.
Sources: src/handlers/stats.ts:111-119
User-Facing Commands
Users can interact with the stats system through several slash commands.
| Command | Description | Source File |
|---|---|---|
/stats [user] | View detailed XP and message statistics for a member. | src/commands/stats/stats.ts |
/leaderboard type:xp | View the top 10 users by XP in the server. | src/commands/info/leaderboard.ts |
/stats Command
This command provides a summary of a user's tracked statistics. If no user is specified, it defaults to the user who ran the command.
The following sequence diagram shows the flow of the /stats command.
The command displays the following information from the MemberStats document:
- Messages
- Slash Commands
- XP
- Level
- Voice Connections
- Voice Time (in minutes)
Sources: src/commands/stats/stats.ts, src/data/respInfo.json:138-152
/leaderboard Command
The /leaderboard command with the xp type displays the top 10 users in the guild based on their total XP.
- It calls the
getXpLbfunction to retrieve an ordered list of members from the database. - The command checks if the stats system is enabled in the guild settings before proceeding.
- The results are cached to reduce database load on repeated requests.
Sources: src/commands/info/leaderboard.ts:60-84, src/data/respInfo.json:154-164