So übersetzen Sie Skripte mithilfe von KI (FiveM-Leitfaden)
Publikum: FiveM-Serverbesitzer, Skriptersteller und -Betreuer, die qualitativ hochwertige Übersetzungen wünschen, ohne Platzhalter oder die Benutzeroberfläche zu beschädigen.
Kurz zusammengefasst
- Zentralisieren Sie den gesamten Text in lokalen Dateien (JSON- oder Lua-Tabellen). Verwenden Sie niemals fest codierte Zeichenfolgen in der Spiellogik.
- Platzhalter schützen (zB
%s,%d,%{name},{0},~r~,^1) während der Übersetzung. - Verwenden Sie KI für die Erstübersetzung + Glossar + automatisierte Prüfungen → schnelle menschliche Überprüfung → Versand.
- Behalten Sie eine einzige Quelle der Wahrheit (normalerweise Englisch), prüfen Sie Änderungen und generieren Sie nur geänderte Schlüssel neu.
Warum sollten Sie Ihre FiveM-Skripte übersetzen?
- Zugänglichkeit und Wachstum: Lokalisierte Server ziehen mehr Spieler an und halten sie bei der Stange.
- Professionalität: Einheitliche Terminologie für alle Befehle, Benutzeroberflächen und Fehlermeldungen.
- Beitragsfreundlich: Eine klare lokale Struktur lädt zu Community-PRs ein.
Wenn Sie eine grundlegende Auffrischung zu Struktur und Best Practices benötigen, lesen Sie: So übersetzen Sie FiveM-Skripte (richtig).
Architektur: So lokalisieren Sie richtig
Ziel: Keine für den Benutzer sichtbaren Zeichenfolgen im Gameplay-Code. Leiten Sie alles über eine Gebietsschemaebene weiter.
Empfohlenes Ressourcenlayout
my_resource/ ├─ fxmanifest.lua ├─ locales/ │ ├─ en.json # Quellsprache (einzige Quelle der Wahrheit) │ ├─ de.json # übersetzt (generiert/bearbeitet) │ ├─ es.json # übersetzt (generiert/bearbeitet) │ └─ qa.rules.json # optional: Platzhalter-Whitelist und Prüfungen ├─ client/ │ └─ main.lua ├─ server/ │ └─ main.lua └─ shared/ └─ i18n.lua # Übersetzungshilfe
fxmanifest.lua (Minimalbeispiel)
fx_version 'cerulean' Spiel 'gta5' lua54 'ja' shared_scripts { 'shared/i18n.lua', } Dateien { 'locales/*.json' }
shared/i18n.lua (leichtgewichtiger Loader + Platzhalterersetzung)
lokales LOCALE = GetConvar('my_locale', 'en') lokaler CACHE = {} lokale Funktion loadJSON(Pfad) lokale Datei = io.open(Pfad, 'r') wenn nicht Datei, dann returniere {} Ende lokaler Inhalt = Datei:lesen('*a') Datei:schließen() lokales ok, Daten = pcall(Funktion() returniere json.decode(Inhalt) Ende) returniere ok und Daten oder {} Ende lokale Funktion readLocale(Sprache) wenn CACHE[Sprache] dann returniere CACHE[Sprache] Ende lokale Datei = ('locales/%s.json'):Format(Sprache) lokales dict = loadJSON(Datei) CACHE[Sprache] = dict returniere dict Ende lokale Funktion interpoliere(str, vars) wenn nicht vars dann returniere str Ende für k, v in Paaren (vars) mache str = str:gsub('%%{'..k..'}', tostring(v)) -- %{name} end return str end function _U(key, vars) local dict = readLocale(LOCALE) local src = dict[key] if not src then -- fallback to English if missing src = readLocale('en')[key] or key end return interpolate(src, vars) end exports('Translate', _U)
Verwendung im Client/Server-Code
-- Client lib.notify({ Titel = _U('notify_title'), Beschreibung = _U('welcome_player', { Name = GetPlayerName(PlayerId()) }), }) -- Server print(('[MyRes] %s'):format(_U('server_started')))
locales/en.json (Quelle)
{ "notify_title": "Servernachricht", "welcome_player": "Willkommen, %{name}!", "server_started": "Servermodul ist bereit.", "no_permission": "Du hast keine Berechtigung.", "items_remaining": "%{count} Elemente verbleiben" }
KI-Übersetzungsworkflow (schnell und sicher)
- Quelle extrahieren und einfrieren
- Halten Englisch (oder Ihre Quelle) als
locales/en.json. - Erzwingen Sie die Benennung von Schlüsseln:
Domäne.Aktion.Betreff(z.B,Bestandsaufnahme.Ablegen.Bestätigen).
- Erstellen/Erweitern eines Glossars
- CSV- oder JSON-Zuordnung von kanonischen Begriffen → Zielbegriffen. Beispiel:
Quelle,Ziel EMS,Rettungsdienst PD,Polizeimechaniker,Mechaniker
- Platzhalter und Markup schützen
- Platzhalter:
%{name},%s,%d,{0} - FiveM-Farbcodes:
~r~,~g~,~s~; Chat-Codes:^1,^2 - NUI/HTML-Tags:
<b>,<span>…
- Übersetzen über API (Charge)
- Schicken Werte nur, behalten Schlüssel unverändert.
- Liefern Glossar Und Stil (Ton) zum Modell/Motor.
- Automatisierte Qualitätssicherung
- JSON validieren.
- Verifizieren Platzhalterparität (jeder Platzhalter in der Quelle ist im Ziel vorhanden).
- Markieren Sie verbotene Änderungen (z. B. geänderte Farbcodes oder hinzugefügte Satzzeichen, wenn diese nicht zulässig sind).
- Menschliche Stichprobenkontrolle (5–10 Minuten)
- Überprüfen Sie Befehle, Fehlermeldungen und lange UI-Zeichenfolgen.
- Ausliefern und iterieren
- Behalten Sie eine Übersetzungsspeicher (vorherige Ausgaben), um eine erneute Übersetzung unveränderter Schlüssel zu vermeiden.
Leitplanken: Hinweise und Regeln, die wirklich funktionieren
LLM-Eingabeaufforderung für JSON-Batch-Konvertierung
Aufgabe: Übersetzen Sie JSON-Werte vom Englischen in für einen FiveM/GTA RP-Kontext. Regeln: – SCHLÜSSEL UNVERÄNDERT LASSEN. – Alle Platzhalter exakt beibehalten: %{var}, %s, %d, {0}, ~r~, ~g~, ^1, ^2 usw. – Groß- und Kleinschreibung sowie Code-Stil-Token (Befehle, /Slash-Befehle) unverändert lassen. – Keine Anführungszeichen oder zusätzliche Satzzeichen hinzufügen oder Bedeutungen ändern. – NUR gültiges JSON mit derselben Struktur zurückgeben. Zu übersetzendes JSON:
Reguläre Ausdrücke, die Sie in einem QA-Skript verwenden können
- Platzhalter:
%%\{[A-Za-z0-9_]+\} - C printf:
%(?:\d+\$)?[sdif] - Chat-Codes:
\^\d - Tilde-Farbcodes:
~[rgbso]~
Beispiel: Übersetzen mit DeepL (Node.js)
Funktioniert hervorragend für einmalige Aufträge oder CI.
package.json (Skripte)
{ "type": "module", "scripts": { "i18n:translate:de": "node tools/translate-deepl.js en de", "i18n:check": "node tools/i18n-check.js" } }
tools/translate-deepl.js
fs von „fs“ importieren; Pfad von „Pfad“ importieren; Assert von „Assert“ importieren; Fetch von „Node-Fetch“ importieren; const [,, srcLang, dstLang] = process.argv; const apiKey = process.env.DEEPL_API_KEY; // in CI/ENV festlegen assert(apiKey, „DEEPL_API_KEY ist erforderlich“); const src = JSON.parse(fs.readFileSync(„locales/en.json“, „utf8“)); const out = {}; const GLOSSARY = { „EMS“: „Rettungsdienst“, „PD“: „Polizei“, }; function protect(str){ // Platzhalter durch Token ersetzen, die DeepL nicht ändern wird return str .replace(/%\{([^}]+)\}/g, '⟦$1⟧') .replace(/%s/g, '⟪S⟫') .replace(/%d/g, '⟪D⟫'); } function restore(str){ return str .replace(/⟦([^⟧]+)⟧/g, '%{$1}') .replace(/⟪S⟫/g, '%s') .replace(/⟪D⟫/g, '%d'); } asynchrone Funktion translate(text){ const res = warte auf fetch('https://api.deepl.com/v2/translate', { Methode: 'POST', Header: { 'Content-Type': 'application/x-www-form-urlencoded' }, Body: neue URLSearchParams({ auth_key: apiKey, Text: Text, Quellsprache: srcLang.toUpperCase(), Zielsprache: dstLang.toUpperCase(), Formalität: 'prefer_more' }) }); const json = warte auf res.json(); wenn (!json.translations) neuen Fehler auslösen(JSON.stringify(json)); returniere json.translations[0].text; } für (const [k, v] von Object.entries(src)) { const protectedText = protect(v); // Glossar-Vorabpass (einfach): let glossed = protectedText; for (const [from, to] of Object.entries(GLOSSARY)) { glossed = glossed.replace(new RegExp(`\\b${from}\\b`, 'g'), to); } // Übersetzen // eslint-disable-next-line no-await-in-loop const tr = await translate(glossed); out[k] = restore(tr); } fs.writeFileSync(`locales/${dstLang}.json`, JSON.stringify(out, null, 2)); console.log(`Wrote locales/${dstLang}.json`);
tools/i18n-check.js (Platzhalterparität)
importiere fs von 'fs'; const src = JSON.parse(fs.readFileSync('locales/en.json', 'utf8')); const dst = JSON.parse(fs.readFileSync('locales/de.json', 'utf8')); const reVar = /%\{[^}]+\}/g; const reS = /%s/g; const reD = /%d/g; let ok = true; für (const k von Object.keys(src)) { const a = (src[k].match(reVar)||[]).Länge === (dst[k]?.match(reVar)||[]).Länge; const b = (src[k].match(reS)||[]).Länge === (dst[k]?.match(reS)||[]).Länge; const c = (src[k].match(reD)||[]).length === (dst[k]?.match(reD)||[]).length; if (!(a && b && c)) { console.error('Platzhalter-Fehlanpassung für Schlüssel:', k); ok = false; } } process.exit(ok ? 0 : 1);
LLMs (OpenAI/andere) effektiv nutzen
- Chunk nach Thema/Domäne für einen besseren Kontext (z. B. Inventar, Polizei, Jobs).
- Bieten Kurzbeschreibungen pro Gruppe (zwei Zeilen), um Ton und Publikum zu definieren.
- Beispiele mit wenigen Aufnahmen: 2–3 korrekt übersetzte Paare mit Platzhaltern verbessern die Konsistenz.
- Wiederholungsrichtlinie: Führen Sie nur fehlerhafte Schlüssel erneut aus, die gekennzeichnet sind durch
i18n-Prüfung.
Few‑Shot-Vorlage (System + Benutzer)
System: Sie übersetzen FiveM-Spiel-UI-Strings für . - Schlüssel unverändert lassen, Platzhalter beibehalten, Ton prägnant halten. Benutzerbeispiele: EN: "You have %{count} fines." DE: "Du hast %{count} Strafzettel." EN: "~r~Error:~s~ You lack permission." DE: "~r~Fehler:~s~ Dir fehlt die Berechtigung." Übersetzen Sie nun die folgenden JSON-Werte von Englisch in . Nur gültiges JSON zurückgeben:
NUI (HTML/JS)-Übersetzungen
Für Browser-Benutzeroberflächen ist eine clientseitige Bibliothek praktisch.
Empfohlene Vorgehensweise
- Verwenden Sie ein JSON-Bundle pro Sprache in
web/locales/ .json. - Laden Sie mit Ihrem UI-Framework und stellen Sie eine
t(Schlüssel, Variablen)Helfer. - Behalten Sie die gleiche Schlüssel als Server-Gebietsschemas, um die kognitive Belastung zu reduzieren.
Minimaler JS-Helfer
const dict = warte (warte auf fetch(`/locales/${lang}.json`)).json(); Exportfunktion t(Schlüssel, Variablen){ lass s = dict[Schlüssel] || Schlüssel; für (const [k,v] von Object.entries(Variablen||{})) s = s.replace(`%{${k}}`, v); return s; }
ESX/QBCore-Besonderheiten
- Viele ESX-Skripte werden mitgeliefert
locales/en.lua,locales/de.luamit einem_UHelfer. - Wenn Sie Lua-Tabellen für Gebietsschemata verwenden, behalten Sie ein Stil in Ihrem gesamten Repo. Das Mischen von JSON und Lua für dieselbe Ressource erhöht die Wartungskosten.
- QBCore verwendet häufig konfigurationsgesteuerte Nachrichten. Migrieren Sie wiederholte Zeichenfolgen in Gebietsschemadateien, um Abweichungen zu vermeiden.
Lua-Tabellengebietsschema (wenn Sie Lua gegenüber JSON bevorzugen)
Locales = Locales oder {} Locales['en'] = { no_permission = 'Sie haben keine Berechtigung.', Welcome_player = 'Willkommen, %{name}!' } Locales['de'] = { no_permission = 'Du hast keine Berechtigung.', Welcome_player = 'Willkommen, %{name}!' }
Qualitätskontrollen vor dem Versand
- JSON/Lua-Analyseprüfung im CI.
- Platzhalterparität (Regex-Prüfungen wie gezeigt).
- Verbotene Änderungen: Änderungen an nicht zulassen
/Befehle, Tastenbelegungsbuchstaben, Farb-/Chatcodes. - Längendeltas: Flag +40%-Wachstum für UI-Schaltflächen; kann das Layout beschädigen.
- Rauchtest: Starten Sie Ihren Server und überprüfen Sie kritische Abläufe stichprobenartig.
Sie haben noch keine Erfahrung mit der Einrichtung eines Testservers? Folgen Sie diesem Einstieg: So erstellen Sie einen FiveM-Server.
Wartungsstrategie
- Behandeln
en.jsonals Quelle der Wahrheit; Erstellen Sie einen CI-Job, der sich unterscheideten.jsonund aktualisiert nur geänderte Schlüssel in Zielen. - Behalten Sie eine
CHANGELOG.i18n.mdfür Übersetzer. - Ermutigen Sie die Community, über PRs Beiträge zu leisten. Dokumentieren Sie Ihre Stilhandbuch Und Glossar In
/docs/i18n.md.
Häufige Fallstricke (und Lösungen)
- Defekte Platzhalter → Verwenden Sie automatisierte Prüfungen und Schutztoken.
- Inkonsistente Terminologie → Pflegen Sie ein Glossar und setzen Sie es in Eingabeaufforderungen und der Vorverarbeitung durch.
- Gemischte Gebietsschemas im Code → CI fehlschlagen, wenn Zeichenfolgen außerhalb erkannt werden
Gebietsschemas/. - RTL-Sprachen → Stellen Sie sicher, dass Ihre NUI CSS-Sets
Regie: rtl;und verwendet Schriftarten mit RTL-Unterstützung. - Abweichungen bei Groß- und Kleinschreibung und Zeichensetzung → Geben Sie der KI explizite Anweisungen und führen Sie einen Linter aus, um die Zeichensetzung zu normalisieren.
Externe Ressourcen
- DeepL-API — Entwicklerdokumente: https://www.deepl.com/docs-api
- Google Cloud-Übersetzung — Dokumente und bewährte Methoden: https://cloud.google.com/translate/docs
- FiveM-Ressourcenmanifest (fxmanifest.lua) - Referenz: https://docs.fivem.net/docs/scripting-reference/resource-manifest/resource-manifest/
Interne Ressourcen (weiterführende Literatur)
- So übersetzen Sie FiveM-Skripte (richtig) — Arbeitsablauf und Muster: https://fivemx.com/fivem-scripts-translation/
- So erstellen Sie einen FiveM-Server — Richten Sie ein Testbett für die Qualitätssicherung ein: https://fivemx.com/how-to-create-a-fivem-server/
Checklisten kopieren und einfügen
Vorübersetzung
- Alle Saiten zentralisiert in
locales/en.json(oder Lua-Tabelle) - Schlüssel folgen einer Namenskonvention
- Glossar erstellt
- Platzhalter geprüft
Laufen
- Stapelübersetzung mit Glossar
- Ausgabe speichern unter
Gebietsschemas/ .json
Qualitätssicherung
- JSON/Lua gültig
- Platzhalterparität OK
- Verbotene Token unverändert
- Längendeltas akzeptabel
- Menschliche Stichprobenkontrolle durchgeführt
Schiff
- CI grün
- Änderungsprotokoll aktualisiert
- Community-Feedback einholen






