# /rank

> Show a member's level and XP, with a progress bar to the next level.

Shows the level and XP of a member, or of yourself.

> **Alex** is level **4**
> `███████░░░` 350 / 500 XP

This page has two parts:

1. A **Message** event that gives XP for chatting.
2. The `/rank` command that shows it.

Both use the same saved values: `xp` and `level`, stored per member.

> **Premium:** Message events only run on servers with a paid plan. The event menu shows it as **MESSAGE (Pro Only)**. On a free server, give XP from a command instead, for example a `/daily` command.

## Give XP for chatting

Open **Create → Event**. Set **Type** to **MESSAGE (Pro Only)**. Paste into **Code**:

```python
if not user.is_bot:
    last = int(member_var("xp_last", 0))
    # One reward per member per minute, so spam earns nothing extra.
    if unix_timestamp - last >= 60:
        update_member_var("xp_last", unix_timestamp)
        xp = int(member_var("xp", 0)) + random(range(15, 26))
        level = int(member_var("level", 0))
        need = 100 * (level + 1)
        if xp >= need:
            xp = xp - need
            level = level + 1
            update_member_var("level", level)
            send_message(channel, f"🎉 {user.mention} reached level {level}!")
        update_member_var("xp", xp)
```

Each message gives 15 to 25 XP, at most once a minute. Level 1 needs 100 XP, level 2 needs 200, and so on.

## The /rank command

Create a slash command and switch to **Advanced**.

| Field | Value |
|---|---|
| Command Name | `rank` |
| Description | `Show your level` |

**Arguments:**

| Type | Name | Required |
|---|---|---|
| Member | `member` | No |

**Pre-hook:**

```python
target = member or user
xp = int(member_var("xp", 0, member=target))
level = int(member_var("level", 0, member=target))
need = 100 * (level + 1)

filled = min(10, xp * 10 // need)
bar = "█" * filled + "░" * (10 - filled)
```

**Content / Reply Message:**

```text
**{target.display_name}** is level **{level}**
`{bar}` {xp} / {need} XP
```

When nobody is picked, `member` is empty, so `member or user` falls back to the member who ran the command.

## Notes

- Saved values come back as text. `int(...)` turns them into numbers.
- `member_var` reads one member's value. Pass `member=` to read someone else's.
- Change `100 * (level + 1)` in **both** places to make levels harder or easier.

## Related

- [Levels](https://ccbot.app/docs/guides/levels) builds a full level system with role rewards.
- [Saving data](https://ccbot.app/docs/concepts/saving-data) compares member variables, databases and Mongo.
- [Storage](https://ccbot.app/docs/reference/storage) lists `member_var` and `update_member_var`.
