Skip to Content
ScriptingState Bags (Networking)

State Bags (Networking)

State Bags (or Entity State) are a modern networking feature in FiveM (requires OneSync) that allows you to store arbitrary key-value pairs on entities (players, vehicles, peds, objects) or globally. These values are automatically synchronized between the server and relevant clients.

They replace many traditional TriggerClientEvent patterns for syncing data like “is player handcuffed”, “vehicle fuel level”, or “job duty status”.

Why use State Bags?

  • Automatic Sync: No need to manually trigger events when a player connects or comes into range. The state is “just there”.
  • Bandwidth Efficient: Only sends updates when data changes.
  • Persistent: Data stays on the entity as long as the entity exists.
  • Server-Authoritative: You can secure states so clients cannot modify them.

Basic Syntax

State bags are accessed via the .state property on an entity.

Setting State (Server Side)

-- Set a value on a vehicle local vehicle = GetVehiclePedIsIn(GetPlayerPed(source), false) local ent = Entity(vehicle) -- Set 'fuel' to 100. -- The 'true' argument enables replication to clients. ent.state:set('fuel', 100, true) -- Set a value on a player local playerEnt = Entity(GetPlayerPed(source)) playerEnt.state:set('isHandcuffed', true, true)

Reading State (Client & Server)

local vehicle = GetVehiclePedIsIn(PlayerPedId(), false) local ent = Entity(vehicle) -- Access directly like a table local fuel = ent.state.fuel if fuel then print("Current fuel:", fuel) end

Global State

GlobalState is a special state bag that is not attached to any specific entity but is available everywhere. It’s perfect for server-wide variables like “weather”, “server announcement”, or “event active”.

-- Server: Set global state GlobalState.weather = "EXTRASUNNY" -- Client: Read global state print("Current weather:", GlobalState.weather)

State Change Handlers

You can listen for changes to state bags using AddStateBagChangeHandler. This is useful for triggering visual effects or logic when a value changes.

-- Client Side: Listen for 'isHandcuffed' changes on any player AddStateBagChangeHandler('isHandcuffed', nil, function(bagName, key, value, _reserved, replicated) -- bagName format: "entity:12345" or "player:1" local entity = GetEntityFromStateBagName(bagName) -- Verify the entity exists and is a player if entity == 0 then return end if value == true then -- Apply handcuff animation print("Player handcuffed!") else -- Remove animation print("Player released!") end end)

Replication and Security

When setting a state bag value, the third argument controls replication:

-- replicated: true = sends to clients -- replicated: false = stays on server only entity.state:set('secretKey', '12345', false)

Local vs. Replicated

  • Server: Can set replicated state (visible to clients) or local state (server only).
  • Client: By default, clients can only set local state (visible to themselves). They cannot replicate state to the server or other players unless the server allows it.

To allow a client to replicate a specific state key, use SetResourceKvp policy (advanced) or trust the client to trigger a server event to change the state. Best Practice: Always have the server set important game states.

Player State (PlayerState)

For player entities, you can access state via the player’s server ID.

-- Server Side local playerState = Player(source).state playerState.job = "police" -- Client Side local myState = LocalPlayer.state print(myState.job) -- prints "police"

Best Practices

  1. Don’t Overuse: State bags are for state (persistent data). Don’t use them for fleeting events (like playing a sound once). Use standard Events for that.
  2. Use Namespaces: Prefix your keys to avoid collisions with other resources (e.g., myScript:fuel instead of just fuel).
  3. Security: Never trust client-set state for critical logic (money, permission, etc.).

Summary Table

FeatureSyntax
Get EntityEntity(entityHandle)
Get PlayerPlayer(serverId)
Get Local PlayerLocalPlayer
Set Stateent.state:set(key, value, replicated)
Get Stateent.state.key
Global StateGlobalState.key
Listen for ChangeAddStateBagChangeHandler(...)
Last updated on