Coupon WELCOME disponibile Usa il codice WELCOME al checkout entro il 31 luglio 2026. WELCOME

Come tradurre gli script utilizzando l'intelligenza artificiale (guida FiveM)

Testare uno script gratuito?

Gli script gratuiti vanno bene per controlli rapidi. Per server in produzione, confronta pacchetti server completi o script a pagamento mantenuti, in base al framework e al caso d'uso.

Pubblico: Proprietari di server FiveM, programmatori e manutentori che desiderano traduzioni di alta qualità senza danneggiare segnaposto o interfaccia utente.


In breve

  • Centralizzare tutto il testo nei file locali (tabelle JSON o Lua). Non codificare mai le stringhe nella logica di gioco.
  • Proteggi i segnaposto (ad esempio, %s, %d, %{nome}, {0}, ~r~, ^1) durante la traduzione.
  • Utilizzare l'intelligenza artificiale per la traduzione di prima passata + glossario + controlli automatici → rapida revisione umana → spedizione.
  • Mantieni un'unica fonte di verità (solitamente l'inglese), diff per le modifiche e rigenera solo le chiavi modificate.

Perché tradurre i tuoi script FiveM

  • Accessibilità e crescita: I server localizzati attraggono più giocatori e li mantengono coinvolti.
  • Professionalità: Terminologia coerente tra comandi, interfacce utente e messaggi di errore.
  • Adatto ai collaboratori: Una struttura locale chiara incoraggia le relazioni pubbliche della comunità.

Se hai bisogno di un ripasso di base sulla struttura e sulle migliori pratiche, consulta: Come tradurre gli script FiveM (nel modo giusto).


Architettura: il modo giusto per localizzare

Obiettivo: Nessuna stringa visibile all'utente all'interno del codice di gioco. Instrada tutto attraverso un livello locale.

Disposizione delle risorse consigliata

my_resource/ ├─ fxmanifest.lua ├─ locales/ │ ├─ en.json # lingua sorgente (unica fonte di verità) │ ├─ de.json # tradotto (generato/modificato) │ ├─ es.json # tradotto (generato/modificato) │ └─ qa.rules.json # facoltativo: segnaposto whitelist e controlli ├─ client/ │ └─ main.lua ├─ server/ │ └─ main.lua └─ shared/ └─ i18n.lua # assistente di traduzione

fxmanifest.lua (esempio minimo)

fx_version 'cerulean' gioco 'gta5' lua54 'yes' shared_scripts { 'shared/i18n.lua', } file { 'locales/*.json' }

condiviso/i18n.lua (caricatore leggero + sostituzione segnaposto)

LOCALE locale = GetConvar('my_locale', 'en') CACHE locale = {} funzione locale loadJSON(percorso) file locale = io.open(percorso, 'r') se non è un file allora restituisci {} fine contenuto locale = file:read('*a') file:close() ok locale, dati = pcall(function() return json.decode(contenuto) fine) restituisci ok e dati o {} fine funzione locale readLocale(lang) se CACHE[lang] allora restituisci CACHE[lang] fine file locale = ('locales/%s.json'):format(lang) dizionario locale = loadJSON(file) CACHE[lang] = dizionario restituisci dizionario fine funzione locale interpolate(str, vars) se non è un file allora restituisci str fine per k, v in coppie(vars) fai str = str:gsub('%%{'..k..'}', tostring(v)) -- %{name} fine ritorno str fine funzione _U(key, vars) local dict = readLocale(LOCALE) local src = dict[key] se non è src allora -- fallback all'inglese se manca src = readLocale('en')[key] o key fine ritorno interpolate(src, vars) fine exports('Translate', _U)

Utilizzo nel codice client/server

-- Client lib.notify({ title = _U('notify_title'), description = _U('welcome_player', { name = GetPlayerName(PlayerId()) }), }) -- Server print(('[MyRes] %s'):format(_U('server_started')))

locales/en.json (fonte)

{ "notify_title": "Messaggio del server", "welcome_player": "Benvenuto, %{name}!", "server_started": "Il modulo server è pronto.", "no_permission": "Non hai l'autorizzazione.", "items_remaining": "%{count} elementi rimanenti" }

Flusso di lavoro di traduzione AI (veloce e sicuro)

  1. Estrai e congela la fonte
  • Mantenere Inglese (o la tua fonte) come locales/en.json.
  • Applicare la denominazione delle chiavi: dominio.azione.soggetto (per esempio, inventario.rilascia.conferma).
  1. Creare/estendere un glossario
  • Mappa CSV o JSON dei termini canonici → termini di destinazione. Esempio:
