Documentation

Pepper Poker

Texas Hold'em at freely placeable tables – in-game table editor, side pots, spectators, private games with a PIN, rake, stats and a leaderboard for ESX, QBCore and Qbox.

Overview

Pepper Poker brings no-limit Texas Hold'em to your server: players sit down at a real table, buy in and play against each other – with blinds, side pots, all-ins and spectators. An admin places the tables in game with /pokeradmin, no coordinates in a config file. The server shuffles, deals and calculates everything; other players' cards never leave the server before the showdown. Every stack is also stored in the database.

Play money only. Do not connect Pepper Poker to real money or to currencies that can be bought with real money – Rockstar's and Cfx.re's rules forbid real-money gambling.

Features

  • No-limit Texas Hold'em for 2–8 players per table, up to 40 tables per server
  • In-game table editor (/pokeradmin): create, move, edit, enable/disable, delete, remove players from a table
  • Per-table settings: name, seats, small/big blind, minimum and maximum buy-in, account, rake, PIN, spawn table and chairs
  • 4 accounts: cash, bank, dirty money or chips as an item (poker_chips)
  • Complete rules: blinds, minimum raise, all-in, side pots, split pots, heads-up order, automatic runout when players are all-in
  • The server decides everything: shuffling, dealing, bets, pots, money and permissions
  • Turn timer: 25 s to act, then an automatic check or fold; after 2 timeouts in a row the player sits out
  • Rebuy, sit out, stand up right at the table
  • Spectating at every table (up to 12 spectators), private tables with a PIN (4–8 digits)
  • Rake with a percentage, a cap and "no flop, no drop" – optionally paid to a company account
  • Money safety: on disconnect, character switch, restart or crash the stack is paid out, or paid on the next login
  • Stats & leaderboard (/pokerstats), 6 quick reactions, action log, hand strength hint
  • Discord webhooks, hand log in the database, 2 server exports
  • German & English, open config, locales and bridges

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, spectators, 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, saved stacks, stats) 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 "chips" account (item poker_chips) https://github.com/overextended/ox_inventory
esx_addonaccount, Renewed-Banking or qb-banking optional rake into a society account (ServerConfig.RakeAccount) –

Installation

  1. Download the resource from the Cfx.re Portal (Granted Assets)
  2. Extract it to resources/[pepper]/pepper_poker – do not rename
  3. Database: tables are created automatically on first start. Without CREATE permission, import install/pepper_poker.sql first
  4. Check config/config.lua (language, accounts, rake, game flow) and config/server.lua for webhooks and the rake account
  5. Add it to server.cfg after oxmysql, ox_lib and your framework, and grant the admin permission:
ensure oxmysql
ensure ox_lib
ensure es_extended      # or qb-core / qbx_core
# ensure ox_target      # optional
# ensure ox_inventory   # optional, only for chips as an item
ensure pepper_poker

add_ace group.admin pepper_poker.admin allow
  1. Start the server – the console shows Pepper Poker 1.1.0 started (framework: …, tables: 0)
  2. In game, stand where the centre of the table should be (face the side where the players should sit), /pokeradmin → New table here

No tables are pre-installed. If a table or chairs already stand at that spot (MLO, casino), turn off Spawn table or Spawn chairs in the editor.

Chips item (optional)

Only needed if a table uses the "chips" account. 1 item = Config.Chips.Value play money.

Inventory File Where
ox_inventory (ESX, QBCore, Qbox) install/ox_items.lua entry into ox_inventory/data/items.lua before the last }
qb-inventory / ps- / lj-inventory install/qb_items.lua entry into qb-core/shared/items.lua (QBShared.Items)
Default ESX inventory install/esx_items.sql import into the database

Item image: copy install/images/poker_chips.png into your inventory's image folder (ox_inventory: web/images/, qb-inventory: html/images/).

If seats or chairs do not fit

