> 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/activities/pepper-game-night.md).

# Pepper Game Night

12 party and board games with lobbies and AI opponents at game tables in your world – board, cards, dice and party for ESX, QBCore and Qbox.

{% hint style="success" %}
✅ **Get Pepper Game Night:** <https://shop.pepperscripts.de/package/7783526>
{% endhint %}

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

## Overview

Pepper Game Night brings **12 games** to your server: board, card, dice and party games with one shared **lobby** and **AI players**. Players sit at game tables in the world or at a table from the **game box**. The character sits at the table while the game runs in an interface.

### The games

| Game                  | Type                            | Players | AI  |
| --------------------- | ------------------------------- | ------- | --- |
| Way Home              | Piece race with knock-outs      | 2–4     | yes |
| Checkers              | Board, forced captures          | 2       | yes |
| Mill                  | Board                           | 2       | yes |
| Four Up               | Drop discs                      | 2       | yes |
| Last Card             | Shedding game with action cards | 2–6     | yes |
| Thirty-One            | Collect 31, lose lives          | 2–6     | yes |
| Pepper Dice           | 5 dice, score sheet             | 1–6     | yes |
| Bluff Dice            | Bluffing with a hidden roll     | 2–6     | yes |
| Quiz Night            | Trivia, everyone at once        | 1–8     | yes |
| Word Hunt             | Guess the word                  | 2–6     | yes |
| City, Country, Pepper | Terms for a letter              | 2–8     | no  |
| Scribble Guess        | Draw and guess                  | 3–8     | no  |

## Requirements

| Dependency                                                      | Required/optional      | Used for                                                            | Link                                                                         |
| --------------------------------------------------------------- | ---------------------- | ------------------------------------------------------------------- | ---------------------------------------------------------------------------- |
| FiveM server build ≥ 7290                                       | required               | declared in `fxmanifest.lua` as `/server:7290`                      | <https://runtime.fivem.net/artifacts/fivem/build\\_server\\_windows/master/> |
| OneSync                                                         | required               | seats, nearby lobbies, table props                                  | <https://docs.fivem.net/docs/scripting-reference/onesync/>                   |
| ESX Legacy, QBCore or Qbox                                      | required (one of them) | money, groups, identifiers – `Config.Framework = 'auto'` detects it | <https://github.com/esx-framework/esx\\_core>                                |
| ox\_lib                                                         | required               | UI building blocks, callbacks                                       | <https://github.com/overextended/ox\\_lib>                                   |
| oxmysql                                                         | required               | database (tables, stats, stakes)                                    | <https://github.com/overextended/oxmysql>                                    |
| ox\_target                                                      | optional               | interacting with the table – without it key `E` is used             | <https://github.com/overextended/ox\\_target>                                |
| ox\_inventory, qb-inventory (also ps-/lj-) or the ESX inventory | optional               | only for the game box (item `gamenight_box`)                        | <https://github.com/overextended/ox\\_inventory>                             |
| esx\_addonaccount, Renewed-Banking or qb-banking                | optional               | house cut into a society account (`ServerConfig.HouseAccount`)      | –                                                                            |

## Installation

1. Download the resource from the Cfx.re Portal (Granted Assets)
2. Extract it to `resources/[pepper]/pepper_gamenight` – **do not rename it**, the item export `pepper_gamenight.…` depends on the folder name
3. Add the game box item (optional):

| Inventory                         | File                    | Where                                                                                  |
| --------------------------------- | ----------------------- | -------------------------------------------------------------------------------------- |
| ox\_inventory (ESX, QBCore, Qbox) | `install/ox_items.lua`  | entry in `ox_inventory/data/items.lua` before the last `}` – including `server.export` |
| qb-inventory / ps- / lj-inventory | `install/qb_items.lua`  | entry in `qb-core/shared/items.lua` (`QBShared.Items`)                                 |
| ESX default inventory             | `install/esx_items.sql` | import into the database                                                               |

Copy the image from `install/images/` to your inventory's image folder. 4. Database: the script creates its tables on start. Only if your DB user has no CREATE permission, import `install/pepper_gamenight.sql` first 5. Add it to `server.cfg` after the dependencies and grant the admin permission:

```cfg
ensure oxmysql
ensure ox_lib
ensure es_extended      # or qb-core / qbx_core
# ensure ox_target      # optional
# ensure ox_inventory   # optional, for the game box
ensure pepper_gamenight

add_ace group.admin pepper_gamenight.admin allow
```

