Ottimizzazione di inventario e peso: da items.lua ai metadati

Ottimizzazione di inventario e peso: da items.lua ai metadati

In breve: Questa guida fornisce preset di peso/slot pronti per la produzione, tabelle di budget degli articoli, copia-incolla items.lua definizioni (ESX/QBCore/ox_inventory) e strategie di migrazione sicura tra inventari popolari. Utilizzalo per eliminare il problema del sovraffollamento, fermare il sovraffollamento degli articoli e mantenere la coerenza della tua economia.


Perché è importante ottimizzare l'inventario

Un'economia RP stabile si basa su scarsità, attrito e scelte significative. Le regole di inventario (slot, peso, limiti di stack, metadati come durata/numeri di serie) sono le leve che rendono concrete queste scelte. Se tutti possono portare tutto, i prezzi crollano e i loop si interrompono. Regola prima l'inventario, poi itera prezzi, pagamenti e sink. Per un'economia più ampia, consulta il nostro pilastro: Progettare un'economia equilibrata per GTA RP: prezzi, pozzi, progressione.


Modelli: Slot vs. Peso vs. Ibrido

Solo slot

  • Modello cognitivo semplice; ogni elemento = 1 slot o definito da classi di dimensioni.
  • Scarso nel distinguere tra pile pesanti e leggere; sfrutta molti piccoli oggetti di alto valore.

Solo peso

  • Ogni oggetto ha un peso (solitamente grammi). I giocatori hanno maxWeight per contenitore. Forte realismo; necessita di impostazioni predefinite ponderate.

Ibrido (raccomandato)

  • Limite di peso globale E Limite di slot. Previene gli exploit sia per i micro-oggetti che per i mega-oggetti. Funziona meglio per il RP.

Mancia: Mantieni i numeri leggibili dall'uomo. Se modelli in grammi, usa numeri interi (ad esempio, water = 500g) e cappellini rotondi per giocatori (ad esempio, maxWeight = 120,000).


Predefiniti (copia e adatta)

Di seguito sono riportati punti di partenza collaudati in battagliaRegolare ±10–20% dopo una settimana di telemetria in città.

Inventario del giocatore (di persona)

Scala del serverModelloPeso massimo (g)SlotNote
Nuovo/Piccolo (≤40 pop)Ibrido80,00030Onboarding più rapido; meno punti critici iniziali.
Medio (40–150)Ibrido120,00035Adatto per giochi di ruolo generici; adatto a lavori diversi.
High-Pop (150+)Ibrido150,00032Ridurre le fasce orarie per limitare l'accumulo compulsivo; mantenere un peso equo.

Veicoli (valori predefiniti comuni)

ContenitorePeso massimo (g)SlotMotivazione
Cassetto portaoggetti10,0005Piccola scorta, incoraggia la pianificazione.
Baule delle berline80,00020Linea di base.
SUV/furgone con bagagliaio120,00025I veicoli utilitari diventano significativi.
Camion (utilitaria)180,00028Gameplay logistico.
Deposito motociclette8,0003Minimo intasamento.

Nascondigli e contenitori speciali

TipoPeso massimo (g)SlotNote
Nascondiglio della casa (livello 1/2/3)120k / 180k / 240k40 / 60 / 80Incentiva i miglioramenti degli alloggi.
Armadietto di lavoro80,00020Prevenire gli exploit di riporto.
Armadietto delle prove240,000120Comodità per amministratori/LEO; richiesta la registrazione degli audit.

Budget del peso degli articoli (per classe)

Usalo per assegnare pesi coerenti. Pensa attrito relativo non realismo.

ClasseEsempiPeso consigliato (g)
Molto leggeroLama per grimaldello, USB, SIM5–50
LeggeroMunizioni per pistola (10), benda, spuntino100–250
MedioBottiglia d'acqua, hamburger, kit di riparazione400–800
PesanteScatola di munizioni per fucile (30), serbatoio ossigeno, cassa di materiale1.500–4.000
Molto pesanteCassa di armi, borsa di denaro (contrassegnata)6.000–12.000

