# Chat System
Bookshelf includes a full chat formatting and moderation system. When enabled, it replaces vanilla chat with a customizable format that supports LuckPerms prefixes, colored names, inline features like `@mentions` and `@item`, and built-in moderation tools.
---
## Enabling the Chat System
The chat system is controlled by `managers/chat.yml`, which is generated automatically when the plugin first loads.
```yaml
enabled: true
```
Set `enabled` to `true` to activate Bookshelf's chat system. When disabled, vanilla chat is used and none of the features on this page apply.
---
## Chat Format
When a player sends a message, Bookshelf formats it as:
```
[prefix] PlayerName: message [suffix]
```
| Component | Description | Default |
|---|---|---|
| **Prefix** | Displayed before the player name. Set via LuckPerms or the API. | Empty |
| **Player Name** | The player's display name, colored with the **rank color**. | Gray |
| **Message** | The message content, colored with the **chat color**. | Gray |
| **Suffix** | Displayed after the message. Set via LuckPerms or the API. | Empty |
All components support [MiniMessage formatting](https://docs.adventure.kyori.net/minimessage.html) — including colors, bold, italic, gradients, hex colors, and custom fonts.
---
## LuckPerms Integration
Bookshelf reads permission nodes from the player's **primary LuckPerms group** to determine chat formatting. No additional configuration is needed — if LuckPerms is installed, Bookshelf detects it automatically.
### Available Meta Nodes
| Node Format | Purpose | Example |
|---|---|---|
| `prefix.<weight>.<prefix>` | Sets the chat prefix | `prefix.10.<red><bold>ADMIN` |
| `suffix.<weight>.<suffix>` | Sets the chat suffix | `suffix.10.<gray>[Staff]` |
| `chat_color.<color>` | Sets the message text color | `chat_color.#ff00ff` |
| `rank_color.<color>` | Sets the player name color | `rank_color.#ff00ff` |
| `chat_cooldown.<seconds>` | Overrides the chat cooldown for this group | `chat_cooldown.1` |
> [!important]
> If `distinguishable_operators` is set to `true` in `chat.yml`, operators will always display the **STAFF** prefix with white colors. Set it to `false` if you are using LuckPerms to define your own prefixes.
### How Nodes are Parsed
Bookshelf reads the raw permission node key from the player's primary group and extracts the value:
- For **prefix/suffix** (`prefix.<weight>.<value>`): The weight is ignored by Bookshelf — only the value after the second dot is used for chat display.
- For **colors** (`rank_color.<value>`): Everything after the first dot is used.
- For **cooldown** (`chat_cooldown.<value>`): Everything after the first dot is parsed as a number.
### Setting Up Nodes in LuckPerms
Use the LuckPerms editor or commands to add permission nodes to a group:
```
/lp group <group> permission set <node>
```
**Examples:**
```
/lp group admin permission set prefix.100.<red><bold>ADMIN <reset>
/lp group mod permission set prefix.50.<aqua>MOD <reset>
/lp group default permission set prefix.10.<gray>Member <reset>
/lp group admin permission set rank_color.#ff0000
/lp group admin permission set chat_color.#ffffff
/lp group vip permission set chat_cooldown.1
```
### Practical Examples
Here is an example of a rank fully configured with LuckPerms:
| Node | Purpose | Chat Result |
|---|---|---|
| `prefix.2.<#ff00ff>PURPLE <#ff00ff>` | Colored prefix with hex | Displays `PURPLE` in pink before the player name |
| `prefix.<font:ranks><white>ꀁ</font> <white>` | Prefix using a custom resource pack font | Displays a custom rank icon from a resource pack |
| `rank_color.#ff00ff` | Player name color | Player name appears in pink |
| `chat_color.#ffffff` | Message text color | Message text appears in white |
> [!tip] Custom Fonts
> Using `<font:ranks>` in a prefix requires a resource pack that defines the `ranks` font. The character inside (e.g., `ꀁ`) maps to a custom texture in your pack. This is how servers display rank icons in chat.
### Color Format
- **Rank color** (`rank_color`) accepts MiniMessage color names (`white`, `red`, `aqua`) or hex colors (`#ff00ff`).
- **Chat color** (`chat_color`) should use hex colors (`#ffffff`, `#ff00ff`) for best results.
- **Prefix/Suffix** values support full MiniMessage formatting — colors, bold, italic, gradients, fonts, etc.
> [!tip] Trailing Spaces
> If your prefix does not end with a space, Bookshelf automatically inserts one between the prefix and player name. To control spacing yourself, end your prefix with a space (e.g., `prefix.10.<red>ADMIN <reset>`).
---
## Chat Features
Bookshelf adds inline chat features that players can use in their messages. Each feature requires a specific permission.
### Clickable Links
| Permission | `lodestone.bookshelf.chat.links` |
|---|---|
| Trigger | Any `http://` or `https://` URL |
| Behavior | URL becomes underlined and clickable. Hovering shows "Click to open link". |
**Example:**
```
Player: Check out https://example.com
→ "https://example.com" appears underlined and clickable
```
### Player Mentions
| Permission | `lodestone.bookshelf.chat.mentions` |
|---|---|
| Trigger | `@PlayerName` (3-16 characters) |
| Behavior | Mentioned player's name turns yellow. They hear a notification sound. |
**Example:**
```
Player: Hey @Steve come here
→ "@Steve" appears in yellow, Steve hears a ding
```
### Item Display
| Permission | `lodestone.bookshelf.chat.item` |
|---|---|
| Trigger | `@item` |
| Behavior | Replaced with the held item's name in brackets, colored by rarity. Hovering shows the full item tooltip. |
**Example:**
```
Player: Look at this @item I found
→ "Look at this [Diamond Sword] I found" with hover tooltip
```
### @everyone Ping
| Permission | `lodestone.bookshelf.chat.everyone` |
|---|---|
| Trigger | `@everyone` |
| Behavior | Highlights in yellow. All online players (except the sender) hear a notification sound. |
---
## Chat Moderation
Bookshelf includes automatic moderation that runs before every message is displayed. Each check fires a `PlayerChatModerationEvent` that other plugins can cancel to override the decision.
### Warning Block
Players with an active `/warn` infraction cannot chat until they acknowledge the warning by typing **"I understand"**. This is checked first before all other moderation.
### Mute Enforcement
Players with an active `/mute` or `/tempmute` infraction cannot send messages. The player sees the mute reason and remaining duration.
### Global Chat Mute
When global chat is muted (`/muteglobalchat`), non-operator players without `lodestone.bookshelf.chat.bypass` cannot send messages.
### Banned Words
Messages are checked against the `banned_words` list in `chat.yml`. Each entry can be a plain word or a regex pattern. Staff with `lodestone.bookshelf.alerts` receive a notification with the original message on hover.
```yaml
banned_words:
- "(?i)\\bbadword\\b" # Regex pattern (case-insensitive, word boundaries)
- "exactmatch" # Exact word match
```
> [!tip] Regex Tips
> Use [regex101.com](https://regex101.com/) to test patterns. `(?i)` makes the pattern case-insensitive. `\\b` marks word boundaries to avoid matching partial words.
### Character Spam Detection
Messages containing a word with the same character repeated 5 or more times (e.g., `aaaaaaa`, `!!!!!`) are blocked. Staff with `lodestone.bookshelf.alerts` receive a notification.
### Chat Cooldown
Players must wait a set number of seconds between messages. The default cooldown is set in `chat.yml`:
```yaml
chat_cooldown: 3
```
This can be overridden per LuckPerms group using the `chat_cooldown.<seconds>` node:
```
/lp group vip permission set chat_cooldown.1
/lp group default permission set chat_cooldown.5
```
### Duplicate Message Prevention
Sending the same message twice in a row is blocked. Staff with `lodestone.bookshelf.alerts` receive a notification.
### Bypass Permission
Players with `lodestone.bookshelf.chat.bypass` skip **all** of the following checks:
- Chat cooldown
- Duplicate message detection
- Banned word filter
- Character spam detection
> [!warning]
> The bypass permission does **not** skip warn checks, mute checks, or global chat mute (unless the player is an operator).
---
## Chat Channels
Players can switch between chat channels using `/chat <channel>`. Messages sent in a channel are only visible to players with access to that channel.
### Built-in Channels
| Channel | Permission | Description |
|---|---|---|
| **ALL** | None | Default channel. Messages go to all players on the current server. |
| **NETWORK** | `lodestone.bookshelf.chat.network` | Cross-server channel. Requires Redis. Messages are sent to all connected servers. |
### Custom Channels
Define custom channels in `chat.yml`:
```yaml
channels:
- "STAFF"
- "MODERATOR"
- "VIP"
```
Each custom channel requires the permission `lodestone.bookshelf.chat.<channel_name>` (lowercase). For example, the **STAFF** channel requires `lodestone.bookshelf.chat.staff`.
Custom channel messages appear in a different format:
```
STAFF » PlayerName: message
```
When Redis is available, custom channel messages are automatically synced across all connected servers.
### Switching Channels
```
/chat → View your current channel
/chat all → Switch to ALL (public) chat
/chat staff → Switch to STAFF channel
/chat network → Switch to NETWORK channel
```
---
## Operator Distinction
If `distinguishable_operators` is enabled in `chat.yml`, players with operator status automatically receive:
- A red **STAFF** prefix
- White player name color
- White message color
```yaml
distinguishable_operators: true # Operators get STAFF prefix
distinguishable_operators: false # Use LuckPerms for all formatting (recommended)
```
> [!important]
> When using LuckPerms for rank formatting, set `distinguishable_operators` to `false`. Otherwise, operator formatting will override your LuckPerms nodes unless another plugin modifies the `PlayerChatEvent` first.
---
## Full Permissions Reference
### Chat Feature Permissions
| Permission | Description |
|---|---|
| `lodestone.bookshelf.chat.links` | Allows clickable URLs in chat |
| `lodestone.bookshelf.chat.mentions` | Allows `@PlayerName` mentions |
| `lodestone.bookshelf.chat.item` | Allows `@item` display in chat |
| `lodestone.bookshelf.chat.everyone` | Allows `@everyone` ping |
| `lodestone.bookshelf.chat.bypass` | Bypasses cooldowns, spam, banned words, and duplicate checks |
| `lodestone.bookshelf.chat.network` | Access to the NETWORK chat channel |
| `lodestone.bookshelf.chat.<channel>` | Access to a custom chat channel |
| `lodestone.bookshelf.alerts` | Receives staff alerts for moderation violations |
### LuckPerms Meta Nodes
| Node | Format | Description |
|---|---|---|
| `prefix.<weight>.<value>` | MiniMessage text | Chat prefix before player name |
| `suffix.<weight>.<value>` | MiniMessage text | Chat suffix after message |
| `rank_color.<color>` | Color name or hex (`#ff00ff`) | Player name color |
| `chat_color.<color>` | Hex color (`#ffffff`) | Message text color |
| `chat_cooldown.<seconds>` | Integer | Per-group chat cooldown override |
---
## Related Pages
- [[Bookshelf/Server Owners/Configuration]] - Full config.yml and chat.yml reference
- [[Bookshelf/Server Owners/Commands]] - Complete command reference
- [[Bookshelf/Server Owners/Overview]] - Feature overview and plugin dependencies