6. Start the server – the console shows `Pepper Game Night v1.0.0 started (…, 0 tables)`

### First test

1. As admin stand where the table centre should be, `/spieleadmin` → **New table**, save
2. Press `E` at the table (or use ox\_target): the game hub opens
3. **Create lobby**, e.g. Four Up, add an AI in the waiting room and **Start round**
4. Finish the round – `/spielestats` then shows your stats

## Configuration

| File                | Content                                                                                                |
| ------------------- | ------------------------------------------------------------------------------------------------------ |
| `config/config.lua` | language, commands, accounts, key, games, times, lobby, AI, stakes, stats, game box, tables, interface |
| `config/server.lua` | admin ACE, webhooks, society account for the house cut – **never** sent to clients                     |
| `data/*.json`       | quiz questions and words, extendable by you. They stay on the server                                   |

Name, seats, table model, allowed games, jobs and stake limits of a table are not in the config – you set them in game with `/spieleadmin`.

### Basics

| Option               | Default                      | Meaning                                       |
| -------------------- | ---------------------------- | --------------------------------------------- |
| `Config.Locale`      | `'de'`                       | language (`de` / `en`) – folder in `locales/` |
| `Config.Framework`   | `'auto'`                     | `auto`, `esx`, `qbcore`, `qbox`, `standalone` |
| `Config.Accounts`    | `cash`, `bank`               | accounts allowed for stakes                   |
| `Config.AdminGroups` | `admin`, `superadmin`, `god` | framework groups that count as admin          |
| `Config.Keys.Open`   | `''`                         | default key for the game hub, e.g. `'F6'`     |

### Games and turn time

Every game can be turned off; `turnTime` sets the seconds per turn (10 to 300). A game missing from the list is on.

```lua
Config.Games = {
    checkers = { enabled = true, turnTime = 60 },
    shed = { enabled = false },
}
```

IDs: `race` (Way Home), `checkers`, `mill`, `four`, `shed` (Last Card), `swim`, `dice5` (Pepper Dice), `liar` (Bluff Dice), `hangman` (Word Hunt), `quiz`, `categories`, `draw`. `quiz`, `categories` and `draw` use their own phase timers.

### Lobby, round and AI

| Option                              | Default        | Meaning                                               |
| ----------------------------------- | -------------- | ----------------------------------------------------- |
| `Config.Game.StartDelay`            | `4`            | countdown before the round in seconds                 |
| `Config.Game.TimeoutsToReplace`     | `3`            | timeouts in a row until an AI takes over the seat     |
| `Config.Game.MaxDistance`           | `8.0`          | metres from the table; further away = seat left       |
| `Config.Lobby.ListDistance`         | `150.0`        | range of the lobby list in metres (`0` = all lobbies) |
| `Config.Lobby.MaxSpectators`        | `6`            | spectators per lobby                                  |
| `Config.Bots.Enabled`               | `true`         | AI players on/off                                     |
| `Config.Bots.DelayMin` / `DelayMax` | `800` / `2500` | AI thinking time per turn in milliseconds             |

### Stakes

| Option                      | Default         | Meaning                                                                |
| --------------------------- | --------------- | ---------------------------------------------------------------------- |
| `Config.Stakes.Enabled`     | `true`          | stakes on/off                                                          |
| `Config.Stakes.Min` / `Max` | `100` / `50000` | limits; can be narrowed per table in the editor                        |
| `Config.Stakes.HouseCut`    | `0`             | percent for the house (account: `ServerConfig.HouseAccount`)           |
| `Config.Stakes.Split`       | `{ 100 }`       | pot by place in percent, e.g. `{ 70, 30 }`; the rest goes to 1st place |
| `Config.Stakes.DailyLimit`  | `0`             | maximum loss per character and day (`0` = off)                         |
| `Config.Stakes.AllowBox`    | `false`         | allow stakes at the game box too                                       |

### Game box, tables, display