Everything is in Config.Table (applies to every table): SeatZ (the character's seat height), ChairZ and TableZ (height correction of the models), SeatRadius (distance seat ↔ table centre), ChairHeadingOffset (180.0 or 0.0 if chairs face the wrong way), Models / ChairModels (the first existing model is used).

First test

  1. As admin stand at a free spot and choose /pokeradmin → New table here (2 seats, cash account)
  2. Open the table via ox_target or [E], click a seat and pick a buy-in – the amount is deducted
  3. No second player around: set Config.Bots.Enabled = true and add a bot with /pokerbot 1
  4. Play a hand, then Stand up – your stack is paid out at once; /pokerbot 0 removes the bots

Configuration

File Contents
config/config.lua language, framework, commands, admin groups, accounts, chips, game flow, rake, limits, table models, interaction, label, blips, reactions, stats, interface
config/server.lua admin ACE, webhooks, rake account, hand log (never sent to clients)

Key values:

Option Default Meaning
Config.Locale 'de' language (de / en)
Config.Framework 'auto' auto, esx, qbcore, qbox, standalone
Config.Accounts cash, bank, black_money, chips accounts selectable in the editor
Config.DirtyMoney ESX black_money, QB/Qbox cash what black_money maps to per framework
Config.Chips poker_chips, value 1 chips item and value per item
Config.Game.TurnTime 25 seconds to act per turn
Config.Game.StartDelay 6 seconds until the next hand
Config.Game.TimeoutsToSitOut 2 timeouts in a row → the player sits out
Config.Game.SitOutKick 180 seconds of sitting out until the seat is freed (0 = never)
Config.Game.BrokeKick 45 seconds without chips until the seat is freed
Config.Game.MaxSpectators 12 spectators per table
Config.Rake.Percent 5 rake in percent (0 = off), can be overridden per table
Config.Rake.Cap 5000 at most this much per pot (0 = no cap)
Config.Rake.NoFlopNoDrop true no rake if the hand ends before the flop
Config.Limits.MaxSeats / MaxTables 8 / 40 seats per table, tables per server
Config.Limits.MinBuyinBB / MaxBuyinBB 10 / 500 buy-in range in big blinds
Config.Interact.Mode 'auto' auto (ox_target, otherwise a key), target, key
Config.UI.FourColorDeck false four-colour deck
Config.Bots.Enabled false test bots (/pokerbot, "Add bot" in table management)
ServerConfig.RakeAccount nil company account for the rake – nil = money leaves circulation
ServerConfig.BigPot 50000 pots of this size or more trigger a webhook message
ServerConfig.HandLogDays 14 hand log retention in days (0 = never store)

Rake account: ESX uses the shared account of esx_addonaccount (e.g. 'society_casino'), QBCore/Qbox Renewed-Banking, otherwise qb-banking. If none of these resources is running, the amount is dropped.

Gameplay

  1. Open the table: at the table via ox_target or [E] – you start as a spectator
  2. Take a seat: click a free seat (within 6 m of the table centre), pick your buy-in – the amount is charged right away
  3. Play: you are dealt in from the next hand. A hand starts as soon as 2 players with chips are seated
  4. Actions: fold, check/call, bet/raise with a slider, an input field and quick buttons ½ Pot · Pot · All-in
  5. Time is up: automatic check, otherwise fold; after 2 timeouts in a row you sit out
  6. Rebuy: up to the maximum buy-in, added before the next hand
  7. Stand up: the stack is paid out immediately; in a running hand your cards are folded

Keys on the table screen: F fold, C check/call, R raise field, Enter confirm raise, ESC close.

Private tables ask for a PIN (4–8 digits) – after 5 wrong attempts the input is locked for 60 seconds.

Money safety

Situation What happens
Disconnect, character switch cards are folded, the stack is paid out on the next login
Resource restart hands are aborted, bets are returned, stacks are paid out
Server crash stored stacks become pending payouts on the next start
Table edited, moved or deleted the hand is aborted, bets are returned, everyone is paid out

Webhooks

In config/server.lua ('' = off):

Key Contents
bigPots pots of ServerConfig.BigPot or more: table, pot, winners with their hand, blinds, rake
admin table created, changed or deleted

Commands and permissions

Commands

Command Who What
/pokeradmin admin table management: create, move, edit, delete, remove players, bots
/pokerstats everyone your stats + leaderboard
/pokerleave everyone emergency: leave the table if the interface hangs
/pokerbot [count] admin, only with Config.Bots.Enabled = true seat bots at your table, /pokerbot 0 removes them
/pokerdebug everyone (output in F8) table model, seat positions and props at the nearest table – helps with custom models

Rename or disable ('') them in Config.Commands. Keys in the table view: F fold, C check/call, R raise field, Enter confirm raise, ESC close.

Permissions

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

Exports and framework integration

Exports (server)

-- server, read-only
exports.pepper_poker:isPlaying(src)   -- true while the player is seated at a poker table
exports.pepper_poker:getTables()      -- list of all tables

Framework integration

bridge/server/{esx,qbcore,qbox,standalone}.lua provide money, groups and identifiers, bridge/server/inventory.lua the chips item (ox_inventory, qb-/ps-/lj-inventory, ESX). All bridges are open.

Troubleshooting

Problem Solution
No table anywhere No tables are pre-installed – /pokeradmin → New table here; is the table Active?
"You don't have permission to do that." add_ace group.admin pepper_poker.admin allow or a group from Config.AdminGroups, then log in again
"Pepper Poker is still starting" Database not reachable – start oxmysql before pepper_poker, check the console
No table/chair model Turn on Spawn table / Spawn chairs; enter an existing model in Config.Table.Models
Players float, chairs face the wrong way Config.Table.SeatZ, ChairHeadingOffset, SeatRadius
"You do not have enough on you" The money must be on the table's account; for chips register the item
Interface hangs /pokerleave

FAQ

Are tables included?

No, no tables are pre-installed. An admin places them in game: walk to the spot, /pokeradmin, New table here – no coordinates in a config. The script can spawn the table and chair models itself.

What money can players use?

Each table uses exactly one account: cash, bank, dirty money or chips as an item. Config.Accounts decides which accounts the editor offers. On QBCore and Qbox dirty money points to cash by default – change that in Config.DirtyMoney.

What happens to chips on a disconnect or restart?

Nothing is lost. Every stack is saved in the database: on a disconnect the cards are folded and the stack is paid out at the next login, on a resource restart bets are returned, and after a crash saved stacks become pending payouts.

How does the rake work and where does it go?

The rake is a percentage of the pot (default 5 %), capped (default 5,000), and isn't taken before the flop ("no flop, no drop"). Without ServerConfig.RakeAccount the money leaves circulation; with an account it goes to esx_addonaccount (ESX) or Renewed-Banking / qb-banking.

Can players see other players' cards?

No. The server shuffles, deals and calculates everything; other players' cards aren't sent to other players or spectators before the showdown. Every action, amount and permission is checked on the server.

The console or chat says "Pepper Poker is still starting".

The database can't be reached: start oxmysql before pepper_poker and check the console. Without CREATE permission import install/pepper_poker.sql first.

Can I use existing casino furniture or MLOs?

Yes. Stand in the middle of the existing table when creating it and turn off Spawn table and – if chairs are there – Spawn chairs in the editor. Config.Table.SeatRadius and SeatZ adjust the seat positions.

Chairs face the wrong way or players float.

Everything is in Config.Table: ChairHeadingOffset rotates the chair models (180.0 or 0.0), SeatZ is the seat height, ChairZ and TableZ fix the model heights, SeatRadius the distance to the table centre. /pokerdebug shows in F8 which model and seat positions the nearest table uses.

ox_target or a key?

Both work. Config.Interact.Mode = 'auto' uses ox_target when it runs, otherwise key E with an on-screen hint. 'key' forces the key.

How many tables and players are possible?

2 to 8 seats per table plus up to 12 spectators. By default 40 tables per server are allowed (Config.Limits.MaxTables). A character can only sit at one table at a time.

Can I test on my own?

Yes, with bots: Config.Bots.Enabled = true, then "Add bot" in table management or /pokerbot [count]. Bots play with chips from nowhere, never show up in stats and disappear once the last real player stands up.

Are there tournaments?

No. Games are cash tables: you buy in, can rebuy and stand up at any time.

Can I change the turn time, blinds or texts?

The turn time is Config.Game.TurnTime and applies to all tables; blinds, buy-in, account, rake and PIN are set per table in the editor. All texts are open in locales/de/ and locales/en/ (core.json, game.json, ui.json), Config.Locale picks the language.

Is poker a gambling problem for my server?

Pepper Poker is meant for play money only. Don't connect it to real money or currencies that can be bought with real money – Rockstar's and Cfx.re's rules forbid that. You're responsible for the rules on your server.

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/ and changed locales/ first. Tables, stats and pending payouts live in the database and are kept.

Support

Open a ticket on Discord: https://discord.gg/6NaFJWKDYu (category "Script Support") – link your purchase with /verify first.

Permanently tested on the Pepper Scripts dev server.

Changelog

Current version: 1.1.0 (2026-10-04, test bots, table model by seat count). All changes are listed on the updates page and in CHANGELOG.md inside the resource.


Found a mistake? Report it on Discord.