fonte,bersaglio EMS,Rettungsdienst PD,Polizei Mechanic,Mechaniker

  1. Proteggi segnaposto e markup
  • Segnaposto: %{nome}, %s, %d, {0}
  • Codici colore FiveM: ~r~, ~g~, ~s~; codici chat: ^1, ^2
  • Tag NUI/HTML: <b>, <span>
  1. Traduci tramite API (lotto)
  • Inviare valori solo, mantieni chiavi invariato.
  • Fornitura glossario E stile (tono) al modello/motore.
  1. Controllo qualità automatizzato
  • Convalida JSON.
  • Verificare parità segnaposto (ogni segnaposto nella sorgente esiste anche nella destinazione).
  • Segnala le modifiche vietate (ad esempio, codici colore modificati o punteggiatura aggiunta quando non consentita).
  1. Controllo a campione umano (5–10 minuti)
  • Esaminare i comandi, i messaggi di errore e le stringhe lunghe dell'interfaccia utente.
  1. Spedire e ripetere
  • Mantieni un memoria di traduzione (output precedenti) per evitare di ritradurre le chiavi non modificate.

Guardrail: suggerimenti e regole che funzionano davvero

Richiesta LLM per la traduzione batch JSON

Attività: tradurre i valori JSON dall'inglese all'inglese per un contesto FiveM/GTA RP. Regole: - MANTENERE LE CHIAVI INVARIATE. - MANTENERE tutti i segnaposto esattamente: %{var}, %s, %d, {0}, ~r~, ~g~, ^1, ^2, ecc. - Mantenere invariate le maiuscole e i token di stile del codice (comandi, comandi /slash). - Non aggiungere virgolette, punteggiatura aggiuntiva o modificare il significato. - Restituire SOLO JSON valido con la stessa struttura. JSON da tradurre:

Espressione regolare che puoi usare in uno script QA

  • Segnaposto: %%\{[A-Za-z0-9_]+\}
  • C printf: %(?:\d+\$)?[sdif]
  • Codici chat: \^\d
  • Codici colore tilde: ~[rgbso]~

Esempio: tradurre con DeepL (Node.js)

Ideale per lavori una tantum o CI.

package.json (script)

{ "type": "module", "scripts": { "i18n:translate:de": "node tools/translate-deepl.js en de", "i18n:check": "node tools/i18n-check.js" } }

strumenti/traduci-deepl.js

importa fs da 'fs'; importa percorso da 'percorso'; importa assert da 'assert'; importa fetch da 'node-fetch'; const [,, srcLang, dstLang] = process.argv; const apiKey = process.env.DEEPL_API_KEY; // impostato in CI/ENV assert(apiKey, 'DEEPL_API_KEY è obbligatorio'); const src = JSON.parse(fs.readFileSync('locales/en.json', 'utf8')); const out = {}; const GLOSSARIO = { 'EMS': 'Servizio di soccorso', 'PD': 'Polizia', }; function protect(str){ // Sostituisci i segnaposto con i token che DeepL non modificherà 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'); } funzione asincrona translate(testo){ const res = await fetch('https://api.deepl.com/v2/translate', { metodo: 'POST', intestazioni: { 'Content-Type': 'application/x-www-form-urlencoded' }, corpo: new URLSearchParams({ auth_key: apiKey, testo: testo, source_lang: srcLang.toUpperCase(), target_lang: dstLang.toUpperCase(), formalità: 'prefer_more' }) }); const json = await res.json(); if (!json.translations) throw new Error(JSON.stringify(json)); return json.translations[0].text; } for (const [k, v] of Object.entries(src)) { const protectedText = protect(v); // Pre-passaggio al glossario (semplice): let glossed = protectedText; for (const [from, to] of Object.entries(GLOSSARY)) { glossed = glossed.replace(new RegExp(`\\b${from}\\b`, 'g'), to); } // Traduci // 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(`Ha scritto locales/${dstLang}.json`);

strumenti/i18n-check.js (parità segnaposto)

importa fs da '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; lascia ok = vero; per (const k di Object.keys(src)) { const a = (src[k].match(reVar)||[]).length === (dst[k]?.match(reVar)||[]).length; const b = (src[k].match(reS)||[]).length === (dst[k]?.match(reS)||[]).length; const c = (src[k].match(reD)||[]).length === (dst[k]?.match(reD)||[]).length; if (!(a && b && c)) { console.error('Segnaposto non corrispondente per la chiave:', k); ok = false; } } process.exit(ok ? 0 : 1);

Utilizzo efficace degli LLM (OpenAI/altri)

  • Suddividi per argomento/dominio per un contesto migliore (ad esempio, inventario, polizia, posti di lavoro).
  • Fornire brevi descrizioni per gruppo (due righe) per definire il tono e il pubblico.
  • Pochi esempi sparati: 2–3 coppie tradotte correttamente con segnaposto migliorano la coerenza.
  • Politica di ripetizione: rieseguire solo le chiavi non riuscite contrassegnate da i18n-controllo.

