Files
redl-fivem-rp/docs/SERVER.md
T
Claude Opus 5andClaude Opus 5 71856b15e9 The server itself: repo now mirrors the machine it runs on, plus install.sh
The repository carried two different servers side by side - the early
`justrp` prototype with its Python auth API, and a snapshot of the real
one under `server-code/`. Only the second one is a server anyone should
start from, so the prototype is gone and the real one moved to the root.

Taken from the live box, so the UI is the finished version (the tokens,
the county-records sheets and the variable fonts landed after the last
snapshot was pushed):

  resources/[rp]/   rp_db, rp_core, rp_session, rp_loading, rp_ui,
                    rp_selftest, rp_dbtest
  bin/              supervise.sh (keep-alive + console FIFO), rcon, init script
  etc/schema.sql    accounts, characters, transactions, inventory, vehicles
  assets/fonts/     the bundled subsets
  docs/SERVER.md    how it is put together, resource by resource

install.sh turns a clean Ubuntu/Debian box into this server in one
command: recommended FXServer build, MariaDB with the schema, resources,
server.cfg + a generated database password, boot entry (systemd or
init.d), then it waits for the Cfx registration. --name/--port/--db-name
let a second server live on the same machine. Tested end to end on a
spare install root: build 25770 fetched, schema applied, boot entry
written, FXServer started and stopped exactly where a wrong licence key
should stop it.

No secrets travel with it: the licence key and the database password live
in data/secrets.cfg on the machine, and .gitignore now names it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-12 23:23:33 +00:00

5.2 KiB

Los Santos RP — server notes

Everything here was written for this server. No ESX, no QBCore, no downloaded resources: cfx-server-data is not used at all, and the bundled chat and monitor resources are not started.

Layout

/opt/fivem/server        FXServer artefacts (build 25770, the recommended one)
/opt/fivem/data          server-data root; run FXServer with this as cwd
  server.cfg             main config
  secrets.cfg            licence key + DB credentials, mode 600
  resources/[rp]/        our resources
/opt/fivem/bin           supervise.sh (keep-alive), rcon (console pipe)
/opt/fivem/logs          server.log, rotated at 200MB
/opt/fivem/etc/schema.sql  the database schema

Resources

resource what it is
rp_db MariaDB client speaking the MySQL wire protocol directly over a TCP socket — handshake, mysql_native_password, text result sets, connection pool, transactions. No npm packages. Lua front end in lib/db.lua.
rp_core Config, shared validation, appearance model, scrypt password hashing, the player registry, and the client/server request bridge.
rp_session Connection gate (bans, capacity), accounts, characters, spawn. Every decision is made here; the client can only ask.
rp_loading Loading screen: procedural night-city flyover on canvas, progress bound to the game's real load events, ambience synthesised with the Web Audio API.
rp_ui Sign in / register, character creation with a live ped preview, spawn picker. Scripted cameras live in client/camera.lua.
rp_selftest Checks the account/character data path on every boot and proves it survived the restart.
rp_dbtest Driver test suite. Not started by default; ensure rp_dbtest to run it.

The look

The interface is the paperwork side of a life in Los Santos: every screen is a sheet from the city's Office of Vital Records, lying on a dark desk while the game runs on behind it. Paper is the only surface we draw; the game is the room the desk is in. That is why the NUI body stays transparent and the sheets are opaque - an opaque sheet stays legible over a bright daylight city, where a dark glass panel would not.

html/tokens.css is shared verbatim by rp_ui and rp_loading and holds the whole system. Three typographic voices, and the rule between them is literal:

voice face what it is
preprinted Archivo, expanded, caps what the form was printed with: headings, field captions, buttons
typed IBM Plex Mono what somebody entered on it: values, serials, names, user input
prose IBM Plex Sans the plain-English notes in the margin: blurbs and hints

Three inks, each with exactly one job and never used decoratively: --canary (municipal form yellow) is what is selected right now, --stamp (oxblood) is filed / refused / destroyed, --verdi (municipal teal) is checked and valid.

The one loud thing is the rubber stamp, and it only ever marks a real change of state: the file opened, the application approved, the placement issued. It is masked with SVG turbulence so the ink lands unevenly, and the paper on the desk takes the hit with it.

Fonts are bundled, never fetched: a NUI page has no guaranteed internet. Any glyph used in content: must exist in the shipped latin subset, which is why the validation tick is drawn from borders rather than U+2713.

Screens can be looked at without launching the game: python3 /opt/preview/build.py stubs the NUI bridge, pushes each screen into a representative state, and writes standalone pages to /opt/preview/out for headless Chrome to shoot.

Operating it

service fivem start|stop|restart|status
rcon <command>            # e.g. rcon refresh, rcon status
tail -f /opt/fivem/logs/server.log

supervise.sh restarts FXServer if it dies, backing off from 5s up to 5min so a server that cannot start (bad key, database down) does not hammer Cfx. It also holds a FIFO open on the server's stdin — FXServer quits the moment stdin reaches EOF, and that FIFO is what rcon writes to.

Starting on boot

There is no systemd in this container. The platform runs a login shell as PID 1, which sources /etc/profile.d/redl-autostart.sh, which starts everything marked in /etc/redl/enabled. Both mariadb and fivem are marked, and /etc/init.d/fivem waits for MariaDB to answer before starting the server.

Database

MariaDB, database rp, application user rp@127.0.0.1 with only SELECT/INSERT/UPDATE/DELETE. Passwords are scrypt with a per-password salt and the cost parameters stored in the hash. Tables: accounts, auth_attempts, characters, transactions, inventory, vehicles.

Every query goes through DB.Query/DB.Insert/... with ? parameters. CLIENT_MULTI_STATEMENTS is deliberately not negotiated, so even a failure of the escaper could not turn a parameter into a second statement.

Not yet built

The pre-spawn experience and the framework underneath it are done. Gameplay on top of it — chat, HUD, inventory, jobs, vehicles, policing, medical — is not. characters, transactions, inventory and vehicles already have their tables and the money API in rp_core/server/player.lua is journalled and ready.