{"id":193071,"date":"2025-08-17T08:32:20","date_gmt":"2025-08-17T06:32:20","guid":{"rendered":"https:\/\/fivemx.com\/?p=193071"},"modified":"2026-06-22T20:42:15","modified_gmt":"2026-06-22T18:42:15","slug":"fivem-skripte-pflegen","status":"publish","type":"post","link":"https:\/\/fivemx.com\/de\/maintain-fivem-scripts\/","title":{"rendered":"So bewerten, testen und warten Sie FiveM-Skripte"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">This no-fluff guide how to maintain FiveM scripts is for server owners, developers, and QA leads. You\u2019ll get a production-like \u201cTest City\u201d 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.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">TL;DR<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Spin up <strong>Test City<\/strong> (<a href=\"https:\/\/fivemx.com\/how-to-run-a-fivem-server-using-docker\/\" data-type=\"post\" data-id=\"199189\">Docker<\/a>) to isolate and benchmark any script safely.<\/li>\n\n\n\n<li>Run the <strong>Acceptance Checklist<\/strong> before a penny changes hands.<\/li>\n\n\n\n<li>Use the <strong>Risk Score (0\u2013100)<\/strong> to decide ship\/hold\/reject.<\/li>\n\n\n\n<li>Vet sellers with the <strong>Vendor Rubric<\/strong> (don\u2019t skip this).<\/li>\n\n\n\n<li>If you buy, prefer reputable stores \u2014 see our picks: <strong><a href=\"https:\/\/fivemx.com\/best-tebex-shops\/\">Best Tebex Shops<\/a><\/strong>.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">Part 1 \u2014 \u201cTest City\u201d (Docker) for Safe, Repeatable Script QA<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>What you get<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Containerized FXServer + MariaDB (+ Adminer)<\/li>\n\n\n\n<li>Clean <a class=\"wpil_keyword_link\" href=\"https:\/\/fivemx.com\/fivem-server-cfg\/\" title=\"FiveM server.cfg \u2013 Full Guide\" data-wpil-keyword-link=\"linked\" data-wpil-monitor-id=\"1711\">server.cfg<\/a> with <code>oxmysql<\/code> and base resources<\/li>\n\n\n\n<li>Bind-mounted <code>resources\/custom<\/code> where you drop the script under test<\/li>\n\n\n\n<li>Deterministic network names\/ports for simple DB strings<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/github.com\/kashuax\/FiveM-Test-City\" data-type=\"link\" data-id=\"https:\/\/github.com\/kashuax\/FiveM-Test-City\" target=\"_blank\" rel=\"noopener\"><strong>Download test-city.zip<\/strong><\/a> (Github)<\/p>\n\n\n\n<div class=\"wp-block-buttons is-layout-flex wp-block-buttons-is-layout-flex\">\n<div class=\"wp-block-button\"><a class=\"wp-block-button__link wp-element-button\" href=\"https:\/\/fivemx.com\/how-to-run-a-fivem-server-using-docker\/\">How to Use Docker (FiveM)<\/a><\/div>\n<\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>How to use:<\/strong><\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Unzip \u2192 <code>cd test-city<\/code><\/li>\n\n\n\n<li>Copy <code>.env.example<\/code> to <code>.env<\/code> and set your <code>LICENSE_KEY<\/code> (and DB creds if you like).<\/li>\n\n\n\n<li>Drop <code>oxmysql<\/code> into <code>server-data\/resources\/[standalone]\/oxmysql\/<\/code>.<\/li>\n\n\n\n<li>Put the script under test into <code>server-data\/resources\/custom\/&lt;scriptname&gt;\/<\/code> and add <code>ensure &lt;scriptname&gt;<\/code> to <code>server.cfg<\/code>.<\/li>\n\n\n\n<li><code>docker compose build &amp;&amp; docker compose up -d<\/code> \u2192 connect via Direct Connect to <code>localhost:30120<\/code>.<\/li>\n<\/ol>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\"><strong>Prereqs:<\/strong> Docker + Docker Compose, a cfx license key, and an <code>oxmysql<\/code> resource copy (drop into <code>server-data\/resources\/[standalone]\/oxmysql<\/code>).<\/p>\n<\/blockquote>\n\n\n\n<h3 class=\"wp-block-heading\">Folder layout<\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">test-city\/\n\u251c\u2500 docker-compose.yml\n\u251c\u2500 fxserver\/\n\u2502  \u251c\u2500 Dockerfile\n\u2502  \u2514\u2500 entrypoint.sh\n\u251c\u2500 server-data\/\n\u2502  \u251c\u2500 server.cfg\n\u2502  \u2514\u2500 resources\/\n\u2502     \u251c\u2500 [standalone]\/oxmysql\/   # place oxmysql here\n\u2502     \u2514\u2500 custom\/                 # put the script under test here (e.g., myscript\/)\n\u2514\u2500 .env\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\"><code>.env<\/code> (example)<\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">LICENSE_KEY=changeme_cfx_license_key\nMYSQL_DATABASE=fivem\nMYSQL_USER=fivem\nMYSQL_PASSWORD=fivempw\nMYSQL_ROOT_PASSWORD=rootpw\nFX_ARTIFACT_URL=https:\/\/runtime.fivem.net\/artifacts\/fivem\/build_proot_linux\/master\/LATEST.tar.xz\n# Tip: replace with a specific artifact URL you trust for reproducibility.\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\"><code>docker-compose.yml<\/code><\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">version: \"3.9\"\n\nnetworks:\n  testcity:\n\nvolumes:\n  db_data:\n\nservices:\n  db:\n    image: mariadb:10.11\n    restart: unless-stopped\n    environment:\n      MYSQL_DATABASE: ${MYSQL_DATABASE}\n      MYSQL_USER: ${MYSQL_USER}\n      MYSQL_PASSWORD: ${MYSQL_PASSWORD}\n      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}\n    command: &gt;\n      --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci\n      --innodb_buffer_pool_size=256M\n    volumes:\n      - db_data:\/var\/lib\/mysql\n    networks: [testcity]\n\n  adminer:\n    image: adminer:4\n    restart: unless-stopped\n    ports:\n      - \"8080:8080\"\n    networks: [testcity]\n    depends_on: [db]\n\n  fxserver:\n    build:\n      context: .\/fxserver\n      args:\n        FX_ARTIFACT_URL: ${FX_ARTIFACT_URL}\n    restart: unless-stopped\n    environment:\n      LICENSE_KEY: ${LICENSE_KEY}\n      MYSQL_DATABASE: ${MYSQL_DATABASE}\n      MYSQL_USER: ${MYSQL_USER}\n      MYSQL_PASSWORD: ${MYSQL_PASSWORD}\n    depends_on: [db]\n    networks: [testcity]\n    ports:\n      - \"30120:30120\/udp\"\n      - \"30120:30120\/tcp\"\n      - \"40120:40120\/tcp\" # txAdmin (optional)\n    volumes:\n      - .\/server-data:\/opt\/fivem\/server-data\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\"><code>fxserver\/Dockerfile<\/code><\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">FROM debian:bookworm-slim\n\nARG FX_ARTIFACT_URL\nENV DEBIAN_FRONTEND=noninteractive\n\nRUN apt-get update &amp;&amp; apt-get install -y --no-install-recommends \n    xz-utils curl ca-certificates tini bash &amp;&amp; \n    rm -rf \/var\/lib\/apt\/lists\/*\n\n# Fetch &amp; extract FXServer artifact (URL provided via build-arg)\nRUN mkdir -p \/opt\/fivem &amp;&amp; \n    curl -fsSL \"$FX_ARTIFACT_URL\" -o \/opt\/fivem\/fx.tar.xz &amp;&amp; \n    tar -xJf \/opt\/fivem\/fx.tar.xz -C \/opt\/fivem &amp;&amp; \n    rm -f \/opt\/fivem\/fx.tar.xz\n\n# Non-root\nRUN useradd -ms \/bin\/bash fivem\nUSER fivem\n\nWORKDIR \/opt\/fivem\nCOPY --chown=fivem:fivem ..\/server-data \/opt\/fivem\/server-data\nCOPY --chown=fivem:fivem entrypoint.sh \/entrypoint.sh\n\nENTRYPOINT [\"\/usr\/bin\/tini\",\"--\"]\nCMD [\"\/bin\/bash\",\"\/entrypoint.sh\"]\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\"><code>fxserver\/entrypoint.sh<\/code><\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">#!\/usr\/bin\/env bash\nset -euo pipefail\n\n# Provide DB string for oxmysql via server.cfg (already set there),\n# just ensure the DB is reachable before boot to avoid spam errors.\necho \"Waiting for database...\"\nuntil nc -z db 3306; do sleep 1; done\necho \"DB ready.\"\n\n# Run FXServer with our server.cfg\n# Most Linux artifacts ship a run.sh in the artifact root.\nexec bash \/opt\/fivem\/run.sh +exec \/opt\/fivem\/server-data\/server.cfg\n<\/pre>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">If your artifact uses a different launcher path, adjust the last line accordingly (e.g., <code>\/opt\/fivem\/alpine\/opt\/cfx-server\/run.sh<\/code>).<\/p>\n<\/blockquote>\n\n\n\n<h3 class=\"wp-block-heading\"><code>server-data\/server.cfg<\/code> (lean, test-ready)<\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># ---------- Identity ----------\nsv_licenseKey \"%LICENSE_KEY%\"            # injected by env in entrypoint command or replace manually\nsv_hostname \"Test City \u2014 Script QA\"\nsets tags \"qa,testing,fivemx\"\nsv_maxclients 2\nonesync on\nsv_scriptHookAllowed 0\nsv_enforceGameBuild 3095\n\n# ---------- Networking ----------\nendpoint_add_tcp \"0.0.0.0:30120\"\nendpoint_add_udp \"0.0.0.0:30120\"\n\n# ---------- Database (oxmysql) ----------\nset mysql_connection_string \"mysql:\/\/%MYSQL_USER%:%MYSQL_PASSWORD%@db:3306\/%MYSQL_DATABASE%?charset=utf8mb4\"\n\n# ---------- Core \/ Base resources ----------\nensure mapmanager\nensure chat\nensure spawnmanager\nensure sessionmanager\nensure hardcap\nensure baseevents\n\n# ---------- Datastore ----------\nensure oxmysql\n\n# ---------- Under test ----------\n# Drop your script folder into resources\/custom\/&lt;scriptname&gt; and enable here:\n# ensure myscript\n\n# ---------- QA helpers ----------\n# Verbose logging in dev\nsetr con_minSeverity info\n\n# Enable txAdmin panel (optional)\nsetr txAdminPort 40120\n<\/pre>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\"><strong>Enable your script:<\/strong> copy it into <code>server-data\/resources\/custom\/myscript\/<\/code> and add <code>ensure myscript<\/code> to the bottom block.<\/p>\n<\/blockquote>\n\n\n\n<h3 class=\"wp-block-heading\">Run it<\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">cd test-city\ndocker compose build\ndocker compose up -d\n# Adminer at http:\/\/localhost:8080 (server: db, user: fivem, pass: fivempw)\n# Connect FiveM client \u2192 Direct Connect: your-docker-host:30120\n<\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">Part 2 \u2014 Script Acceptance Checklist (Do Not Skip)<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Use this every time. Copy into your tracker and check off items.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">A. Pre-flight (before install)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Source type:<\/strong> Open source \/ partially open \/ escrow-only.<\/li>\n\n\n\n<li><strong>Dependencies listed:<\/strong> framework (ESX\/QBCore\/QBOX), <code>ox_lib<\/code>, <code>oxmysql<\/code>, <code>PolyZone<\/code>, etc.<\/li>\n\n\n\n<li><strong>fxmanifest.lua:<\/strong> <code>lua54 'yes'<\/code>, correct <code>game 'gta5'<\/code>, <code>fx_version<\/code> not ancient.<\/li>\n\n\n\n<li><strong>Docs:<\/strong> install steps, config examples, permissions, locales, known conflicts.<\/li>\n\n\n\n<li><strong>License\/ToS:<\/strong> usage rights, refund policy, updates, support channel.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">B. Installability<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>No console errors on <code>ensure<\/code>:<\/strong> zero stack traces or asset missing spam.<\/li>\n\n\n\n<li><strong>No <code>deprecated natives<\/code> spam.<\/strong><\/li>\n\n\n\n<li><strong>Config loads clean:<\/strong> no JSON\/Lua syntax errors.<\/li>\n\n\n\n<li><strong>DB migrations:<\/strong> create tables once; re-starts don\u2019t re-apply or break.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">C. Functional<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong><a class=\"wpil_keyword_link\" href=\"https:\/\/fivemx.com\/brand\/core\/\" title=\"Core\" data-wpil-keyword-link=\"linked\" data-wpil-monitor-id=\"1709\">Core<\/a> flows work:<\/strong> happy path tested (e.g., purchase, job flow, crafting).<\/li>\n\n\n\n<li><strong>Edge cases:<\/strong> wrong inputs, missing perms, out-of-range quantities.<\/li>\n\n\n\n<li><strong>Localization:<\/strong> no hard-coded strings if locales promised.<\/li>\n\n\n\n<li><strong>Permissions:<\/strong> staff\/admin commands gated; no free access client-side.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">D. Performance (client &amp; server)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong><code>resmon<\/code>:<\/strong> idle \u2264 <strong>0.10ms<\/strong>, active \u2264 <strong>0.50ms<\/strong> (client).<\/li>\n\n\n\n<li><a href=\"https:\/\/fivemx.com\/fivem-thread-hitch-warning-fix\/\" title=\"Server Thread Hitch Warning: Effortless Must-Have Fix\" data-wpil-monitor-id=\"1532\">Server tick health: no long hitch warnings<\/a> under normal use.<\/li>\n\n\n\n<li><strong>DB queries:<\/strong> no tight loops; prepared statements used; minimal N+1.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">E. Security<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Server-side validation:<\/strong> every server event validates <code>source<\/code>, perms, and input types.<\/li>\n\n\n\n<li><strong>No trust in client:<\/strong> money\/inventory changes only from server logic.<\/li>\n\n\n\n<li><strong>No eval\/<code>loadstring<\/code>\/remote code<\/strong> patterns.<\/li>\n\n\n\n<li><strong>Anti-abuse:<\/strong> rate limits\/throttles on spammy endpoints.<\/li>\n\n\n\n<li><strong>Escrow integrity:<\/strong> no backdoors in non-escrow config loaders.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Good event pattern (example):<\/strong><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">RegisterNetEvent('myscript:buy', function(item, amount)\n  local src = source\n  if type(item) ~= 'string' or type(amount) ~= 'number' or amount &lt; 1 then return end\n  if not HasPermission(src, 'shop.buy') then return end\n  local xPlayer = GetPlayer(src) -- framework adapter\n  if not xPlayer then return end\n  -- validate price server-side, check inventory limits, do DB in a transaction\nend)\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">F. Compatibility &amp; Cleanliness<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Framework adapters present<\/strong> (ESX\/QBCore\/QBOX) or clearly declared unsupported.<\/li>\n\n\n\n<li><strong>No globals leakage<\/strong>, unique event names, no resource name assumptions.<\/li>\n\n\n\n<li><strong>Uninstall clean:<\/strong> removing the resource doesn\u2019t break others.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">Part 3 \u2014 Quantitative Risk Scoring Model (0\u2013100)<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Use this to decide \u201cship\/hold\/reject.\u201d Lower is better.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Factor<\/th><th>Weight<\/th><th>How to Score (0=good \u2192 5=bad)<\/th><\/tr><\/thead><tbody><tr><td><strong>Performance<\/strong><\/td><td>0.20<\/td><td><a class=\"wpil_keyword_link\" href=\"https:\/\/fivemx.com\/how-to-use-resmon-in-fivem-optimize-resources\/\" title=\"How to Use Resmon in FiveM (To Optimize Resources)\" data-wpil-keyword-link=\"linked\" data-wpil-monitor-id=\"1710\">resmon<\/a> idle: 0=\u22640.10ms, 1=\u22640.20, 3=\u22640.50, 5=&gt;0.50; spikes add +1<\/td><\/tr><tr><td><strong>Security<\/strong><\/td><td>0.25<\/td><td>0=all server-validated + rate limits; 3=some gaps; 5=trusts client \/ unsafe events<\/td><\/tr><tr><td><strong>Stability<\/strong><\/td><td>0.15<\/td><td>0=no errors; 3=occasional warnings; 5=frequent errors\/hitches<\/td><\/tr><tr><td><strong>Compatibility<\/strong><\/td><td>0.10<\/td><td>0=adapters\/tests; 3=one framework only; 5=breaks common deps<\/td><\/tr><tr><td><strong>Maintainability<\/strong><\/td><td>0.10<\/td><td>0=docs\/changelog\/semantic versions; 5=no docs\/abandoned<\/td><\/tr><tr><td><strong>Supply-chain\/Vendor<\/strong><\/td><td>0.20<\/td><td>0=reputable, history, refunds; 5=unknown, no policy<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Formula<\/strong><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">RiskScore = 100 * \u03a3(weight_i * (score_i \/ 5))\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Bands &amp; Actions<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>0\u201324 (Low):<\/strong> Ship to staging, monitor.<\/li>\n\n\n\n<li><strong>25\u201349 (Moderate):<\/strong> Fixes required before live.<\/li>\n\n\n\n<li><strong>50\u201374 (High):<\/strong> Hold; request vendor patches or replace.<\/li>\n\n\n\n<li><strong>75\u2013100 (Critical):<\/strong> Reject.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Example<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Perf=1, Sec=3, Stability=1, Compat=1, Maint=2, Vendor=1<\/li>\n\n\n\n<li>Risk = 100*(.2*.2 + .25*.6 + .15*.2 + .1*.2 + .1*.4 + .2*.2) = <strong>34 \u2192 Moderate<\/strong><\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">Part 4 \u2014 Vendor Vetting Rubric (score each 0\u20135, higher is <strong>better<\/strong>)<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Criterion<\/th><th>What \u201cGood\u201d Looks Like<\/th><th>Notes<\/th><\/tr><\/thead><tbody><tr><td><strong>Identity &amp; Track Record<\/strong><\/td><td>Clear brand, years active, consistent handle<\/td><td>Avoid burner stores<\/td><\/tr><tr><td><strong>Documentation<\/strong><\/td><td>Install + config + perms + troubleshooting<\/td><td>Screenshots\/gifs help<\/td><\/tr><tr><td><strong>Update Cadence<\/strong><\/td><td>Changelog, semantic versions, recent commits\/releases<\/td><td>Quarterly+ is fine<\/td><\/tr><tr><td><strong>Support Quality<\/strong><\/td><td>Ticket\/Discord SLAs, reproducible fixes, not just \u201crestart\u201d<\/td><td>Sample responses<\/td><\/tr><tr><td><strong>Issue Transparency<\/strong><\/td><td>Public known issues &amp; roadmap<\/td><td>Honesty &gt; perfection<\/td><\/tr><tr><td><strong>Refund\/ToS Clarity<\/strong><\/td><td>Refund window, conditions, license terms<\/td><td>No dark patterns<\/td><\/tr><tr><td><strong>Testing Proof<\/strong><\/td><td>Staging video, perf metrics, framework list<\/td><td>Even better: demo server<\/td><\/tr><tr><td><strong>Security Hygiene<\/strong><\/td><td>Mentions server-side checks, no sensitive keys, no eval<\/td><td>Ask about audits<\/td><\/tr><tr><td><strong>Compatibility Policy<\/strong><\/td><td>ESX\/QBCore\/QBOX stated, adapters, version matrix<\/td><td>State supported builds<\/td><\/tr><tr><td><strong>Pricing &amp; Value<\/strong><\/td><td>Fair for complexity, no dependency paywalls<\/td><td>Watch upsell traps<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Rubric Score (0\u201350):<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>40\u201350: Strong \u2014 preferred vendor<\/li>\n\n\n\n<li>30\u201339: Acceptable \u2014 monitor<\/li>\n\n\n\n<li>20\u201329: Weak \u2014 proceed cautiously<\/li>\n\n\n\n<li>&lt;20: Avoid<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Pro tip:<\/strong> Cross-reference with reputable marketplaces. Start here: <strong><a href=\"https:\/\/fivemx.com\/best-tebex-shops\/\">Best Tebex Shops<\/a><\/strong>.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">Part 5 \u2014 Maintenance Playbook (After You Ship)<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Version pinning:<\/strong> lock script releases + dependency versions (e.g., <code>oxmysql<\/code>, <code>ox_lib<\/code>).<\/li>\n\n\n\n<li><strong>Staging first:<\/strong> all updates land in <strong>Test City<\/strong>; run the acceptance checklist again.<\/li>\n\n\n\n<li><strong>Backups &amp; rollback:<\/strong> DB snapshot + resource files before each update. Keep a <strong>Rollback.md<\/strong> with exact steps.<\/li>\n\n\n\n<li><strong>CI smoke test (optional, recommended):<\/strong> headless client connect + command macro to hit main flows; parse server console for errors.<\/li>\n\n\n\n<li><strong>Operational metrics:<\/strong> keep a simple ledger per script: average resmon (idle\/active), error count\/session, incident notes.<\/li>\n\n\n\n<li><strong>Changelog discipline:<\/strong> require vendor changelogs; maintain your own integration notes.<\/li>\n\n\n\n<li><strong>De-risk scheduled events:<\/strong> update outside peak hours; announce maintenance windows.<\/li>\n<\/ol>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">Part 6 \u2014 Templates You Can Copy<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">A. Test Plan (per script)<\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># Script Test Plan \u2014 &lt;name&gt; &lt;version&gt;\n\n## Context\nFramework(s): ESX\/QBCore\/QBOX\nDependencies: oxmysql vX, ox_lib vY, PolyZone vZ\nDB Migrations: yes\/no\nEscrow: yes\/no\n\n## Functional Cases\n- [ ] Case 1:\n- [ ] Case 2:\n- [ ] Negative 1:\n\n## Performance\nresmon idle: ____ ms\nresmon active: ____ ms (scenario: ______)\n\n## Security Checks\n- [ ] All server events validate source\/perm\/input\n- [ ] Rate limits present\n- [ ] No client-trusted money\/inventory mutations\n\n## Logs &amp; Errors\nPaste snippet (server + F8): \n\n## Result\nPass\/Fail + Notes\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">B. Rollback.md (skeleton)<\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># Rollback \u2014 &lt;date&gt; &lt;script&gt; &lt;from\u2192to&gt;\n\n1) Disable script: `stop &lt;resource&gt;`\n2) Restore resource files from backup: &lt;path&gt;\n3) Restore DB snapshot: &lt;path\/command&gt;\n4) Restart FXServer\n5) Verify: console clean, perf normal, flows ok\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">C. Issue Template<\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">**Summary**\nWhat happened vs expected, with timestamps.\n\n**Repro Steps**\n1) ...\n2) ...\n\n**Env**\nArtifact build:\nFramework &amp; versions:\nScript version:\nOther deps:\n\n**Logs**\nServer console:\nF8:\n\n**Attachments**\nScreens\/video if possible.\n<\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">How to Use This Guide Efficiently<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Bootstrap Test City<\/strong> once, keep it clean.<\/li>\n\n\n\n<li>For each candidate script:\n<ul class=\"wp-block-list\">\n<li>Drop into <code>resources\/custom\/<\/code>, enable in <code>server.cfg<\/code>.<\/li>\n\n\n\n<li>Run the <strong>Acceptance Checklist<\/strong>.<\/li>\n\n\n\n<li>Compute the <strong>Risk Score<\/strong>.<\/li>\n\n\n\n<li>Vet the seller with the <strong>Vendor Rubric<\/strong>.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>If it passes, merge into staging; if not, request fixes or walk away.<\/li>\n<\/ol>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Need more testing guides?<\/strong> Check out the section<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This no-fluff guide how to maintain FiveM scripts is for server owners, developers, and QA leads. You\u2019ll get a production-like \u201cTest City\u201d 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 Part 1 \u2014 \u201cTest City\u201d (Docker) for Safe, [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":193073,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2883],"tags":[2884],"class_list":["post-193071","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-buying-testing-maintaining-fivem-scripts","tag-maintain-fivem-scripts"],"blocksy_meta":[],"_links":{"self":[{"href":"https:\/\/fivemx.com\/de\/wp-json\/wp\/v2\/posts\/193071","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fivemx.com\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fivemx.com\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/fivemx.com\/de\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/fivemx.com\/de\/wp-json\/wp\/v2\/comments?post=193071"}],"version-history":[{"count":1,"href":"https:\/\/fivemx.com\/de\/wp-json\/wp\/v2\/posts\/193071\/revisions"}],"predecessor-version":[{"id":207098,"href":"https:\/\/fivemx.com\/de\/wp-json\/wp\/v2\/posts\/193071\/revisions\/207098"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/fivemx.com\/de\/wp-json\/wp\/v2\/media\/193073"}],"wp:attachment":[{"href":"https:\/\/fivemx.com\/de\/wp-json\/wp\/v2\/media?parent=193071"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fivemx.com\/de\/wp-json\/wp\/v2\/categories?post=193071"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fivemx.com\/de\/wp-json\/wp\/v2\/tags?post=193071"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}