Modello di pochi scatti (sistema + utente)

Sistema: traduci le stringhe dell'interfaccia utente del gioco FiveM per . - Mantieni le chiavi invariate, conserva i segnaposto, mantieni il tono conciso. Esempi utente: EN: "Hai %{count} multe." DE: "Hai ricevuto %{count} multe." EN: "~r~Errore:~s~ Non hai l'autorizzazione." DE: "~r~Errore:~s~ Hai ricevuto l'autorizzazione." Ora traduci i seguenti valori JSON dall'inglese a Restituisce solo JSON valido:

Traduzioni NUI (HTML/JS)

Per le interfacce utente dei browser, una libreria lato client è pratica.

Approccio consigliato

  • Utilizzare un bundle JSON per lingua in web/locali/ .json.
  • Carica con il tuo framework UI ed esponi un t(chiave, variabili) aiutante.
  • Mantieni il stesse chiavi come impostazioni locali del server per ridurre il carico cognitivo.

Helper JS minimo

const dict = await (await fetch(`/locales/${lang}.json`)).json(); export function t(key, vars){ let s = dict[key] || key; for (const [k,v] of Object.entries(vars||{})) s = s.replace(`%{${k}}`, v); return s; }

Specifiche ESX/QBCore

  • Molti script ESX vengono spediti locales/en.lua, locales/de.lua con un _U aiutante.
  • Se si utilizzano tabelle Lua per le impostazioni locali, mantenere uno stile nel tuo repository. Combinare JSON e Lua per la stessa risorsa aumenta i costi di manutenzione.
  • QBCore utilizza spesso messaggi basati sulla configurazione. Migra le stringhe ripetute nei file locali per evitare divergenze.

Impostazioni locali della tabella Lua (se preferisci Lua a JSON)

Locales = Locales or {} Locales['en'] = { no_permission = 'Non hai i permessi.', Welcome_player = 'Benvenuto, %{name}!' } Locales['de'] = { no_permission = 'Du hast keine Berechtigung.', Welcome_player = 'Willkommen, %{name}!' }

Controlli di qualità prima della spedizione

  • Controllo di analisi JSON/Lua in CI.
  • Parità segnaposto (le espressioni regolari verificano come mostrato).
  • Modifiche vietate: non consentire modifiche a /comandi, lettere di scelta rapida, codici colore/chat.
  • Delta di lunghezza: flag +40% crescita per i pulsanti dell'interfaccia utente; potrebbe danneggiare il layout.
  • Prova del fumo: avvia il tuo server e controlla a campione i flussi critici.

Non hai mai configurato un server per i test? Segui questo tutorial: Come creare un server FiveM.


Strategia di manutenzione

  • Trattare en.json COME fonte di verità; crea un lavoro CI che differisce en.json e aggiorna solo le chiavi modificate nei target.
  • Mantieni un CHANGELOG.i18n.md per i traduttori.
  • Incoraggia la comunità a contribuire tramite PR; documenta il tuo guida di stile E glossario In /docs/i18n.md.

Errori comuni (e soluzioni)

  • Segnaposto non funzionanti → Utilizzare controlli automatizzati e token di protezione.
  • Terminologia incoerente → Mantenere un glossario e applicarlo nei prompt e nella pre-elaborazione.
  • Locali misti nel codice → Fallimento CI se le stringhe vengono rilevate all'esterno locali/.
  • lingue RTL → Assicurati che i tuoi set CSS NUI direzione: rtl; e utilizza font con supporto RTL.
  • Deriva di maiuscole e minuscole e punteggiatura → Istruire l'IA in modo esplicito ed eseguire un linter per normalizzare la punteggiatura.

Risorse esterne



Copia e incolla le checklist

Pre-traduzione

  • Tutte le stringhe centralizzate in locales/en.json (o tabella Lua)
  • Le chiavi seguono una convenzione di denominazione
  • Glossario preparato
  • Segnaposto controllati

Correre

  • Traduci in batch con glossario
  • Salva l'output in locali/ .json

Controllo qualità

  • JSON/Lua valido
  • Parità segnaposto OK
  • I token proibiti non cambiano
  • Delta di lunghezza accettabili
  • Controllo umano a campione effettuato

Nave

  • CI verde
  • Changelog aggiornato
  • Invita la comunità a inviare feedback
Luca
Luca

Mi chiamo Luke, sono un giocatore e amo scrivere di FiveM, GTA e giochi di ruolo. Gestisco una community di gioco di ruolo e ho circa 10 anni di esperienza nell'amministrazione di server.

Articoli: 436