Munizioni: Bilancio per unità per stack in pool (ad esempio, 9mm = 15g ciascuno → 30 round ≈ 450 g) o rappresentare come scatole (ad esempio, 9mm box (30) = 500g).


Dimensioni dello stack e strategia degli slot

  • Materie prime (cibo, medicine): impilare da 5 a 20 per ridurre la noia.
  • Munizioni: impilare 30–60 per le pistole; 60–120 per i fucili quando imballati.
  • Tappetini da lavoro: impilare 100–250; mantenere un peso significativo.
  • Armi: stack = 1, metadati univoci (seriale, durabilità).

Modelli di metadati (durata, seriali, allegati, qualità)

Progetta i metadati come un piccolo schema. Mantieni i campi minimi, tipizzati e convalidati.

Schema dei metadati canonici (raccomandazione)

{
 "serial": "string", // weapon unique id
 "owner": "citizenid|identifier",
 "durability": 0.0, // 0.0–1.0; decay per use/time
 "quality": 100, // 0–100; repairable threshold 25
 "ammo": 0, // integer; weapon mags
 "tint": 0, // integer (game tint index)
 "attachments": ["flashlight", "scope"],
 "expiry": 0, // unix timestamp; perishable items
 "notes": "" // small text; avoid bloat
}

Durata e decadimento

  • Armi: decadimento 0,5–1,5% per caricatore; probabilità di inceppamento <5% al di sotto della qualità 20%.
  • Utensili (grimaldelli, trapano): consumano % all'uso; si rompono a 0.
  • Prodotti deperibili: expiry controllo all'uso; penalità o blocco.

Sicurezza e prestazioni

  • Convalida i metadati lato server; non fidarti mai delle scritture client.
  • Limita le dimensioni dei metadati (ad esempio, <512 byte). I blob di grandi dimensioni danneggiano i payload di salvataggio/caricamento e di rete.
  • Utilizzare enumerazioni per allegati e tinte.

Esempio ESX (es_extended)

-- esx items.lua (example) — weight in grams; negative weight means not counted in legacy modes
['water'] = { label = 'Water Bottle', weight = 500, stack = true, close = true, description = 'Stay hydrated.' },
['bandage'] = { label = 'Bandage', weight = 150, stack = true, close = true },
['lockpick'] = { label = 'Lockpick', weight = 50, stack = true, close = true },
['pistol_ammo'] = { label = 'Pistol Ammo (30)', weight = 450, stack = true, close = true, description = '9mm, box of 30.' },
['weapon_pistol'] = { label = 'Pistol', weight = 1500, stack = false, close = true, degrade = 0.01, unique = true },

Per le varianti ESX che utilizzano ancora limite invece di peso, impostato limit = -1 (illimitato) e cambia il saldo economico tramite il peso a livello globale.

QBCore (shared/items.lua) esempio

-- qb-core shared/items.lua
['water'] = { name = 'water', label = 'Water Bottle', weight = 500, type = 'item', image = 'water.png', unique = false, useable = true, shouldClose = true, description = 'Stay hydrated.',
 combinable = nil },
['bandage'] = { name = 'bandage', label = 'Bandage', weight = 150, type = 'item', image = 'bandage.png', unique = false, useable = true, shouldClose = true },
['lockpick'] = { name = 'lockpick', label = 'Lockpick', weight = 50, type = 'item', image = 'lockpick.png', unique = false, useable = true, shouldClose = true },
['pistol_ammo'] = { name = 'pistol_ammo', label = 'Pistol Ammo (30)', weight = 450, type = 'item', image = 'pistol_ammo.png', unique = false, useable = true, shouldClose = true },
['weapon_pistol'] = { name = 'weapon_pistol', label = 'Pistol', weight = 1500, type = 'weapon', image = 'weapon_pistol.png', unique = true, useable = false, shouldClose = true,
 info = { serial = '', durability = 1.0, ammo = 12, attachments = {} } },

