> For the complete documentation index, see [llms.txt](https://pepper-scripts.gitbook.io/pepper-scripts-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://pepper-scripts.gitbook.io/pepper-scripts-docs/tools-ui/pepper-rp-commands.md).

# Pepper RP-Commands

Free roleplay commands with modern speech bubbles – /me, /do, /try, /status, /whisper, /shout and more. Standalone.

{% hint style="success" %}
✅ **Get Pepper RP-Commands:** <https://shop.pepperscripts.de/package/7729481>
{% endhint %}

{% hint style="info" %}
🧪 **Tested on our dev server:** Of course we test all scripts continuously on our own dev server “Pepper Scripts”.
{% endhint %}

Free and open source: <https://github.com/PepperScripts/pepper\\_rpcommands>

## Overview

Pepper RP-Commands brings ten roleplay commands like `/me`, `/do`, `/try` and `/status` to your server. The text appears as a speech bubble above the head and, if you want, as a line in chat – but only for players in range and, optionally, only with line of sight. Dice, coin and `/try` are decided by the server, so nobody can fake a result. It runs standalone and takes the character name from ESX, QBCore or Qbox when one is running.

### Features

* 10 commands: `/me`, `/do`, `/try`, `/roll`, `/dice`, `/coin`, `/status`, `/looc`, `/whisper`, `/shout`
* Modern speech bubbles above the head with an icon per command – or `minimal` (text with shadow) or `classic` (GTA font)
* `/status` keeps a text above your head (e.g. "injured") until you remove it or the time runs out
* Several texts stack above a player, long texts wrap
* Character name from ESX, QBCore or Qbox in the chat line – detected automatically
* `/try`, `/roll`, `/dice` and `/coin` are decided on the server, so nobody can fake a result
* Only players in range receive the text (same routing bucket); optional line-of-sight check, so nothing shows through walls
* Discord webhook log, word filter, admin commands to clear texts and mute players
* Exports for other resources
* English, German, French, Spanish and Dutch
* No dependencies; the draw loop only runs while a text or status is active

## Requirements

| Dependency                                       | Required/optional | What for                                                                                                                    | Link                                                             |
| ------------------------------------------------ | ----------------- | --------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------- |
| FiveM server (`fx_version 'cerulean'`, Lua 5.4)  | required          | Runs the resource                                                                                                           | <https://docs.fivem.net/docs/server-manual/setting-up-a-server/> |
| ESX Legacy, QBCore or Qbox                       | optional          | Character name in the chat line and admin groups; without a framework FiveM name + ACE                                      | –                                                                |
| Chat resource (default chat or e.g. Pepper Chat) | optional          | Chat line, hints and command suggestions (`chat:addMessage`, `chat:addSuggestion`)                                          | **Pepper Chat**                                                  |
| OneSync                                          | optional          | With OneSync the server sends texts only to players in range; without it to everyone, the client checks the distance itself | –                                                                |
| Database                                         | not needed        | No database, no oxmysql – status and mutes live in the server's memory                                                      | –                                                                |

## Installation

1. Put the `pepper_rpcommands` folder into your `resources` folder. **Do not rename the folder** – the exports are called `exports.pepper_rpcommands:…`.
2. Add it to your `server.cfg`, after your framework and your chat:

   ```
   ensure es_extended      # or qb-core / qbx_core – optional
   ensure chat             # or pepper_chat
   ensure pepper_rpcommands
   ```
3. Remove other resources that register `/me` or `/do`, otherwise both will answer.
4. Set `Config.Locale` in `config.lua` and restart the server.
5. Optional – admin rights via ACE:

   ```
   add_ace group.admin pepperrp.admin allow
   ```

**Updating from 1.x:** replace the whole folder. If you changed `config.lua`, copy your values into the new file – the new commands only appear with the new config. `config_server.lua` is new and belongs to it.

### First test

1. In game type `/me opens the trunk` – a speech bubble appears above your head and a line in chat.
2. `/try pick the lock` – the server decides "succeeds" or "fails".
3. `/dice 2d6` – two dice with single results and the sum.
4. `/status injured` sets a lasting text, `/status` without text removes it.
5. With a second player: `/whisper over here` is only visible within 3 m.

## Configuration

| File                | Controls                                                                                                                   |
| ------------------- | -------------------------------------------------------------------------------------------------------------------------- |
| `config.lua`        | Language, style, size, range, duration, stack, line of sight, length, cooldown, chat, name, all commands (sent to players) |
| `config_server.lua` | Webhook, console log, word filter, admin groups and commands (server only)                                                 |
| `locales/*.json`    | Texts above the head, chat lines and hints per language                                                                    |
| `html/style.css`    | Look of the speech bubbles (styles `modern` and `minimal`)                                                                 |

### General

| Option                      | Default       | Description                                                                                             |
| --------------------------- | ------------- | ------------------------------------------------------------------------------------------------------- |
| `Config.Locale`             | `'en'`        | `en`, `de`, `fr`, `es` or `nl`                                                                          |
| `Config.Style`              | `'modern'`    | `modern` (speech bubble with icon), `minimal` (text with shadow) or `classic` (GTA font like version 1) |
| `Config.Scale`              | `1.0`         | Size of the bubbles                                                                                     |
| `Config.Distance`           | `15.0`        | Default range in metres                                                                                 |
| `Config.Duration`           | `7000`        | How long a text stays above the head (milliseconds)                                                     |
| `Config.MaxStack`           | `3`           | Texts stacked above one player; older ones disappear                                                    |
| `Config.RequireLineOfSight` | `true`        | Only show texts with line of sight (not through walls)                                                  |
| `Config.MaxLength`          | `150`         | Max input length (up to 250)                                                                            |
| `Config.Cooldown`           | `1500`        | Wait between two commands per player (ms)                                                               |
| `Config.Chat`               | `true`        | Also a chat line for everyone in range                                                                  |
| `Config.NameMode`           | `'character'` | `character` (name from ESX/QBCore/Qbox, else FiveM name) or `fivem`                                     |
| `Config.GetName`            | `nil`         | Own name function (runs on the server, overrides `NameMode`)                                            |

### Commands

```lua
Config.Commands = {
    me      = { enabled = true, name = 'me',      color = { 255, 196, 107 }, icon = 'me' },
    try     = { enabled = true, name = 'try',     color = { 196, 160, 255 }, icon = 'try', chance = 50 },
    status  = { enabled = true, name = 'status',  color = { 200, 205, 215 }, icon = 'status', maxLength = 60, maxMinutes = 60 },
    whisper = { enabled = true, name = 'whisper', color = { 190, 215, 230 }, icon = 'whisper', distance = 3.0 },
    -- …
}
```

| Field                                 | Description                                                                             |
| ------------------------------------- | --------------------------------------------------------------------------------------- |
| `enabled`                             | `false` turns the command off                                                           |
| `name`                                | Command name without `/`                                                                |
| `color`                               | Colour as `{ red, green, blue }` (0–255)                                                |
| `icon`                                | `me`, `do`, `try`, `dice`, `coin`, `status`, `ooc`, `whisper`, `shout`                  |
| `distance`                            | Own range (otherwise `Config.Distance`); `whisper` 3 m, `shout` 35 m                    |
| `overhead` / `chat`                   | `false` hides the speech bubble or the chat line for this command                       |
| `chance` (`try`)                      | Success chance in percent, default `50`                                                 |
| `default` / `max` (`roll`)            | Sides without input `6`, at most `1000`                                                 |
| `maxDice` / `maxSides` (`dice`)       | At most `10` dice with `100` sides each                                                 |
| `maxLength` / `maxMinutes` (`status`) | Status text up to `60` characters, expires after `60` minutes (`0` = until logging out) |

### Server settings (`config_server.lua`)

| Option                                  | Default                                   | Description                                                                           |
| --------------------------------------- | ----------------------------------------- | ------------------------------------------------------------------------------------- |
| `ServerConfig.Webhook`                  | `''`                                      | Discord webhook for the log of all RP commands (name, server ID, licence), `''` = off |
| `ServerConfig.ConsoleLog`               | `false`                                   | Also print every line to the server console                                           |
| `ServerConfig.Filter.mode`              | `'censor'`                                | `censor` (asterisks), `block` (reject the command) or `off`                           |
| `ServerConfig.Filter.words`             | empty                                     | Filtered words (case-insensitive)                                                     |
| `ServerConfig.Admin.groups`             | `{ 'god', 'superadmin', 'admin', 'mod' }` | Framework groups allowed to use admin commands                                        |
| `ServerConfig.Admin.commands`           | `rpclear`, `rpmute`, `rpunmute`           | Names of the admin commands                                                           |
| `ServerConfig.Admin.defaultMuteMinutes` | `30`                                      | Mute duration without input (1 to 10080 minutes)                                      |

## Commands and permissions

| Command                | Who      | Example → above the head                                         |
| ---------------------- | -------- | ---------------------------------------------------------------- |
| `/me [text]`           | everyone | `/me opens the trunk` → opens the trunk                          |
| `/do [text]`           | everyone | `/do The door is locked.`                                        |
| `/try [text]`          | everyone | `/try pick the lock` → tries to pick the lock – succeeds / fails |
| `/roll [sides]`        | everyone | `/roll 20` → rolls 14 (1–20)                                     |
| `/dice [dice]`         | everyone | `/dice 2d6` → 3 + 5 = 8 (also `d20` or `3` = 3d6)                |
| `/coin`                | everyone | flips a coin: heads                                              |
| `/status [text]`       | everyone | lasting text; `/status` alone removes it                         |
| `/looc [text]`         | everyone | (( brb )) – local OOC chat                                       |
| `/whisper [text]`      | everyone | only visible within 3 m                                          |
| `/shout [text]`        | everyone | visible within 35 m                                              |
| `/rpclear [ID]`        | admin    | Remove texts and status of one player – without ID of everyone   |
| `/rpmute ID [minutes]` | admin    | Block RP commands for a player (stays after reconnecting)        |
| `/rpunmute ID`         | admin    | Unblock                                                          |

**Admin** is whoever has the ACE permission `pepperrp.admin`, a group from `ServerConfig.Admin.groups` (ESX group, QBCore permission or ACE group on Qbox) or the server console. The RP commands themselves do not work from the console. There are no keys.

## Exports and events

```lua
-- Server
exports.pepper_rpcommands:ShowText(source, 'opens the safe', { color = { 255, 196, 107 }, icon = 'me', duration = 5000, distance = 10.0 })
exports.pepper_rpcommands:SetStatus(source, 'handcuffed', 10) -- minutes optional
exports.pepper_rpcommands:ClearStatus(source)
exports.pepper_rpcommands:GetStatus(source)  -- text or nil
exports.pepper_rpcommands:IsMuted(source)    -- true / false

-- Client
exports.pepper_rpcommands:ShowLocalText(serverId, 'only you see this', { icon = 'do' })
exports.pepper_rpcommands:SetHidden(true) -- hide everything, e.g. for a cinematic mode
```

| Side   | Export                                                                           | Effect                                                                             |
| ------ | -------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- |
| Server | `ShowText(source, text, options)`                                                | Speech bubble above a player for everyone in range; `options.chat` = own chat line |
| Server | `SetStatus(source, text, minutes)` / `ClearStatus(source)` / `GetStatus(source)` | Set, remove, read a lasting text                                                   |
| Server | `IsMuted(source)`                                                                | Is the player blocked from RP commands?                                            |
| Client | `ShowLocalText(serverId, text, options)`                                         | Speech bubble only for this player                                                 |
| Client | `SetHidden(bool)`                                                                | Hide/show all texts                                                                |

Icons: `me`, `do`, `try`, `dice`, `coin`, `status`, `ooc`, `whisper`, `shout`, `chat`.

## FAQ

### `/me` answers twice – what now?

Another resource registers `/me` or `/do` as well (often an old RP script or a framework module). Remove it or rename the commands here via `name` in `Config.Commands`.

### I see the speech bubble but no chat line?

The chat line goes through `chat:addMessage` – a chat resource must be running (default chat or Pepper Chat). Also check `Config.Chat = true` and that the command does not have `chat = false`.

### Why don't I see other players' texts?

You must be in range (15 m by default, `whisper` 3 m) and in the same routing bucket. With `Config.RequireLineOfSight = true` texts behind walls are hidden – set it to `false` for testing.

### Do I need a database?

No. Status and mutes live in the server's memory. A mute is tied to the licence and lasts through a reconnect, but ends with a restart of the resource or the server.

### How long does a `/status` stay?

Until the player types `/status` without text, logs out or `maxMinutes` runs out – 60 minutes by default. With `maxMinutes = 0` it stays until logging out.

### How do I show the character name instead of the FiveM name?

`Config.NameMode = 'character'` (default) takes the name from Qbox, QBCore or ESX. For other frameworks set `Config.GetName = function(source) … end` – the function runs on the server.

### How do I change colours and look?

The colour per command is in `Config.Commands` (`color`), the style in `Config.Style`, the size in `Config.Scale`. Finer details of the bubble are in `html/style.css`.

### How do I change the texts?

In `locales/<language>.json`, e.g. the lines above the head (`overhead_…`) and in chat (`chat_…`).

### Can a player fake the result of `/try` or `/dice`?

No. The server draws the random numbers, the client only shows the result. You set the success chance of `/try` with `chance`.

### How do I use the speech bubbles from my own script?

On the server `exports.pepper_rpcommands:ShowText(source, 'Text', { icon = 'me' })`, for a lasting text `SetStatus(source, 'handcuffed', 10)`. Details under "Exports and events".

### Are colour codes or HTML shown in the text?

No. The server removes control characters, GTA codes (`~r~`), chat colour codes (`^1`) and angle brackets before the text is sent out.

### How do I log all RP commands to Discord?

Put the webhook URL into `config_server.lua` at `ServerConfig.Webhook`. The file stays on the server.

### How do I update Pepper RP-Commands?

Replace the folder, back up `config.lua` and `config_server.lua` first and copy your values into the new files. Changes are listed in the `CHANGELOG.md` in the resource folder.

## Support

Open a ticket in our [Discord](https://discord.gg/6NaFJWKDYu) (category “Script Support”) and link your purchase with `/verify` first.

## Changelog

Current version **2.0.0**: speech bubbles in three styles, `/status`, `/looc`, `/whisper`, `/shout`, `/coin`, `/dice`, character name, webhook, admin commands, word filter, exports and three new languages. All changes are listed in the `CHANGELOG.md` in the resource folder.