| Option                              | Default                    | Meaning                                                                                  |
| ----------------------------------- | -------------------------- | ---------------------------------------------------------------------------------------- |
| `Config.Box.Enabled` / `Item`       | `true` / `'gamenight_box'` | game box on/off and item name                                                            |
| `Config.Box.Seats`                  | `4`                        | seats at the box table                                                                   |
| `Config.Box.IdleMinutes`            | `5`                        | without a lobby the table is packed away after this time                                 |
| `Config.Box.NoGoZones`              | empty                      | restricted zones, e.g. `{ coords = { x = 440.0, y = -982.0, z = 30.0 }, radius = 60.0 }` |
| `Config.Table.Models`               | 4 models                   | table models with `model` and `chair` for the editor                                     |
| `Config.Table.SeatRadius` / `SeatZ` | `1.35` / `0.5`             | seat ↔ table centre distance, seat height                                                |
| `Config.Table.ChairHeadingOffset`   | `180.0`                    | if chairs face the wrong way: `0.0`                                                      |
| `Config.Interact.Mode` / `Key`      | `'auto'` / `38`            | `auto` (ox\_target, otherwise key), `target`, `key`; 38 = `E`                            |
| `Config.Text.Blocklist`             | empty                      | blocked word parts for free text, lower case                                             |

### Webhooks

In `config/server.lua` (`''` = off): `admin` (table created, changed, deleted), `rounds` (every ranked round), `money` (only rounds with stakes). Webhooks contain names only, never player identifiers.

## Placing tables

Stand where the table centre should be. Your facing direction becomes seat 1. `/spieleadmin` → **New table**, choose name and seats, save. If suitable furniture already exists, turn off **Spawn table** and **Spawn chairs**. Per table you can limit the games and set stakes with a minimum and maximum.

Under **Jobs only** enter job names separated by commas – empty means: for everyone.

## How to play

1. Press **E** at the table or use ox\_target. The hub shows lobbies nearby.
2. **Create lobby**: pick a game, optionally a private lobby with a PIN.
3. In the **waiting room** set seats, rules and stake, add AI or invite players.
4. **Start round**. After the result, continue with "Play again" or "Other game".

**Hide** closes the interface while the character stays seated. Return via the key at the table or `/spiele`. Invites are accepted in the hub (`/spiele`).

## Playing for stakes

The creator picks **For money** and the amount in the waiting room. Rules:

* At least 2 humans, no AI. Nobody can win money against the AI.
* Money is taken right before the start. If someone can't pay, the round doesn't start and everyone keeps their money.
* Whoever leaves mid-round loses their stake. The replacement AI wins nothing, its share goes to the next human.
* If the round is aborted (error, admin, restart, last human leaves), all stakes are returned.
* Offline players receive their money the next time their character loads.

Stakes are off at the game box by default (`Config.Stakes.AllowBox`).

## Your own questions and words

`data/quiz.<language>.json`: entries with `id`, `cat` (`geo`, `hist`, `sci`, `cult`, `sport`, `life`), `q` and `a`. **The first answer is the right one**, the game shuffles them. `data/words.<language>.json`: `hangman` (A–Z only), `draw`, `categories`.

## Commands and permissions

### Commands

| Command        | Who      | What                                              |
| -------------- | -------- | ------------------------------------------------- |
| `/spiele`      | everyone | open the game hub or return to the game           |
| `/spielestats` | everyone | stats and leaderboard                             |
| `/spieleraus`  | everyone | emergency: leave the lobby if the interface hangs |
| `/spieleadmin` | admins   | manage tables, open lobbies and placed game boxes |
| `/spieledebug` | everyone | diagnostics in the F8 console                     |

The names of the first four are in `Config.Commands` – `''` turns a command off.

### Permissions

There is exactly one permission: admin = ACE `pepper_gamenight.admin` or a group from `Config.AdminGroups` (`admin`, `superadmin`, `god`). The server checks it again on every admin call.

### Keys

| Where        | Key        | Action                                                                   |
| ------------ | ---------- | ------------------------------------------------------------------------ |
| At the table | `E`        | open the hub (without ox\_target) – change with `Config.Interact.Key`    |
| Anywhere     | no default | `Config.Keys.Open` sets a key, players change it in the GTA key bindings |
| Interface    | `ESC`      | close a dialog, then the open view                                       |

## Exports and events

### Exports (server, read-only)

```lua
exports.pepper_gamenight:isPlaying(src)   -- is the player in a lobby or round?
exports.pepper_gamenight:getTables()      -- list of tables (empty while the script is starting)
```

### Server event `pepper_gamenight:roundFinished`

Fired on the server after every finished round – e.g. for your own XP or achievement scripts. Clients can neither see nor trigger it.

```lua
AddEventHandler('pepper_gamenight:roundFinished', function(data)
    if not data.ranked then return end -- only rounds with at least 2 humans
    for _, p in ipairs(data.players) do
        if not p.bot and p.place == 1 then
            print(p.name .. ' won ' .. data.game)
        end
    end
end)
```

