How to use State Bags (FiveM Lua Scripting Master Series) — Transcript
Full transcript
- 0:05[Music]
- 0:12all right hello everyone and welcome to
- 0:15the first video in my new series that
- 0:17we're calling the master series
- 0:19and in the master series we're looking
- 0:21at some more advanced features and
- 0:23functionality of 5m things you might not
- 0:24be aware of or things you might not know
- 0:26how to use well and we're going to try
- 0:28to do a little bit of a deep dive into
- 0:30these topics and see what we can learn
- 0:32about them and find out how you can use
- 0:34them in your projects your resources
- 0:36your servers and for this very first
- 0:38master series episode we are going to be
- 0:40looking at state bags which are an
- 0:42amazing feature of one sync if you're
- 0:45coming over from the zero to hero series
- 0:47today we talked about sharing data
- 0:48between client and server communicating
- 0:50using events and commands and in this
- 0:53master series we're going to look at
- 0:54another way of sharing information
- 0:56between client server and that's with
- 0:58state bags
- 0:59so let's talk a little bit about what
- 1:01state bags are and you can think of
- 1:03state bags as a table of information
- 1:06that can be attached to any networked
- 1:08entity
- 1:10so we can have a state bag attached to a
- 1:12ped uh or we could have it attached to a
- 1:14vehicle or maybe a network networked
- 1:17object we've created
- 1:18and this state can be accessed by the
- 1:21server and accessed by any other
- 1:24player client who is in scope of that
- 1:26entity
- 1:27there's also state bag change handlers
- 1:29which behave a little bit like events
- 1:30where the function will be called when
- 1:32the state bag on something that we're
- 1:34listening for changes
- 1:35now there's also a global state bag
- 1:37which is uh basically one big state bag
- 1:40that is shared between client server
- 1:42it's not tied to any specific entity it
- 1:44just kind of exists and all of the
- 1:46clients can access it now one thing
- 1:48that's important to know is that in its
- 1:49default form
- 1:51without any other modifications state
- 1:54back global state can only be modified
- 1:56by the server so all of the clients can
- 1:58access it but only the server can change
- 2:01it so it's authoritative in that way
- 2:03whereas on the client side clients can
- 2:05change the state of entities that they
- 2:08own
- 2:08so let's look at how this works and what
- 2:11we're going to start out with first is
- 2:12looking at global state all right so
- 2:15this is going to be a very simple
- 2:16example we're just going to keep a
- 2:17counter of a number
- 2:19that we can increment on the server and
- 2:21we'll see how that's reflected on the
- 2:22client so i'm just going to go in here
- 2:25and
- 2:26set up just a little thread here where
- 2:28we will say global state which is how we
- 2:30access a global the global state bag and
- 2:32then we'll just say counter is equal to
- 2:34zero and then let's also register a
- 2:37command
- 2:39and this command will only be available
- 2:40server side we're gonna be calling this
- 2:41from the server side and uh when we call
- 2:44the increment command we're just gonna
- 2:45say globalstate.counter is equal to
- 2:47global
- 2:50state dot counter plus one all right and
- 2:53then on the client let's just create a
- 2:55thread here
- 2:58and then we'll say well true
- 3:01and we'll run this every half second and
- 3:03we will just print
- 3:05the global state dot counter out now
- 3:07i've got two clients here one of them
- 3:09seems to be a little stuck up there it
- 3:11goes which is something we're going to
- 3:12be looking at later but if we look up at
- 3:14the top left 5m client we can see that
- 3:17we're printing out zero because we
- 3:18haven't incremented at all
- 3:20now let me just bring this over here and
- 3:22then if i run the increment command
- 3:25uh on the server
- 3:27you'll see that we're now reflecting
- 3:28that on the client with one
- 3:31two and three
- 3:34so you'll note that we're not sending
- 3:35any events back and forth all the server
- 3:37had to do
- 3:38was change this global state
- 3:40and all of the clients immediately have
- 3:42access to that now let's look at another
- 3:44potential way we can do this i'm just
- 3:46going to stop state bags so we're not
- 3:48getting spammed while we look at this
- 3:50now instead of running this in a thread
- 3:52i mentioned that you can also use change
- 3:53handlers to hook into these so let's
- 3:55take a look at that
- 3:57and so we can see add state back change
- 3:59handler key filter bag filter and then
- 4:02the handler and the handler has a couple
- 4:03parameters on so let me just split these
- 4:05windows really quick make this a little
- 4:06bit bigger so you can see it
- 4:08and let's look at implementing this so
- 4:10add state bag change handler
- 4:14and our key filter is going to be
- 4:17counter because that's the key that
- 4:18we're looking for and the bag filter is
- 4:20going to be global
- 4:23at least i'm pretty sure it is we're
- 4:24going to find out and then our handler
- 4:26is going to have bag name
- 4:29e value reserved and replicated which uh
- 4:34some of these aren't going to matter but
- 4:36let's just go ahead and print all of
- 4:37them out so now instead of running a
- 4:38thread to keep an eye on that global
- 4:40state we can just react when it changes
- 4:44so we can see uh we have that initial
- 4:47one uh which our value is going to be
- 4:49our third parameter there and let me
- 4:51just do increment
- 4:53perfect
- 4:54and so that's a little bit about how
- 4:55state bag change handlers work now so
- 4:58far we've only been looking at global
- 5:00state bags so now let's look at some
- 5:02uh other state bags and the one we're
- 5:04going to look at is player state
- 5:07so let's talk about how we
- 5:10set player state so when we are on the
- 5:13client the way we're going to set player
- 5:14state is we're just going to say
- 5:15localplayer.state
- 5:18dot you know foo equals bar
- 5:21now this is one way of doing it i like
- 5:23to use the set function
- 5:27because it's a little bit more clear to
- 5:28me what's happening here and we can also
- 5:29control if it's replicated or not so we
- 5:32could say foo is equal to bar and true
- 5:34because we want to replicate that to the
- 5:36server
- 5:37so this is how we can set state on
- 5:39ourselves on the client
- 5:41now if we're on the server
- 5:44and we want to change the state of a
- 5:45player let's say our player's server id
- 5:49is one
- 5:50we're going gonna say player and then
- 5:52player id dot state
- 5:55and then same thing we can either use
- 5:56set
- 5:59uh and then we can access it like
- 6:04that
- 6:05so let's try that and what we're going
- 6:07to do is we're just going to register
- 6:10a command called client increment on the
- 6:14client
- 6:18so what we're going to do we're just
- 6:19going to grab the old counter or zero
- 6:22and then oops
- 6:24and then set state to
- 6:26the old number plus one
- 6:29and then on the server why don't we
- 6:32why don't we just do
- 6:34this as an example so
- 6:37we're gonna get into our while loop
- 6:40and once again we'll just wait half a
- 6:42second and we're gonna do
- 6:45so we're just gonna get all players
- 6:48and we are just going to print their
- 6:50server id and then player
- 6:53server id.state.counter
- 6:57all right let's restart
- 7:00our state bag script and you'll see that
- 7:04one and two are both showing up here and
- 7:06it's nil because we haven't ran the cl
- 7:08inc command yet so let's do that on
- 7:11client one
- 7:13do cl inc
- 7:14perfect
- 7:15and now we can see that well one is
- 7:17equal to two
- 7:19now three
- 7:20and four
- 7:21and if we jump over to our other client
- 7:23and do cl inc here we should see that
- 7:27reflected on client two perfect
- 7:31all right so now we've learned how to
- 7:33use player state to set it on the client
- 7:36and reflect that on the server and once
- 7:38again you could you could set it on the
- 7:40server and reflect it on the client
- 7:43that's a little bit trickier for the
- 7:46the state back change handler if you
- 7:47wanted to use that
- 7:49effectively what you're going to want to
- 7:51do
- 7:52is
- 7:53your
- 7:55bag filter is going to be player colon
- 7:58and then the player server id so
- 8:00um not the cleanest format but it does
- 8:03work and you can kind of listen for
- 8:05state back changes on yourself that way
- 8:07so now let's uh
- 8:09let's dive in and look at setting and
- 8:13managing state on entities that aren't
- 8:15players
- 8:16so i'm just going to
- 8:18nuke all of my code here
- 8:22oops
- 8:23and restart the resource just to get it
- 8:24to stop printing and let's think about
- 8:26what we want to accomplish here so let's
- 8:28say we want to set
- 8:30uh a state bag on a vehicle that tells
- 8:33you who the last driver of the vehicle
- 8:35was so i'm going to use a couple things
- 8:37here i'm going to use base events to
- 8:39determine when a player enters a vehicle
- 8:43and if we jump over to the docks we
- 8:45should let me just kind of organize
- 8:47things here
- 8:49let's see stock resources base events
- 8:52and entered vehicle okay perfect so
- 8:57let's build this out really quick
- 9:02so we should get this event and let me
- 9:04just turn on word wrap so we can see
- 9:06what we're doing okay so we should on
- 9:08the server this event should be called
- 9:10when a player enters a vehicle and we're
- 9:12just going to say if c index is not
- 9:15equal to negative 1 then return
- 9:18otherwise
- 9:21what we want to do is set a state bag on
- 9:23the vehicle so for vehicles instead of
- 9:25using player we use entity and one thing
- 9:28that's important to note is you need to
- 9:29use the entity handle not the entity's
- 9:32network id here
- 9:34so in this case the uh current vehicle
- 9:37is likely going to be the server id i
- 9:41believe
- 9:42you know what after a uh a quick look at
- 9:46the base events resource there's
- 9:47actually an undocumented
- 9:49parameter here
- 9:53vehicle net id
- 9:55which is going to be the fourth one so
- 9:56i'm just going to say
- 9:59we're going to assign a variable vehicle
- 10:01entity and we're just going to say
- 10:02get entity
- 10:06id from network id i'm pretty sure
- 10:08that's correct let me double check
- 10:10network get entity from network id there
- 10:12we go and we're going to provide the
- 10:14vehicle net id
- 10:17all right
- 10:19and then we're going to say entity
- 10:21vehicle entity dot state
- 10:24dot last driver
- 10:26or actually let's use sat set
- 10:30last driver is equal to
- 10:33um the id
- 10:37person who triggered this event which is
- 10:38going to be sourced there so we'll say
- 10:40that
- 10:41and then player id
- 10:43all right so that should
- 10:45assuming we've done everything right
- 10:46here this should set a state bag called
- 10:48last driver on the vehicle itself with
- 10:51the id
- 10:52of the player who last got in the
- 10:54driver's seat and now we just need to
- 10:57implement a way to check that on the
- 10:58client side so down here on the client
- 11:00i'm just going to register a command
- 11:02called get last driver
- 11:05and now i also have a raycasting
- 11:08resource
- 11:09utility resource that i'm going to be
- 11:10using for this
- 11:11and so uh all i need to do is say entity
- 11:14id is equal to export
- 11:17stock raycast dot get hit entity and
- 11:21then uh we can just print uh
- 11:25entity entity id dot
- 11:30state dot last driver
- 11:32and
- 11:33we're kind of winging that
- 11:35everything right
- 11:37i'm gonna start base events i'm gonna
- 11:39start raycast and i'm going to restart
- 11:43state bags which
- 11:45okay
- 11:45perfect
- 11:46so let's see if this worked out for us
- 11:49um
- 11:50so you can see my my raycast utility
- 11:53here is just going to draw to entities
- 11:55and highlight them
- 11:57and then i can get whatever i'm looking
- 11:59at so
- 12:00if we get into our vehicle
- 12:03and then get out of it and then we get
- 12:06the state bag for it you can see that it
- 12:08is two now what's great here is it's not
- 12:11just that client uh any other client so
- 12:13we're gonna take this guy over here and
- 12:15we're gonna have him come take a look at
- 12:17it
- 12:18and they can also access the state bag
- 12:20that says it's two and now if we were to
- 12:23get in it
- 12:24and then use our second client to try to
- 12:26get the last driver again you can see
- 12:28it's been changed to one so state bags
- 12:30are incredibly powerful for keeping
- 12:32information about an entity around some
- 12:34good examples of things i've used state
- 12:36bags for in the past include if a player
- 12:38is handcuffed or not or if they have any
- 12:41injuries
- 12:42as well as for vehicles obviously fuel
- 12:45level
- 12:46for peds also if their seat belts on so
- 12:48there's just an endless amount of things
- 12:50that you can use state bags for and
- 12:52sharing information information between
- 12:53client and server
- 12:55really simply so just imagine the
- 12:57scenario let's take the handcuff
- 12:58scenario let's say that a player is
- 13:00handcuffed and you have you know maybe a
- 13:02radial menu for police where they can
- 13:03uncuff right
- 13:05and we want this radial menu to not suck
- 13:07so when the player's not cuffed we want
- 13:09them the option to say handcuff and when
- 13:11they are cuffed we want it to say uncuff
- 13:14well how would you do that before maybe
- 13:16when they open the radial menu and
- 13:18they're looking at a player you go call
- 13:19the server and ask for information about
- 13:21that player that's not a great time
- 13:22right so if we just have a state bag on
- 13:24the player is cuffed that's set to true
- 13:26or false
- 13:27then the client can access that
- 13:29information about the player they're
- 13:31looking at without ever having to talk
- 13:33to the server about it or like maintain
- 13:35a crazy table list of everybody who's
- 13:37handcuffed at the moment or any weird
- 13:39solutions like that so there's a lot of
- 13:40really really great ways to use state
- 13:42bags
- 13:44and with all of that said i think this
- 13:46is probably going to wrap up this first
- 13:48master series on state bags i've got a
- 13:50ton of useful links down below to
- 13:51information about state bags
- 13:53as well some forum posts things like
- 13:54that stuff that will hopefully get you
- 13:56started and definitely let me know down
- 13:58in the comments below if you found this
- 14:00useful if you learned anything let me
- 14:02know what you're excited to use state
- 14:03bags for
- 14:04be sure to hit that subscribe button
- 14:06check the bell icon so you get notified
- 14:08when new videos come out and as always
- 14:10i've got my discord link down below
- 14:11we've got a growing community of really
- 14:13helpful people there i'm active there if
- 14:15you have any scripting questions come in
- 14:17drop them i'm happy to do my best to try
- 14:19to help you out anyways thanks again for
- 14:21this uh joining us on this inaugural
- 14:23episode of master series and i hope to
- 14:25see you back soon
About this transcript
This page contains the full transcript of How to use State Bags (FiveM Lua Scripting Master Series) by CharlesHacks, generated from the public captions YouTube serves with the video. The transcript has 2,553 words across 402 segments, with the original timestamps preserved so you can click any line to jump to that moment in the embedded player.
What you can do with it
Use the transcript to take notes, quote the speaker, build a study guide, generate a summary with ChatGPT or Claude via the YouTube Summary tool, or export it as a timed subtitle file with YouTube to SRT. You can also re-open it in the transcriber to translate the transcript into 100+ languages.
Free YouTube transcript tool
YouTube2Text is a free YouTube transcript generator — no signup, no daily limit. Paste any YouTube link and get the full transcript instantly, with timestamps, click-to-jump, translation to 100+ languages, AI prompts for ChatGPT, Claude, and Gemini, and exports to TXT, SRT, VTT, or Markdown.