State Bags e Routing Buckets

INFO

Due strumenti avanzati di networking FiveM: i state bags per condividere dati tra entità/giocatori, e i routing buckets per separare lo stato del mondo (instancing).

ObiettivoDettagli
Cosa imparerai• Cosa sono gli state bags
• Usare SetStateBagValue / AddStateBagChangeHandler
• Cosa sono i routing buckets
• Usare SetPlayerRoutingBucket / SetEntityRoutingBucket
Prerequisiti• Eventi e thread (08/02)
• Concetti di networking base

1. Cosa sono i State Bags

Gli state bags sono dati sincronizzati associati a:

  • Un giocatore (player:ID)
  • Un’entità (entity:Handle)
  • Una risorsa (resource:Nome)

Sono la via moderna per condividere stato tra client e server senza eventi manuali — la sincronizzazione è automatica.


2. Impostare un Valore

-- server.lua
-- Stato sul giocatore
SetStateBagValue('player:' .. playerId, 'isDead', true, true)
 
-- Stato su un'entità
SetStateBagValue('entity:' .. entityHandle, 'owner', playerId, true)

NOTE

SetStateBagValue(bagName, key, value, replicate) — replicate true sincronizza anche agli altri client. Il server è la fonte autorevole.


3. Leggere un Valore

-- client.lua o server.lua
local isDead = GetStateBagValue('player:' .. playerId, 'isDead')

4. Ascoltare i Cambiamenti

-- client.lua
AddStateBagChangeHandler('isDead', nil, function(bagName, key, value)
    print(bagName, key, 'cambiato a', value)
end)
 
-- Filtra su un bag specifico (es. solo il tuo giocatore)
AddStateBagChangeHandler('hp', 'player:' .. GetPlayerServerId(PlayerId()), function(bagName, key, value)
    -- aggiorna HUD
end)
ParametroUso
keyNome della chiave (o nil per tutte)
bagNameNome del bag (o nil per tutti)
callbackFunzione eseguita al cambiamento

5. Caso d’uso tipico

-- server.lua
-- Segna un ped come "proprietà" di un giocatore (es. veicolo noleggiato)
RegisterNetEvent('rental:spawn')
AddEventHandler('rental:spawn', function()
    local playerId = source
    local coords = GetEntityCoords(GetPlayerPed(playerId))
    local veh = CreateVehicle(GetHashKey('adder'), coords.x, coords.y, coords.z, 0.0, true, false)
 
    -- Stato sincronizzato: tutti sanno il proprietario
    SetStateBagValue('entity:' .. veh, 'rentalOwner', playerId, true)
end)

6. Cosa sono i Routing Buckets

I routing buckets separano lo stato del gioco: entità e giocatori in bucket diversi non si vedono tra loro. Sono il modo moderno per fare “instancing” (zone separate, dungeon, job instanced).

Bucket 0 (default)      Bucket 1 (instance A)
┌──────────────┐        ┌──────────────┐
│ Giocatore A   │        │ Giocatore C   │
│ Veicolo X     │        │ Veicolo Y     │
└──────────────┘        └──────────────┘
   A NON vede C (bucket diverso)

7. Usare i Buckets

-- server.lua
-- Sposta un giocatore nel bucket 1
SetPlayerRoutingBucket(playerId, 1)
 
-- Sposta un'entità (es. veicolo) nello stesso bucket
SetEntityRoutingBucket(vehicle, 1)
 
-- Riporta nel bucket di default
SetPlayerRoutingBucket(playerId, 0)

WARNING

Un’entità e il suo giocatore devono stare nello stesso bucket, altrimenti il giocatore non la vede. Quando instanzi un giocatore, sposta anche le sue entità.


8. Caso d’uso: Job Instanced

-- server.lua
RegisterNetEvent('job:enterInstance')
AddEventHandler('job:enterInstance', function(instanceId)
    local playerId = source
    local bucket = 100 + instanceId   -- bucket unico per istanza
 
    SetPlayerRoutingBucket(playerId, bucket)
 
    -- Sposta anche il veicolo del giocatore
    local ped = GetPlayerPed(playerId)
    if DoesEntityExist(GetVehiclePedIsIn(ped, false)) then
        SetEntityRoutingBucket(GetVehiclePedIsIn(ped, false), bucket)
    end
 
    -- Teleporta nella zona instanced
    TriggerClientEvent('job:teleportIn', playerId, Config.Instances[instanceId].coords)
end)

9. Best Practice

  • I state bags sono ideali per stato piccolo e letto spesso (hp, isDead, isInCar)
  • Non usare state bags per dati grossi: usa eventi o DB
  • I routing buckets cambiano visibilità: verifica sempre di spostare tutte le entità del giocatore
  • Usa sv_stateBagStrictMode true per impedire ai client di alterare i bag di entità replicate (sicurezza)

Verifica

  • SetStateBagValue con replicate corretto
  • Handler registrati dove servono
  • Bucket coerenti tra giocatore ed entità
  • Nessun dato grosso negli state bags
  • sv_stateBagStrictMode valutato per sicurezza

TIP

Prossimo passo: Modulo Performance e Modulo Sicurezza per approfondire.


Torna alla: Indice Generale