| Field                                 | Content                                                                  |
| ------------------------------------- | ------------------------------------------------------------------------ |
| `roundId`, `game`                     | round ID, game ID (e.g. `checkers`)                                      |
| `tableId`, `tableName`                | table                                                                    |
| `stake`, `account`, `pot`, `houseCut` | stake per player, account, pot, house cut                                |
| `ranked`                              | `true` with at least 2 humans                                            |
| `players`                             | list with `name`, `place`, `score`, `won`, `bot`, `source`, `identifier` |

### Framework integration

The open bridges in `bridge/` detect ESX, QBCore and Qbox automatically. The house cut goes to esx\_addonaccount, Renewed-Banking or qb-banking if `ServerConfig.HouseAccount` is set; otherwise it leaves circulation.

## Troubleshooting

| Problem                                       | Solution                                                                                       |
| --------------------------------------------- | ---------------------------------------------------------------------------------------------- |
| "You don't have permission" on `/spieleadmin` | Set the ACE from the installation or add the group to `Config.AdminGroups`                     |
| Table or chairs missing                       | Check `/spieledebug` in F8; models in `Config.Table.Models`                                    |
| Chairs face the wrong way                     | `Config.Table.ChairHeadingOffset`                                                              |
| Game box does nothing                         | Is the item added? With ox\_inventory, `server.export` from `install/ox_items.lua` is required |
| No stakes available                           | `Config.Stakes.Enabled`, "Allow stakes" on the table; `AllowBox` at the box                    |
| Game missing from the list                    | Check `Config.Games` and the game selection on the table                                       |
| Interface hangs                               | `/spieleraus`                                                                                  |

## FAQ

### Are tables included?

No. An admin places them in game with `/spieleadmin`. The script spawns table and chairs, or you use existing furniture.

### Can I play alone?

Yes, with AI players in 10 of the 12 games. Pepper Dice and Quiz Night can also be started by a single player. City, Country, Pepper and Scribble Guess need humans.

### Can players farm money against the AI?

No. Stakes need at least 2 humans and no AI. If a player leaves a round with stakes, the replacement AI wins nothing.

### What happens to stakes after a crash or restart?

Stakes are stored in the database before the start. After an abort, crash or restart they are refunded; offline players get the money the next time their character loads.

### Can players read hidden cards or quiz answers?

Dice, cards, moves and money are decided by the server. Hidden cards and quiz answers never reach a client early, and the quiz files in `data/` stay on the server.

### `/spieleadmin` says "You don't have permission".

Add `add_ace group.admin pepper_gamenight.admin allow` to your `server.cfg` or put your group into `Config.AdminGroups`.

### The game box does nothing.

The `gamenight_box` item must be registered in your inventory – with ox\_inventory including the `server.export` from `install/ox_items.lua`. `Config.Box.Enabled` must be `true`; inside restricted zones (`Config.Box.NoGoZones`) no box can be placed.

### Can I use existing furniture or an MLO?

Yes. Stand in the middle of the table when creating it and turn off **Spawn table** and **Spawn chairs**. If chairs face the wrong way, use `Config.Table.ChairHeadingOffset`.

### Can I restrict a table to certain jobs?

Yes. Enter the job names under **Jobs only** in `/spieleadmin`, separated by commas. Empty means: for everyone.

### Can I change the turn time?

Yes, per game with `turnTime` in `Config.Games` (10 to 300 seconds). Quiz Night, City, Country, Pepper and Scribble Guess use their own phase timers.

### Can I set a key for the hub?

Yes. `Config.Keys.Open` sets a default, e.g. `'F6'`. With `''` every player sets their own key in the GTA key bindings.

### Can I give XP for wins?

Yes, with the server event `pepper_gamenight:roundFinished` (see "Exports and events"). `data.ranked` is only `true` for rounds with at least 2 humans.

### Can I add my own quiz questions or translate it?

Questions and words are in `data/quiz.<language>.json` and `data/words.<language>.json` – in the quiz the first answer is the right one. For a new language copy `locales/en/`, translate it, add matching files to `data/` and set `Config.Locale`.

### How do I install an update?

Download the new version from the Cfx.re portal (<https://portal.cfx.re/assets/granted-assets>) and replace the folder – back up `config/`, `data/` and changed `locales/` first. Tables and stats live in the database and are kept.

## Support

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

## Changelog

Current version: **1.0.0** (2026-11-01). All changes are listed on the updates page and in `CHANGELOG.md` inside the resource.
