> ## Documentation Index
> Fetch the complete documentation index at: https://docs.nexdev.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Whitelist & priority

> NEX Queue uses Discord roles for three independent decisions:

NEX Queue uses Discord roles for **three** independent decisions:

1. **Can this player connect at all?** → `Config.Whitelist`
2. **Do they skip the queue entirely?** → `Config.Permissions.BypassRoles`
3. **How high up the queue are they?** → `Config.Permissions.PriorityLevels`

Plus a fourth, purely cosmetic one — **what tier do they see on their card?** → `Config.Tiers`.

These are independent on purpose. A "supporter" role might get priority but no bypass. A "developer" role might bypass but not even be a tier. Mix and match.

***

## Bypass (staff & owners)

Anyone holding *any* of `Config.Permissions.BypassRoles` skips the queue entirely **and** is exempt from the whitelist check.

```lua theme={null}
Config.Permissions = {
    BypassRoles = {
        "ROLE_ID_OWNER",
        "ROLE_ID_ADMIN",
        "ROLE_ID_DEV",
    },
    -- ...
}
```

This is what `Config.Server.ReservedSlots` is for — if you reserve, say, `2` slots, the server effectively caps regular players at `sv_maxclients - 2`, leaving those two slots for staff with bypass.

***

## Priority (queue ordering)

```lua theme={null}
Config.Permissions.PriorityLevels = {
    ["ROLE_ID_DIAMOND"]  = 8500,
    ["ROLE_ID_PLATINUM"] = 5000,
    ["ROLE_ID_GOLD"]     = 2500,
    ["ROLE_ID_SILVER"]   = 1500,
    ["ROLE_ID_BRONZE"]   = 1000,
}
```

Rules:

* The map is `roleId → points`.
* A player's **effective priority** is the **sum** of points across every role they hold.
* Higher points = served first.
* A player with *no* matching roles has a priority of `0` and is queued in arrival order behind every prioritized player.
* You can use any positive integer for points. The numbers above are just one common scheme.

### Example

Roles configured:

* Diamond — 8500
* Twitch Sub — 500

A player who holds **both** Diamond *and* Twitch Sub has effective priority **9000**, which puts them ahead of a Diamond-only player.

If you don't want stacking, just don't grant overlapping roles, or give the "lower" role 0 points.

***

## Whitelist (gate the whole server)

When `Config.Whitelist.Enabled = true`, players are kicked at connect **unless** they hold one of `Config.Whitelist.Roles`.

```lua theme={null}
Config.Whitelist = {
    Enabled = true,
    Roles = {
        "ROLE_ID_WHITELISTED",
    },
    KickMessage = "This server is whitelist only. Join our Discord to apply for access."
}
```

* Whitelisted players **still go through the queue** — the whitelist is only an entry gate, not a bypass.
* Bypass roles **are** exempt from the whitelist — staff can always get in.
* Any **one** role is enough — if a player holds at least one role in the list, they pass.
* `KickMessage` is shown in the connect deferral that kicks them. Keep it friendly and link to your Discord.

### Common whitelist patterns

| Pattern                          | Setup                                                                              |
| -------------------------------- | ---------------------------------------------------------------------------------- |
| Closed beta / private server     | `Enabled = true`, `Roles = { "BETA_TESTER_ROLE" }`                                 |
| Application-based whitelist      | `Enabled = true`, `Roles = { "WHITELISTED_ROLE" }` — granted manually in Discord   |
| Paid early-access window         | `Enabled = true`, `Roles = { "SUPPORTER_ROLE" }`, then `Enabled = false` at launch |
| Public server with priority only | `Enabled = false` — just leave it off                                              |

***

## Tiers (display only)

`Config.Tiers` controls the **label** under the player's name on the card. It does **not** affect queue ordering.

```lua theme={null}
Config.Tiers = {
    { name = "Diamond Tier",  role = "ROLE_ID_DIAMOND"  },
    { name = "Platinum Tier", role = "ROLE_ID_PLATINUM" },
    { name = "Gold Tier",     role = "ROLE_ID_GOLD"     },
    { name = "Silver Tier",   role = "ROLE_ID_SILVER"   },
    { name = "Bronze Tier",   role = "ROLE_ID_BRONZE"   },
}

Config.DefaultTier = "Standard"
```

* **Order matters** — the **first** entry whose role the player holds is the one displayed. Put the highest tier on top.
* `Config.DefaultTier` is shown when the player has *none* of the listed roles.
* The label is free text — rename them to whatever fits your branding (`"VIP"`, `"Patron"`, etc.).

### Keeping tier ↔ priority in sync

It's common for the same role to drive both tier display *and* priority points. There's no requirement to mirror them, but if your community expects "Diamond shows Diamond and gets the biggest skip", just use the same role ID in both places:

```lua theme={null}
-- Display
Config.Tiers = {
    { name = "Diamond Tier", role = "ROLE_ID_DIAMOND" },
    -- ...
}

-- Ordering
Config.Permissions.PriorityLevels = {
    ["ROLE_ID_DIAMOND"] = 8500,
    -- ...
}
```

***

## Decision flow (what happens when a player connects)

1. **Discord check** — the bot looks up the player's Discord ID and their roles.
   * No linked Discord at all? They are queued as `Standard` with `0` priority. (Unless your whitelist is on — then they're kicked.)
2. **Whitelist gate** — if `Config.Whitelist.Enabled`, the player must hold one of `Config.Whitelist.Roles` (or a bypass role) or they're kicked with `KickMessage`.
3. **Bypass check** — if they hold any `BypassRoles`, they skip everything below and connect.
4. **Priority sum** — total their `PriorityLevels` points across all their roles.
5. **Tier label** — pick the first matching `Config.Tiers` entry (or `DefaultTier`).
6. **Queue** — they enter the queue at the position implied by their priority, see their tier on the card, and wait.