inventario_ox (data/items.lua) esempio

return {
 water = {
 label = 'Water Bottle',
 weight = 500,
 stack = true,
 client = { status = { thirst = 25000 }, anim = { dict = 'mp_player_intdrink', clip = 'loop_bottle' } },
 },
 bandage = { label = 'Bandage', weight = 150, stack = true },
 lockpick = { label = 'Lockpick', weight = 50, stack = true },
 pistol_ammo = { label = 'Pistol Ammo (30)', weight = 450, stack = true },
 weapon_pistol = {
 label = 'Pistol', weight = 1500, stack = false, allowArmed = true,
 consume = 0, -- handled by durability system
 ammo = { type = 'AMMO_PISTOL', count = 12 },
 metadata = { serial = true, durability = true, attachments = true },
 },
}

inventario_di_bue supporta ricchi client/server comportamenti nelle definizioni degli elementi: preferire gli script integrati rispetto a quelli ad hoc per standardizzare il comportamento.


Configurazione del contenitore QBCore (esempio)

-- qb-inventory/server/config.lua (illustrative)
Config.PlayerMaxWeight = 120000
Config.PlayerMaxSlots = 35
Config.Vehicle = {
 glovebox = { weight = 10000, slots = 5 },
 trunk = function(class)
 if class == 'sedan' then return 80000, 20 end
 if class == 'suv' or class == 'van' then return 120000, 25 end
 if class == 'truck' then return 180000, 28 end
 return 60000, 18
 end
}

configurazione della scorta ox_inventory (esempio)

-- ox_inventory/server/custom/stashes.lua
lib.addstash('house_tier1', 40, 120000)
lib.addstash('house_tier2', 60, 180000)
lib.addstash('house_tier3', 80, 240000)

Manuali di migrazione (sicuri e reversibili)

Principi

  1. Eseguire prima lo snapshot del DB. 2) Migrare elementi/metadati con script idempotenti. 3) Eseguire l'operazione in parallelo in un server di staging. 4) Fornire il rollback SQL.

UN) qb-inventoryox_inventory

Campi della mappa

  • QB items.luaox data/items.lua (name, label, weight, stack/unique, client/server behaviors).
  • player inventory tabella: convertire info JSON → metadata (numero di serie, durata, munizioni).

Pseudocodice (mix Lua/SQL)

-- 1) Export QB items to a Lua table/JSON
-- 2) Generate ox items.lua entries
-- 3) Transform inventories
for item in qb_inventory_rows do
 local meta = json.decode(item.info or '{}')
 local metadata = {
 serial = meta.serial,
 durability = meta.durability or 1.0,
 ammo = meta.ammo or 0,
 attachments = meta.attachments or {},
 }
 insert_into_ox_inventory(item.name, item.amount, metadata)
end

Esempio SQL (stile PostgreSQL/MySQL)

-- Backup
CREATE TABLE backup_playeritems AS SELECT * FROM playeritems;

-- Transform example for a single item family
UPDATE playeritems
SET metadata = JSON_OBJECT(
 'serial', JSON_EXTRACT(info, '$.serial'),
 'durability', COALESCE(JSON_EXTRACT(info, '$.durability'), 1.0),
 'ammo', COALESCE(JSON_EXTRACT(info, '$.ammo'), 0),
 'attachments', COALESCE(JSON_EXTRACT(info, '$.attachments'), JSON_ARRAY())
)
WHERE name IN ('weapon_pistol','weapon_pistol_mk2');

Gotchas

  • Oggetti unici: far rispettare stack = false; assicurarsi che i duplicati non vengano uniti.
  • Sistemi di munizioni: conciliare le convenzioni delle munizioni in scatola con quelle sfuse.
  • Immagini/icone: riassegna il percorso delle immagini degli elementi in modo che corrispondano alla denominazione di ox.

