
How to Evaluate, Test, and Maintain FiveM Scripts
Darmowe skrypty są wystarczające do szybkich kontroli. W przypadku serwerów produkcyjnych porównaj pełne pakiety serwerowe lub płatne skrypty, korzystając z frameworka i przypadku użycia.
This no-fluff guide how to maintain FiveM scripts is for server owners, developers, and QA leads. You’ll get a production-like “Test City” in Docker, an acceptance checklist you can run end-to-end, a quantitative risk scoring model, and a vendor-vetting rubric that keeps you away from headaches.
TL;DR
- Spin up Test City (Docker) to isolate and benchmark any script safely.
- Uruchom Acceptance Checklist before a penny changes hands.
- Use the Risk Score (0–100) to decide ship/hold/reject.
- Vet sellers with the Vendor Rubric (don’t skip this).
- If you buy, prefer reputable stores — see our picks: Best Tebex Shops.
Part 1 — “Test City” (Docker) for Safe, Repeatable Script QA
What you get
- Containerized FXServer + MariaDB (+ Adminer)
- Clean server.cfg z
oxmysqland base resources - Bind-mounted
resources/customwhere you drop the script under test - Deterministic network names/ports for simple DB strings
Download test-city.zip (Github)
How to use:
- Unzip →
cd test-city - Copy
.env.exampledo.envand set yourLICENSE_KEY(and DB creds if you like). - Drop
oxmysqlintoserver-data/resources/[standalone]/oxmysql/. - Put the script under test into
server-data/resources/custom/<scriptname>/and addensure <scriptname>doserver.cfg. docker compose build && docker compose up -d→ connect via Direct Connect tolocalhost:30120.
Prereqs: Docker + Docker Compose, a cfx license key, and an
oxmysqlresource copy (drop intoserver-data/resources/[standalone]/oxmysql).
Folder layout
test-city/ ├─ docker-compose.yml ├─ fxserver/ │ ├─ Dockerfile │ └─ entrypoint.sh ├─ server-data/ │ ├─ server.cfg │ └─ resources/ │ ├─ [standalone]/oxmysql/ # place oxmysql here │ └─ custom/ # put the script under test here (e.g., myscript/) └─ .env
.env (przykład)
LICENSE_KEY=changeme_cfx_license_key MYSQL_DATABASE=fivem MYSQL_USER=fivem MYSQL_PASSWORD=fivempw MYSQL_ROOT_PASSWORD=rootpw FX_ARTIFACT_URL=https://runtime.fivem.net/artifacts/fivem/build_proot_linux/master/LATEST.tar.xz # Tip: replace with a specific artifact URL you trust for reproducibility.
docker-compose.yml
version: "3.9"
networks:
testcity:
volumes:
db_data:
services:
db:
image: mariadb:10.11
restart: unless-stopped
environment:
MYSQL_DATABASE: ${MYSQL_DATABASE}
MYSQL_USER: ${MYSQL_USER}
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
command: >
--character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
--innodb_buffer_pool_size=256M
volumes:
- db_data:/var/lib/mysql
networks: [testcity]
adminer:
image: adminer:4
restart: unless-stopped
ports:
- "8080:8080"
networks: [testcity]
depends_on: [db]
fxserver:
build:
context: ./fxserver
args:
FX_ARTIFACT_URL: ${FX_ARTIFACT_URL}
restart: unless-stopped
environment:
LICENSE_KEY: ${LICENSE_KEY}
MYSQL_DATABASE: ${MYSQL_DATABASE}
MYSQL_USER: ${MYSQL_USER}
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
depends_on: [db]
networks: [testcity]
ports:
- "30120:30120/udp"
- "30120:30120/tcp"
- "40120:40120/tcp" # txAdmin (optional)
volumes:
- ./server-data:/opt/fivem/server-data
fxserver/Dockerfile
FROM debian:bookworm-slim
ARG FX_ARTIFACT_URL
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y --no-install-recommends
xz-utils curl ca-certificates tini bash &&
rm -rf /var/lib/apt/lists/*
# Fetch & extract FXServer artifact (URL provided via build-arg)
RUN mkdir -p /opt/fivem &&
curl -fsSL "$FX_ARTIFACT_URL" -o /opt/fivem/fx.tar.xz &&
tar -xJf /opt/fivem/fx.tar.xz -C /opt/fivem &&
rm -f /opt/fivem/fx.tar.xz
# Non-root
RUN useradd -ms /bin/bash fivem
USER fivem
WORKDIR /opt/fivem
COPY --chown=fivem:fivem ../server-data /opt/fivem/server-data
COPY --chown=fivem:fivem entrypoint.sh /entrypoint.sh
ENTRYPOINT ["/usr/bin/tini","--"]
CMD ["/bin/bash","/entrypoint.sh"]
fxserver/entrypoint.sh
#!/usr/bin/env bash set -euo pipefail # Provide DB string for oxmysql via server.cfg (already set there), # just ensure the DB is reachable before boot to avoid spam errors. echo "Waiting for database..." until nc -z db 3306; do sleep 1; done echo "DB ready." # Run FXServer with our server.cfg # Most Linux artifacts ship a run.sh in the artifact root. exec bash /opt/fivem/run.sh +exec /opt/fivem/server-data/server.cfg
If your artifact uses a different launcher path, adjust the last line accordingly (e.g.,
/opt/fivem/alpine/opt/cfx-server/run.sh).
server-data/server.cfg (lean, test-ready)
# ---------- Identity ---------- sv_licenseKey "%LICENSE_KEY%" # injected by env in entrypoint command or replace manually sv_hostname "Test City — Script QA" sets tags "qa,testing,fivemx" sv_maxclients 2 onesync on sv_scriptHookAllowed 0 sv_enforceGameBuild 3095 # ---------- Networking ---------- endpoint_add_tcp "0.0.0.0:30120" endpoint_add_udp "0.0.0.0:30120" # ---------- Database (oxmysql) ---------- set mysql_connection_string "mysql://%MYSQL_USER%:%MYSQL_PASSWORD%@db:3306/%MYSQL_DATABASE%?charset=utf8mb4" # ---------- Core / Base resources ---------- ensure mapmanager ensure chat ensure spawnmanager ensure sessionmanager ensure hardcap ensure baseevents # ---------- Datastore ---------- ensure oxmysql # ---------- Under test ---------- # Drop your script folder into resources/custom/<scriptname> and enable here: # ensure myscript # ---------- QA helpers ---------- # Verbose logging in dev setr con_minSeverity info # Enable txAdmin panel (optional) setr txAdminPort 40120
Enable your script: copy it into
server-data/resources/custom/myscript/and addensure myscriptto the bottom block.
Run it
cd test-city docker compose build docker compose up -d # Adminer at http://localhost:8080 (server: db, user: fivem, pass: fivempw) # Connect FiveM client → Direct Connect: your-docker-host:30120
Part 2 — Script Acceptance Checklist (Do Not Skip)
Use this every time. Copy into your tracker and check off items.
A. Pre-flight (before install)
- Source type: Open source / partially open / escrow-only.
- Dependencies listed: framework (ESX/QBCore/QBOX),
ox_lib,oxmysql,PolyZone, etc. - fxmanifest.lua:
lua54 'tak'', correctgame 'gta5',fx_versionnot ancient. - Docs: install steps, config examples, permissions, locales, known conflicts.
- License/ToS: usage rights, refund policy, updates, support channel.
B. Installability
- No console errors on
zapewnić: zero stack traces or asset missing spam. - No
deprecated nativesspam. - Config loads clean: no JSON/Lua syntax errors.
- DB migrations: create tables once; re-starts don’t re-apply or break.
C. Functional
- Rdzeń flows work: happy path tested (e.g., purchase, job flow, crafting).
- Edge cases: wrong inputs, missing perms, out-of-range quantities.
- Localization: no hard-coded strings if locales promised.
- Permissions: staff/admin commands gated; no free access client-side.
D. Performance (client & server)
resmon: idle ≤ 0.10ms, active ≤ 0.50ms (client).- Server tick health: no long hitch warnings under normal use.
- DB queries: no tight loops; prepared statements used; minimal N+1.
E. Security
- Server-side validation: every server event validates
źródło, perms, and input types. - No trust in client: money/inventory changes only from server logic.
- No eval/
loadstring/remote code patterns. - Anti-abuse: rate limits/throttles on spammy endpoints.
- Escrow integrity: no backdoors in non-escrow config loaders.
Good event pattern (example):
RegisterNetEvent('myscript:buy', function(item, amount)
local src = source
if type(item) ~= 'string' or type(amount) ~= 'number' or amount < 1 then return end
if not HasPermission(src, 'shop.buy') then return end
local xPlayer = GetPlayer(src) -- framework adapter
if not xPlayer then return end
-- validate price server-side, check inventory limits, do DB in a transaction
end)
F. Compatibility & Cleanliness
- Framework adapters present (ESX/QBCore/QBOX) or clearly declared unsupported.
- No globals leakage, unique event names, no resource name assumptions.
- Uninstall clean: removing the resource doesn’t break others.
Part 3 — Quantitative Risk Scoring Model (0–100)
Use this to decide “ship/hold/reject.” Lower is better.
| Factor | Weight | How to Score (0=good → 5=bad) |
|---|---|---|
| Wydajność | 0.20 | resmon idle: 0=≤0.10ms, 1=≤0.20, 3=≤0.50, 5=>0.50; spikes add +1 |
| Security | 0.25 | 0=all server-validated + rate limits; 3=some gaps; 5=trusts client / unsafe events |
| Stability | 0.15 | 0=no errors; 3=occasional warnings; 5=frequent errors/hitches |
| Zgodność | 0.10 | 0=adapters/tests; 3=one framework only; 5=breaks common deps |
| Maintainability | 0.10 | 0=docs/changelog/semantic versions; 5=no docs/abandoned |
| Supply-chain/Vendor | 0.20 | 0=reputable, history, refunds; 5=unknown, no policy |
Formula
RiskScore = 100 * Σ(weight_i * (score_i / 5))
Bands & Actions
- 0–24 (Low): Ship to staging, monitor.
- 25–49 (Moderate): Fixes required before live.
- 50–74 (High): Hold; request vendor patches or replace.
- 75–100 (Critical): Reject.
Example
- Perf=1, Sec=3, Stability=1, Compat=1, Maint=2, Vendor=1
- Risk = 100*(.2*.2 + .25*.6 + .15*.2 + .1*.2 + .1*.4 + .2*.2) = 34 → Moderate
Part 4 — Vendor Vetting Rubric (score each 0–5, higher is better)
| Criterion | What “Good” Looks Like | Uwagi |
|---|---|---|
| Identity & Track Record | Clear brand, years active, consistent handle | Avoid burner stores |
| Documentation | Install + config + perms + troubleshooting | Screenshots/gifs help |
| Update Cadence | Changelog, semantic versions, recent commits/releases | Quarterly+ is fine |
| Support Quality | Ticket/Discord SLAs, reproducible fixes, not just “restart” | Sample responses |
| Issue Transparency | Public known issues & roadmap | Honesty > perfection |
| Refund/ToS Clarity | Refund window, conditions, license terms | No dark patterns |
| Testing Proof | Staging video, perf metrics, framework list | Even better: demo server |
| Security Hygiene | Mentions server-side checks, no sensitive keys, no eval | Ask about audits |
| Compatibility Policy | ESX/QBCore/QBOX stated, adapters, version matrix | State supported builds |
| Pricing & Value | Fair for complexity, no dependency paywalls | Watch upsell traps |
Rubric Score (0–50):
- 40–50: Strong — preferred vendor
- 30–39: Acceptable — monitor
- 20–29: Weak — proceed cautiously
- <20: Avoid
Pro tip: Cross-reference with reputable marketplaces. Start here: Best Tebex Shops.
Part 5 — Maintenance Playbook (After You Ship)
- Version pinning: lock script releases + dependency versions (e.g.,
oxmysql,ox_lib). - Staging first: all updates land in Test City; run the acceptance checklist again.
- Backups & rollback: DB snapshot + resource files before each update. Keep a Rollback.md with exact steps.
- CI smoke test (optional, recommended): headless client connect + command macro to hit main flows; parse server console for errors.
- Operational metrics: keep a simple ledger per script: average resmon (idle/active), error count/session, incident notes.
- Changelog discipline: require vendor changelogs; maintain your own integration notes.
- De-risk scheduled events: update outside peak hours; announce maintenance windows.
Part 6 — Templates You Can Copy
A. Test Plan (per script)
# Script Test Plan — <name> <version> ## Context Framework(s): ESX/QBCore/QBOX Dependencies: oxmysql vX, ox_lib vY, PolyZone vZ DB Migrations: yes/no Escrow: yes/no ## Functional Cases - [ ] Case 1: - [ ] Case 2: - [ ] Negative 1: ## Performance resmon idle: ____ ms resmon active: ____ ms (scenario: ______) ## Security Checks - [ ] All server events validate source/perm/input - [ ] Rate limits present - [ ] No client-trusted money/inventory mutations ## Logs & Errors Paste snippet (server + F8): ## Result Pass/Fail + Notes
B. Rollback.md (skeleton)
# Rollback — <date> <script> <from→to> 1) Disable script: `stop <resource>` 2) Restore resource files from backup: <path> 3) Restore DB snapshot: <path/command> 4) Restart FXServer 5) Verify: console clean, perf normal, flows ok
C. Issue Template
**Summary** What happened vs expected, with timestamps. **Repro Steps** 1) ... 2) ... **Env** Artifact build: Framework & versions: Script version: Other deps: **Logs** Server console: F8: **Attachments** Screens/video if possible.
How to Use This Guide Efficiently
- Bootstrap Test City once, keep it clean.
- For each candidate script:
- Drop into
resources/custom/, enable inserver.cfg. - Uruchom Acceptance Checklist.
- Compute the Risk Score.
- Vet the seller with the Vendor Rubric.
- Drop into
- If it passes, merge into staging; if not, request fixes or walk away.
Need more testing guides? Check out the section






