FiveM Modding Tutorial
Disclaimer: Entity state bags are a OneSync feature, if you do not have OneSync they will not work.
With the addition of Entity State Bags back in v2843, there’s now a better way to sync data across multiple players. Previously the way to do this was to use Decors, but it wasn’t able to be accessed/modified on the server.
State bags sync with every player, so even if you join after the entity was created, you will still get all the data pertaining to that entity when you render it.
Note: State Bags and GlobalStates are not resource-specific
How to use GlobalStates:
GlobalStates are a global variable that is shared across every resource, server, and client-side. Any variable stored in a GlobalState will be replicated to the client so don’t put any sensitive data in it!
GlobalStates are also immutable to the client, meaning they can not change them.
GlobalState.curState="yes!" print(GlobalState.curState) -- returns 'yes!'
print(GlobalState.curState) -- returns 'yes!' GlobalState.curState="no!" -- doesn't work, client can't change global state.
GlobalState can also be set to any value, making them extremely versatile.
GlobalState.max_version = '1' GlobalState.min_version = '0'
How to use state bags:
There are two different types of state bags, one for the player
Player(plySrc/plyId), and one for the entity
In the example below ‘source’ is assumed to be the player source.
local ply = Player(source) ply.state.alive = true print(ply.state.alive) -- returns true
local ply = Player(PlayerId()) print(ply.state.alive) -- returns true ply.state:set(--[[ keyName ]] 'alive', --[[ value ]] false, --[[ replicate to server ]] true) print(ply.state.alive) -- returns false
This works exactly the same for Entities
In the example below ‘vehNet’ is assumed to be the entity’s network id.
local ent = Entity(NetworkGetEntityFromNetworkId(vehNet)) ent.state.exploded = false print(ent.state.exploded) -- returns false
local ent = Entity(NetToVeh(vehNet)) print(ent.state.exploded) -- returns false ent.state:set(--[[ keyName ]] 'exploded', --[[ value ]] true, --[[ replicate to server ]] true) print(ent.state.exploded) -- returns true
GlobalState.mode="open" does not mean anything, it was an example value. It doesn’t change if you’re able to send data from cl → sv or sv → cl like many people believe.
State bags don’t have to be initialized on the server
ent.state:set( 'exploded', false, true) will still create an entity state bag and be replicated to the server, even if it’s not initialized.
Original source: https://forum.cfx.re/t/how-to-use-state-bags/2093206