B) ESX (basato sui limiti) → modello di peso

  1. Imposta globale useWeight = true nella configurazione (varia a seconda del fork).
  2. Sostituisci per articolo limit con weight (g). Per gli articoli precedentemente limit = -1, assegnare pesi realistici.
  3. Spostare di conseguenza i tappi dei nascondigli/veicoli.

Passaggio con script

for name, item in pairs(Items) do
 if item.limit and not item.weight then
 item.weight = estimateWeightFromClass(name)
 item.limit = nil
 end
end

C) qs-inventory / lj-inventory → QBCore/ox

  • La mappatura del campo è simile a QB: infometadata.
  • Fai attenzione alle chiavi personalizzate (quality, image, createdAt). Normalizzare allo schema canonico.

Bilanciamento del flusso di lavoro (sprint di 1 settimana)

  1. Giorno 0: Implementare le preimpostazioni; migrare gli elementi nella tabella del budget.
  2. Giorno 1–2: Cattura telemetria: peso medio trasportabile, slot utilizzati, distribuzione degli articoli per lavoro.
  3. Giorno 3: Ridurre i valori anomali (peso +5–10% sui primi 5 articoli accumulati).
  4. Giorno 4–5: Ruoli dei veicoli: potenziare i bagagliai; indebolire l'uso improprio del vano portaoggetti.
  5. Giorno 6: Prodotti deperibili: aggiungi expiry per beni di consumo ad alto margine.
  6. Giorno 7: Pubblica le note sulla patch; imposta una revisione di due settimane.

Telemetria minima

  • % time encumbered, avg slots used, i primi 20 articoli per numero e peso totale, percentili di utilizzo della scorta.

Lista di controllo QA (pronta per la spedizione)

  • Tutti gli articoli hanno weight, stacke etichette chiare.
  • Le armi sono unique/non-stack e includi serial, durability.
  • I contenitori impongono Entrambi peso e slot (ove supportati).
  • Le classi dei veicoli corrispondono a capacità ragionevoli.
  • Nascondigli suddivisi in livelli con progressione.
  • Migrazioni sottoposte a backup; rollback testato.
  • Dimensione dei metadati limitata; convalidata lato server.

Peso Budget CSV (copia in Fogli Google)

name,label,class,weight_g,stack,stack_size
water,Water Bottle,consumable,500,true,10
bandage,Bandage,medical,150,true,5
lockpick,Lockpick,tool,50,true,10
pistol_ammo,Pistol Ammo (30),ammo,450,true,5
weapon_pistol,Pistol,weapon,1500,false,1

Tabella della capacità del veicolo (CSV)

container,weight_g,slots
Glovebox,10000,5
Sedan Trunk,80000,20
SUV/Van Trunk,120000,25
Truck Trunk,180000,28
Motorcycle,8000,3

Errori comuni e soluzioni

  • I giocatori sono sempre gravati → Ridurre il peso dei primi 3 oggetti più diffusi di 15%; aumentare il limite massimo per i giocatori di 10%.
  • Accumulo infinito di micro-oggetti → Introdurre il limite dello slot; impostare il peso minimo dell'articolo (ad esempio, 25 g).
  • Inflazione economica tramite accumulo di scorte → Aggiungi prodotti deperibili expiry, attrito del peso di input di lavorazione o commissioni di deposito.
  • DB bloat → Eliminare le chiavi dei metadati; evitare quelle grandi notes campi.

Prossimi passi

  • Implementa i preset ibridi sopra indicati, quindi ripeti con la telemetria.
  • Allineare l'attrito dell'inventario con i pagamenti e i prezzi: vedere il nostro post sull'economia per modelli di lavandini e progressioni che si abbinano bene a queste impostazioni.

Hai domande su un fork specifico del framework o su un inventario personalizzato? Lascia i dettagli e ti creerò le configurazioni più adatte.