DataStore (Saving Player Data, pcall(), Scopes) - Roblox Advanced Scripting #17 — Transcript
Full transcript
- 0:00oh yeah I made so much progress in this
- 0:02tycoon game that I'm playing that I
- 0:04bought this entire dropper for $0 and it
- 0:08would really suck if I left the game
- 0:10right now and come back to find out that
- 0:12all my progress is now gone I really
- 0:15don't know whether that is the case or
- 0:16not with this game if it does have a
- 0:18safe feature but I guess one way to find
- 0:20out is to log out and then come back
- 0:22into the game a couple hours later to
- 0:24see whether that is the case or not
- 0:25because my mom is banging at my door
- 0:27right now so I'm going to have to
- 0:28continue this game at a later time so
- 0:30let's see what happens all right I've
- 0:32finally gotten that taken care of so
- 0:33let's see if my progress still
- 0:35saves
- 0:38uh okay well that sure sucks okay a way
- 0:42we can fix an issue that comes about
- 0:44similar to what we just experienced here
- 0:46is Implement a feature that allows us to
- 0:49save data within play sessions for when
- 0:51a player plays the game and then decides
- 0:53to join back into the game and continue
- 0:56where they left off with their progress
- 0:58we're going to use a feature called a
- 1:00data store that allows us to do exactly
- 1:02what I just said which is if a player
- 1:05decides to join a game and make progress
- 1:07in a tycoon or whatever game that
- 1:09they're playing and they decide to leave
- 1:12the game and then come back into the
- 1:13game and continue right where they left
- 1:16off with the progress that they did have
- 1:19um using a data store that is how we're
- 1:21going to be able to save the players
- 1:23progress so that they can continue uh to
- 1:26do what they want to do but data stores
- 1:29seem to be exclusively for player data
- 1:32but data stores can actually be used for
- 1:34anything related to uh storing data
- 1:37within the game apart from player data
- 1:39that's just one of the most common use
- 1:40cases of using data stores so in this
- 1:43video I'm going to show you the basics
- 1:45of using roblox's roblox's built-in data
- 1:48store service and how we're going to use
- 1:51that inside of our Roblox games so with
- 1:52that being said let me show you further
- 1:54what I'm trying to get out here to
- 1:56understand how this data store works all
- 1:58right let's think about this for a
- 1:59minute I kind of want to paint a picture
- 2:01of how data stores are structured before
- 2:04we start implementing them inside of
- 2:05Roblox studio so let's say we had our
- 2:08game here which is basically our game
- 2:10that we're currently playing right now
- 2:12this weird Tycoon that we're playing uh
- 2:14and then we have roblox's servers which
- 2:16is essentially the back end of where
- 2:19they store all of our information um
- 2:21that we would utilize in order to give
- 2:24them information and then retrieve them
- 2:26if we need them uh for our game so then
- 2:29let's let's say we had data as like this
- 2:32abstract piece of information that we
- 2:35want to save uh from The Game's current
- 2:38session that we have here so if we have
- 2:40data that's lied inside of our game
- 2:43session so if we're playing the game
- 2:45right now this is where the data is
- 2:46currently stored and data could
- 2:48literally be anything it could be a
- 2:50string it could be a table it could be a
- 2:51Boolean just basically all sorts of
- 2:54things that comprise of our players
- 2:56progress like our kills deaths cash uh
- 2:59and and our uh Tycoon progress just
- 3:02examples like that this is essentially
- 3:04what data is it's an abstract piece of
- 3:07information that contains all of our all
- 3:09of our data and let's say we took this
- 3:11data and sent it over to roblox's
- 3:13servers if the player decided to leave
- 3:15the game and let's say that we decided
- 3:18to join into the game again we would ask
- 3:21Roblox to give us data that we want to
- 3:23retrieve back into our game so then we
- 3:26now have the same piece of data that we
- 3:29had when the player left the game to
- 3:31then join back with the data that we now
- 3:34have retrieved from roblox's servers and
- 3:36if the player left again then we would
- 3:38just send it over back to roblox's
- 3:39servers to keep it safe so with this in
- 3:42mind now let's understand how a data
- 3:45store is structured so data is very
- 3:47broad because data can be broken up into
- 3:50multiple pieces of data like our
- 3:52leaderboard data or uh or our Tycoon
- 3:55data so we would basically break this
- 3:58down into multiple data Stores um that
- 4:02have Associated names for them so in
- 4:04this case what if we wanted to let's say
- 4:06have a data store for coins specifically
- 4:09this would be the name of our data store
- 4:12and the way data stores are structured
- 4:14is it's kind of like a dictionary so uh
- 4:17and you know how a dictionary goes we
- 4:19have a key with a value associated with
- 4:22it so in this case let's say we had a
- 4:25key of player one or it could just be
- 4:27brawl battle like me right here um this
- 4:30would be our key right here and if we
- 4:33had a data store called coins and we
- 4:36have a player uh that has a data store
- 4:39inside of our coins that have data
- 4:42inside of our coin's data store like
- 4:44let's say we had 100 coins inside of our
- 4:48um player key for coins so we have our
- 4:51coins data store name with our player as
- 4:54the key and then we have 100 as the the
- 4:58number of coins we have we want to then
- 5:01um put all of this inside of our data
- 5:03and send this over to roblox's server if
- 5:06we leave the game and then retrieve it
- 5:08back if we decide to join back into the
- 5:10game and since this is our data store we
- 5:12can and that this is a dictionary we can
- 5:14have multiple keys inside of here so we
- 5:17can even have player two uh inside of
- 5:19our data store and we can have uh let's
- 5:22say 300 coins so if player one decides
- 5:24to leave the game we're going to send
- 5:26this data into roblox's server and if we
- 5:28join back into the game with player one
- 5:31joining back specifically we want to
- 5:33take what the value of player one's
- 5:35coins were and give it to the players so
- 5:38that we can start off with 100 coins
- 5:40just like we did last time and we can
- 5:42continue our progress and continue this
- 5:44cycle of going back and forth between
- 5:46the game and roblox's servers to um
- 5:50effectively allow us to save data
- 5:52between game gameplay sessions so I hope
- 5:56this part made sense to you and gave you
- 5:57a better understanding of data stores
- 5:59inside of uh Roblox so now what we're
- 6:01going to do is start to implement them
- 6:03inside of our Roblox game so let's go
- 6:05ahead and do that right now now that we
- 6:08understand it let's start implementing
- 6:10data store in our game but there is
- 6:12something we have to do first before
- 6:14we're able to access data stores inside
- 6:16of Roblox studi so that we're able to
- 6:18test it while we are implementing these
- 6:20things um and in order to access this
- 6:23and in order to do this we have to check
- 6:25a setting but we can't access the
- 6:27settings until we publish our games so
- 6:29I'm going to show you how to do that in
- 6:31case you've never done it before so what
- 6:33we're going to do is we're going to go
- 6:34on the top left hit file and we're going
- 6:37to hit publish to Roblox as and it's
- 6:40going to show up this little popup of
- 6:41games that we're going to create so down
- 6:43here we're going to hit create new game
- 6:45and it literally doesn't matter what you
- 6:47call this game you can just call it data
- 6:49store test uh one or something it it
- 6:52really does not matter at all what you
- 6:54call it uh so we're going to hit create
- 6:57and what should happen is now we're
- 6:59going to be uh thrown into a published
- 7:02game uh to now work with a published
- 7:05game instead of a local file like we
- 7:07have been throughout this entire time
- 7:08we've been creating games so now that
- 7:10we've done that we can go up here so if
- 7:13we go to home and then click on game
- 7:14settings we have access to all of these
- 7:17different settings um to modify our
- 7:20published game but what but what we're
- 7:22interested in is we want to go down to
- 7:25security and we want to check this
- 7:27option enable Studio access to API
- 7:30services and this basically allows us to
- 7:33access data stores while we're working
- 7:35on our game inside of studio and that is
- 7:38very important for us to uh and this is
- 7:41very important for us to use you don't
- 7:42have to do this but I think it's
- 7:44definitely a lot better to have this as
- 7:45an option so let's hit save and now
- 7:48we're able to access data stores while
- 7:50we work on our game so sweet we have
- 7:52that down so now let's get to adding our
- 7:54data stores and the place to do this is
- 7:57in a script so it's probably going to be
- 8:00somewhere like server script service or
- 8:01server storage I'm going to put this
- 8:03inside of server script service so we're
- 8:05going to add in a script here and we are
- 8:07adding a script so this does not work
- 8:09with a local script um let's delete this
- 8:13code right here and so what we're going
- 8:14to do is access our data store by saying
- 8:16local data store service equals game
- 8:21colon get service open close parentheses
- 8:24data store service the first thing we
- 8:27can do and this really important thing
- 8:29that we have to do is specify our data
- 8:32give our data a name so that we know
- 8:34what data we're working with that we're
- 8:36trying to save so if you're remember how
- 8:38data stores are structured based on what
- 8:39I showed you data stores comprise of a
- 8:43dictionary data stores are essentially a
- 8:46dictionary that have a key and a value
- 8:49and there can be multiple data stores
- 8:51with associated with a name associated
- 8:54with it so that we know what data we're
- 8:56working with so that we can send it to
- 8:58roblox's servers save it for us and give
- 9:01us the option to retrieve it back so
- 9:03that we can use it at a later time and
- 9:05so now that we understand that let's try
- 9:07and figure out what kind of data we want
- 9:09to save so let's say for this example we
- 9:12want to save a data store of all the
- 9:15players coins inside of uh the game that
- 9:17we're trying to create so what we can do
- 9:19is say local player coins equals data
- 9:24store service and the way we retrieve
- 9:27this data store is use a function called
- 9:31get data store open and close
- 9:34parentheses and there's three arguments
- 9:36here but the important one that we do
- 9:38need to know about is the name of our
- 9:40data store which is just going to be
- 9:42player coin that's what we're going to
- 9:45call our data store so now that we have
- 9:47our data store our data store comprises
- 9:49of a dictionary of keys and values so
- 9:52you might ask what kind of key do we
- 9:55want to store within these player coins
- 9:57well I mean if we're thinking about
- 9:59player coins ideally all of the entries
- 10:02inside of our data store is going to be
- 10:05each individual player so how this might
- 10:08look is that if we let's say had a
- 10:10dictionary here uh well actually let me
- 10:12comment this here if we had a dictionary
- 10:14of player coins let's say and we wanted
- 10:16to have brawl battle as our player for
- 10:20the key and then we're going to have the
- 10:22value of the coin itself which is going
- 10:24to be like I don't know 10 or something
- 10:26like that this is how a dictionary is
- 10:28structured you kind of know this at this
- 10:29point so if we were to translate this
- 10:32into a data store since player coins is
- 10:35essentially a dictionary what we would
- 10:37do is if we want to set this data onto
- 10:40our player coins data store we're going
- 10:42to use a function called set async and
- 10:45this is what it's going to look like
- 10:47we're going to give the name of our data
- 10:49store by saying player coins colon set
- 10:53async open and close parentheses and we
- 10:56have to put in a key here so the key in
- 10:59this case is going to be brawl battle
- 11:02and if this key is not available in our
- 11:05data store then it's going to add this
- 11:06in automatically so you don't have to
- 11:08worry about checking it comma and then
- 11:10we're going to add an a value here to
- 11:13our data store which is going to be 10
- 11:15so now what's happened is that our empty
- 11:17player coins dictionary now has one
- 11:19entry with brawl battle being the key
- 11:22and 10 being the value so now let's say
- 11:24we wanted to retrieve this information
- 11:27what we would do is wrap this in a
- 11:29variable by saying local coins equals
- 11:33player coins colon get async open and
- 11:38close parenthesis and all we need to do
- 11:40is set our key and all we need to do is
- 11:43specify our key which in this case is
- 11:45going to be brawl battle and so with
- 11:48that logic we should be able to retrieve
- 11:5010 inside of our player coins dictionary
- 11:53and so we can pretty much just print
- 11:54this value out uh when we play the game
- 11:57and hit run so let's hit run and then
- 11:58see our output to know that our thing is
- 12:01working properly so as you can see in
- 12:03the output it has printed 10
- 12:05successfully after we fetched the value
- 12:08of coins from our brawl battle key
- 12:11inside of our player coins dictionary I
- 12:13hope that part made sense to you so we
- 12:15don't know whether this is actually
- 12:16working correctly or not because we're
- 12:18constantly setting uh our key to 10
- 12:21every single time we play the game so
- 12:24what if I commented this part out so now
- 12:27if we play into the so now if we play
- 12:29the game all we're doing is fetching the
- 12:31value of my coins so is this going to
- 12:34print 10 or is this going to print zero
- 12:36let's hit run and see what happens uh
- 12:38when we join into the game in the output
- 12:42as you can see it's still printed 10
- 12:44even though we did not set 10 to be
- 12:47inside of our even though we did not set
- 12:5010 to our player in the player coins um
- 12:54data store because we told Roblox that
- 12:56we wanted to save this information and
- 12:58retrieve it back next time we decided to
- 13:01join into the game so this is so this is
- 13:04how you know that the data store that we
- 13:06set is working properly because it saved
- 13:09our previous session and it and it
- 13:12retrieved our data back into the new
- 13:14game when we join back into the game so
- 13:16that is basically working as expected so
- 13:18that's one method of setting data but
- 13:20there's another method we can use to
- 13:23increment our data if we have some sort
- 13:26of numerical value like our coins for
- 13:28instance
- 13:29uh that we want to update so the way
- 13:32this would work is instead of using set
- 13:34async all we would need to do is simply
- 13:36replace set async with increment async
- 13:39so this is what it would look like we
- 13:40would say player coins colon increment
- 13:45async open and close parenthesis and so
- 13:48the first argument is just going to be
- 13:50our key which is just braw battle and
- 13:52then our second argument is going to be
- 13:54this argument called Delta and basically
- 13:56what this means is that we're going to
- 13:58take the current value of what's stored
- 14:01inside of the key brawl battle which in
- 14:03this case it's 10 coins and we're going
- 14:05to give it an and we're going to give it
- 14:08another value here to add it onto what
- 14:11is currently inside of our data store so
- 14:14if we put in five here then it's going
- 14:17to take our current data store which is
- 14:1910 and add five to it uh to get a result
- 14:22of 15 and if we wanted to do this the
- 14:24other way around we would give it a
- 14:26negative value to subtract what our
- 14:29current value is to five rather than 15
- 14:31but we're going to try and set this to
- 14:34but we're going to try and increment
- 14:35this to 15 So currently inside of
- 14:38roblox's data store our value is 10 so
- 14:42if we join into the game and uh let the
- 14:46let the increment async function run
- 14:48then in the output it should say 15 as
- 14:51you can see here instead of 10 because
- 14:54we incremented uh our current value and
- 14:57added five to it and and like I
- 14:59mentioned this only works with numerical
- 15:02values so this is not going to work with
- 15:04things like booleans and tables and all
- 15:07of those other sorts of things this only
- 15:09works with numerical data so like
- 15:11numbers and decimals and those things
- 15:14like that so now that we have our data
- 15:16how do we want to remove this data if we
- 15:18decide that okay well this player does
- 15:20not need this data anymore with player
- 15:22coins instead of just having it set back
- 15:25to zero or anything like that we just
- 15:27want to get rid of it completely from
- 15:29the data store we would use a function
- 15:31called remove async and this is pretty
- 15:33much what it's going to look like so if
- 15:35we drop two lines down here all we need
- 15:37to do is say player coins colon remove
- 15:42async open close parenthesis and all we
- 15:44need to do is pass in the key which is
- 15:47going to be brawl battle in this case
- 15:50and so pretty much what's going to
- 15:51happen here is that if we try to print
- 15:54this out twice so if let's say we wanted
- 15:56to try and uh get our player coins uh
- 16:01get our player coins data store data
- 16:03store using the key brawl battle uh this
- 16:06is not going to work once we remove
- 16:08ourselves from our player coins data
- 16:10store and it's just going to throw in an
- 16:12error so let's hit run and see this
- 16:15happened inside of the output so in the
- 16:17output as you can see uh initially our
- 16:20value is 20 because uh our value is now
- 16:2315 from the last play session and we
- 16:25incremented It Again by five so now the
- 16:28total value use 20 but now that we
- 16:30removed ourselves from the player coins
- 16:33dictionary uh when we try to fetch our
- 16:36player coins again using the key brawl
- 16:37battle it returns null because it no
- 16:40longer exists because we removed
- 16:41ourselves from it so that is a a quick
- 16:44and easy way to remove uh an entry from
- 16:47a data store if you don't need it
- 16:49anymore but you could also just set the
- 16:51data back to zero or whatever the
- 16:54default value is as well cuz remove
- 16:56async specifically gets rid of it
- 16:59entirely from the data store it doesn't
- 17:01reset it back to its default um data
- 17:03store so that's something I want you to
- 17:06know about if you decide to use remove
- 17:08async in your Roblox games okay now this
- 17:10next concept I want you to fully pay
- 17:13attention to because I expect you to do
- 17:15this from now on when you're
- 17:16implementing data stores so so far up
- 17:20until this point when we've been
- 17:22accessing data stores uh by incrementing
- 17:24them by getting them by setting them and
- 17:26even removing them we just simply give a
- 17:29blank statement of just incrementing it
- 17:31if we decide to do so or get it if we
- 17:33decide to do so but here's the thing
- 17:36about data stores it's very it's a very
- 17:39tricky procedure to go and contact
- 17:42Roblox to give us our data that we need
- 17:45and give it back to us so that we can
- 17:46use it in our game uh for future use
- 17:50it's very tricky because there can be a
- 17:52lot of things that can go wrong with
- 17:54trying to do this like maybe the network
- 17:56was just bad when uh we tried to fetch
- 17:58the data or our Wi-Fi was just terrible
- 18:01or the game is just extremely extremely
- 18:03laggy so it's delayed there's so many
- 18:05problems that could arise just from
- 18:07trying to retrieve data from roblox's
- 18:09servers a very scary example of this
- 18:12would be if a player decided to join
- 18:14into the game and they had so much
- 18:17progress in their game that they're
- 18:18playing if we just decided to ask Roblox
- 18:22one time uh to fetch the data and give
- 18:24it to the player but then something goes
- 18:26wrong the player can no longer retrieve
- 18:28retrieve the data that they need in
- 18:30order to progress through the game and
- 18:32so because of a little mess up from
- 18:35roblox's servers or anything that could
- 18:37go wrong with doing this they now have
- 18:39to start back from square one with zero
- 18:42progress and you're going to get a lot
- 18:44of hate from players who complain about
- 18:47losing all their data it's a very scary
- 18:49feeling if you really think about this
- 18:51if you make so much progress in the game
- 18:53to where all of a sudden one little Mis
- 18:57one little error happen
- 18:59then the player will no longer have
- 19:01their data and it's a very scary and
- 19:04very unfortunate situation to be in so
- 19:07now that I've painted that picture for
- 19:08you how can we prevent this from
- 19:10happening well what we can do is we can
- 19:13tell Roblox that okay if the first time
- 19:16we try to get the player data fails
- 19:18let's try it again and then we'll try it
- 19:20again and then we'll try it again and
- 19:21again what we can do is use a function
- 19:24that Roblox has provided for us called a
- 19:27PE call and this this is what it's going
- 19:29to look like so I'm going to comment out
- 19:31all the code that we've had up until
- 19:32this point so that I can demonstrate um
- 19:35how we're going to structure our data
- 19:37stores from now on rather than what we
- 19:39just had right here so what we're going
- 19:40to do is say p call open and close
- 19:44parentheses function open close
- 19:47parenthesis enter and so now that we
- 19:50have this wrapped in a PE call we're
- 19:51going to let Roblox try this over and
- 19:54over again and tell us what's going on
- 19:57with the code and why it's not working
- 20:00and this is sort of a way we can um fail
- 20:03prooof the system uh to know whether
- 20:05this worked or not and if it did not
- 20:07work then we can do alternatives to try
- 20:10and get our data um safely if let's say
- 20:13we wanted to retrieve data using uh our
- 20:16get acing function uh PE call will
- 20:19return two values the first value is
- 20:22going to be whether the PE call was
- 20:24successful or not and the second one is
- 20:26going to be our returned value itself so
- 20:29behind PE call what we're going to do is
- 20:31say local success comma Uh current coins
- 20:37or you can call this whatever you want
- 20:38it doesn't really matter equals Pall
- 20:40function open close parentheses enter so
- 20:43from this PE call uh this will return a
- 20:46Boolean of whether this operation was
- 20:48successful or not and this is also going
- 20:50to return our get async um and put it
- 20:53inside of this uh variable right here so
- 20:56what we're going to do is say return
- 20:59player
- 21:00coins colon get async open and close
- 21:04parentheses and then our key is brawl
- 21:06battle this is basically how a p call is
- 21:08structured so now we can check to see
- 21:10whether this was successful or Not by
- 21:12saying if success then and we can
- 21:16basically just print out our players
- 21:18coins or we could do whatever we want
- 21:19here now that we know that it has been
- 21:21successful we can pretty much say player
- 21:24coins have been retrieved successfully
- 21:30fully and then we can also just return
- 21:33uh what the coins are um specifically so
- 21:36now if we go and hit run we should be
- 21:39able to see that this will successfully
- 21:41go through now that we wrapped it in our
- 21:43PE call function uh and in the output it
- 21:46should say player coins have been
- 21:48successfully retrieved but because in
- 21:50our previous example we removed our
- 21:52value here our key currently does not
- 21:54have a value it's currently set to nil
- 21:57so we need to be be able to do that that
- 21:58ourselves but this is basically how we
- 22:01use PE call to safely know whether uh
- 22:05whether this operation was successful or
- 22:07not and if it wasn't successful we need
- 22:08to be able to we need to be able to
- 22:10handle that ourselves and this is a much
- 22:12safer system than than just simply using
- 22:16get async by itself we can even do this
- 22:18with other operations like setting the
- 22:21data store or removing the data store
- 22:24and just things like that we can do that
- 22:26similar to how we did up here with our p
- 22:28call uh just by having some slight
- 22:30variations to the code itself so let's
- 22:32say we wanted to set the data then what
- 22:35we would do is say local success and
- 22:38then error message in case uh we do
- 22:41decide to have an error message uh we
- 22:42would simply wrap this in a p call
- 22:45function open and close parentheses
- 22:47enter uh and then what we're going to do
- 22:49is just simply say player coins colon
- 22:54set async open and close parentheses put
- 22:57in our key which is Raw Battle and then
- 22:59our new value which is let's say 50 for
- 23:02in this case and let's then check if uh
- 23:05it wasn't successful now that we have an
- 23:07error message to let us know what went
- 23:09wrong exactly so what we can do is say
- 23:12uh if not
- 23:14success then uh we're going to print out
- 23:17our error message inside of the output
- 23:20uh so that we can know exactly what the
- 23:22issue is if uh we decide to uh try
- 23:25setting data if we try setting our
- 23:28player data uh if it doesn't go out if
- 23:31it doesn't turn out well then we're
- 23:32going to know in the output what exactly
- 23:34the error is so that we can fix it
- 23:36ourselves the reason we're doing an
- 23:37error message instead of a um a new
- 23:41variable is because we're not returning
- 23:42anything down here uh all we need to do
- 23:44is know whether this was successful or
- 23:46not and if it wasn't then we're going to
- 23:48print out the error message so that's
- 23:49why there's a slight variation with
- 23:51setting versus if we were trying to get
- 23:54something because in this case we would
- 23:56probably need the current coins in order
- 23:58to process um uh what it whatever it is
- 24:01we want to do with our data but setting
- 24:04in this case we don't care about what
- 24:06the data is because we already know what
- 24:08it is we just care about whether uh this
- 24:11throws an error and if it does we need
- 24:12to know what the error is so that we can
- 24:14fix it incrementing will look something
- 24:16like this so we would have uh our
- 24:19success variable and then we would have
- 24:21a return value for incrementing if we
- 24:23want to do that this is just one example
- 24:25of doing it um we would probably just
- 24:27call this new coins value uh equals P
- 24:31call function open close parentheses
- 24:32enter we're going to say return player
- 24:36coins colon increment async open close
- 24:41parenthesis with our key braw battle and
- 24:44then we're going to increment this from
- 24:4550 to uh let's say 60 by adding 10 here
- 24:48uh that is basically how it's going to
- 24:49work here we can check whether this was
- 24:51true or not if success then print new
- 24:55coins just like a basic example like
- 24:57that and if we let's say want to uh
- 25:00remove the data we would
- 25:03say local success coins value equals P
- 25:08call function open close parentheses
- 25:10enter return player coins remove a sync
- 25:16uh and then just give the key brawl
- 25:18battle so in this case with remove uh
- 25:21once we remove our player from the coins
- 25:24data store if let's say we wanted to
- 25:26retrieve the value one last time we we
- 25:28would add in our own variable here um in
- 25:32case we wanted to use it right after we
- 25:33decide to remove the player data so we'd
- 25:35say if this was successful then let's
- 25:38print uh the coin oh the the coins value
- 25:43and so there we go these are basically
- 25:45the PE call equivalents of these four
- 25:47methods that I've been showing you up
- 25:48until this point okay so I kind of lied
- 25:51there actually is function that we can
- 25:53use to manipulate our data stores that
- 25:56we have in our game so I mentioned four
- 25:58of them but there actually is a fifth
- 26:00one and this is called update async and
- 26:03by the sound of it it sounds very
- 26:05similar to set async in the way how I'm
- 26:08going to describe update async it's
- 26:10basically a function that allows us to
- 26:12change the value of a current data store
- 26:17but this time given a call back so I'm
- 26:20going to further explain how this all
- 26:22works but let's first write it down so
- 26:24I'm actually going to comment out some
- 26:25stuff here because there's just a lot of
- 26:27code that I don't think we really need
- 26:29right now um so let's comment out all
- 26:32this part after the set async part um so
- 26:35we should have 50 coins by the time uh
- 26:38We Run the game so down here we're going
- 26:41to start writing our update async
- 26:44function so this is going to be our
- 26:45update one what we're going to do is say
- 26:48local success comma updated coins equals
- 26:54P call function open and close
- 26:56parentheses enter and so what we're
- 26:58going to going to do now is Right return
- 27:01player coins colon update async open and
- 27:06close parentheses we're going to pass in
- 27:08our key which is braw Battle and then we
- 27:11have this other argument called a
- 27:13transform function and so basically what
- 27:16we do here is it it describes it right
- 27:18here it takes the current value and it
- 27:21Returns the new value along with
- 27:23optional user IDs and metadata but we
- 27:25don't have to worry about that that last
- 27:26part what matters is that we're
- 27:28basically going to take our current data
- 27:31that's inside of this player coins data
- 27:33store and we're going to pass this into
- 27:35a callback function and return the new
- 27:38value and put it inside of updated coins
- 27:41so we actually need to write our own
- 27:42function for this so so before we write
- 27:45our P call let's write a new function so
- 27:47we're going to say local function and
- 27:49let's say
- 27:52uh increment value just whatever we
- 27:55decide to do with this function we're
- 27:57going to pass in our current coins which
- 28:00is going to be in the data store we're
- 28:01going to hit enter and we're just simply
- 28:03going to return current Coins Plus let's
- 28:07say 50 so by the time we return this
- 28:10value it's going to be set to 100 let's
- 28:12pass this in like the the function
- 28:16itself we're going to pass in increment
- 28:19value as our call back so now what
- 28:22should happen is we're going to update
- 28:24async we're going to call the increment
- 28:26value function and we're going to return
- 28:28100 coins now that we added 50 to our
- 28:31current coins put it back here return
- 28:33this here and then put it in our updated
- 28:35coins so now down here we're going to
- 28:37say if success then print updated coins
- 28:422 and then we're just going to uh
- 28:44concatenate our updated coins value here
- 28:47just so that we can organize it and
- 28:49understand what this value actually is
- 28:50here okay sweet so that is basically how
- 28:53you use update async so if we join the
- 28:55game then what we should see is our fin
- 28:58result of coins being 100 so it says
- 29:01here that updated coins to 100 because
- 29:04we first uh made it so that we seted our
- 29:07coins value to 50 and then we called our
- 29:11update async using this function right
- 29:13here to return 100 after we added 50 to
- 29:16it and that is basically how update
- 29:18async Works instead of set async but
- 29:21that's still doesn't really answer what
- 29:23the difference is between set update
- 29:26between set async and update async sync
- 29:28essentially how I would want you to
- 29:30understand the difference between the
- 29:31two is that when we use set async we're
- 29:35basically just trying to change a quick
- 29:37value using a PE call and not really
- 29:39have to worry anything too much about it
- 29:41however there are issues with using set
- 29:43async that update async might do better
- 29:46and that is uh being able to try
- 29:49multiple times to be able to set the
- 29:51value that we want um our value set to
- 29:54because what happens with set async is
- 29:56that if we have set async and we try to
- 29:58make this work it's probably going to
- 30:00set it correctly but let's say we had
- 30:02two set async happen at the exact same
- 30:04time oh sorry I'm still in testing mode
- 30:07what if we haded two set async happen at
- 30:09the same time there's probably going to
- 30:11be some inconsistencies here on whether
- 30:13which one is going to uh set first um
- 30:17it's probably going to be 100 it might
- 30:19be 50 we don't even know because because
- 30:22this one might do it faster than this
- 30:23one so there's an inconsistency when it
- 30:25comes to that but it's definitely a
- 30:28quicker solution to the problem that
- 30:29we're trying to fix it's faster as well
- 30:32and it's less complicated to do but if
- 30:34we wanted to use update async for
- 30:37situations where we want to be
- 30:39consistent with the data that we're
- 30:41trying to set this data store to would
- 30:43be using like multiple attempts to try
- 30:45and make that happen while also making
- 30:47it safer we would probably use update
- 30:50async but the issue with this is that it
- 30:52might be slower than if you try to use
- 30:55uh set async for like one value rather
- 30:57than trying to set multiple values
- 30:59instead of just one that's kind of a
- 31:01superficial explanation as to how the
- 31:03stuff works but I hope that sort of
- 31:05gives you a general idea of which ones
- 31:07you should use over the other one when
- 31:09you're trying to decide on whether
- 31:10you're using set async or update async
- 31:14but generally you could use either or
- 31:16you could use only one of them over the
- 31:18other if you really want to or you can
- 31:20use a mix of both of them it really does
- 31:22not matter that much unless you're being
- 31:24very specific with how you want to
- 31:26handle your data stores so so that's
- 31:28pretty much that okay now there is one
- 31:30more important concept to learn about
- 31:32and that is with the use of Scopes so in
- 31:36order for me to let you understand how
- 31:38this stuff works uh let's paint a
- 31:41picture of of how we would organize our
- 31:44data stores so let's say we did join
- 31:46into the game and we want to save
- 31:49multiple pieces of data um we would
- 31:52probably do something like this we would
- 31:54have one for player coins we would have
- 31:56one for uh I don't know player gems we
- 31:58would have one for uh player kills we
- 32:02would have one for player wipeouts and
- 32:05you you get the idea like if I kept
- 32:07going down this list it's going to get
- 32:10very very very very disorganized very
- 32:13very fast so and so I think that says a
- 32:16lot about how we organize our data
- 32:18stores if we were to try to do this
- 32:20strategy to do this sort of stuff so
- 32:22that's why I want to introduce you to
- 32:24the concept of Scopes and this is
- 32:26essentially a and this is essentially
- 32:29data stores within data stores so that
- 32:31we can organize our data Stores um when
- 32:35we're working with multiple pieces of
- 32:36data that we're trying to save in our
- 32:38Roblox games so the way this would
- 32:40probably work uh let me just try to
- 32:43demonstrate this with an example um
- 32:45let's say we had player inventory but
- 32:48our player inventory could be comprised
- 32:50of many many different things our player
- 32:52inventory could probably be uh coins how
- 32:55this would work is it would kind of work
- 32:57like it's a direct directory or folder
- 32:59by using a forward slash and say uh
- 33:01coins so our coins is a data store in
- 33:05and of itself inside of the player
- 33:07inventory data store because we have
- 33:10multiple data stores inside of the same
- 33:12data store so this is probably what it
- 33:14would look like down here with gems in
- 33:17this case we wouldn't have to say player
- 33:20coins and then player uh gems and things
- 33:24like that because how we were accessing
- 33:26our data uh from this up until this
- 33:29point was basically have our data store
- 33:32and then have our key which was brawl
- 33:34battle uh and then we' basically do the
- 33:36same thing here but there's definitely a
- 33:38better but there's definitely a much
- 33:40better way of doing this by using Scopes
- 33:42to specify specifically what kind of
- 33:45data inside of our main data that we're
- 33:46trying to access so um if we're doing
- 33:49coins then what we're accessing for a
- 33:52key is going to be brawl battle and then
- 33:54the same thing is going to be said here
- 33:56so I think you kind of get the idea of
- 33:58what I'm trying to show you here with
- 34:00scoping this is essentially how we
- 34:03specify and organize our data stores
- 34:05when we're trying to work with multiple
- 34:06pieces of data that we're trying to save
- 34:09and so that's what I'm going to show you
- 34:10how to do uh right now so if we wanted
- 34:13to specify a scope of let's say player
- 34:16coins uh what we can do is we can first
- 34:19specify our player inventory to make it
- 34:21more broad so we're going to say Here
- 34:24Local player inventory equals data store
- 34:28service colon get data store open close
- 34:32parenthesis player
- 34:34inventory and now let's say we wanted to
- 34:37get the player coins coins being a
- 34:39directory of player inventory uh as the
- 34:43scope what we're going to do is say down
- 34:45here player coins equals data store
- 34:47service get data store this time it's
- 34:50going to be player inventory and we're
- 34:54going to pass in a second argument which
- 34:56is going to be our scope this is going
- 34:59to be our coins right here as our scope
- 35:01we're going to say coins simple as that
- 35:04so now we have access to our coins part
- 35:07of the player inventory and this leaves
- 35:10for more organization when it comes to
- 35:13our data stores that we're trying to use
- 35:15in our game and so everything here
- 35:17pretty much works exactly the same way
- 35:19it's just now we have an extra layer of
- 35:21organization with our data stores so
- 35:23that's a little quick tip that I wanted
- 35:24to give you for that so finally we've OD
- 35:28all the important concepts of data
- 35:29stores now let's actually put them to
- 35:32practical use uh inside of our game and
- 35:35what we're going to do is create a
- 35:37leaderboard for the Players when they
- 35:39join into the game and we're going to
- 35:41actually save the players coins and uh
- 35:44retrieve them whenever they join back
- 35:46into the game so this looks a little
- 35:47messy right now so I'm actually going to
- 35:49create a new script on the right side so
- 35:51on the right side let's disable our
- 35:53current script and let's add in a new
- 35:55one over here so we're going to call
- 35:57this player added and then we're going
- 36:00to first access our data store service
- 36:02which we can just copy from here and
- 36:04then paste it into here uh and then what
- 36:06we're going to do is access our player
- 36:09inventory with our player coins so we
- 36:11could just copy these as well and just
- 36:12put them over
- 36:13here and now what we're going to do is
- 36:15add in a player added event so we're
- 36:17going to say game. players. player added
- 36:21colon connect function open to close
- 36:23parenthesis player enter and now we're
- 36:26going to create our leader stats folder
- 36:28so we're going to say leader stats
- 36:30equals instance.
- 36:32new folder and then we're going to put
- 36:36this inside of our player so the parent
- 36:39is going to be set equal to player and
- 36:41then we're going to add in our coins
- 36:43leader our coins leader stat so we're
- 36:45going to say local coins equals
- 36:47instance.
- 36:48new int
- 36:51value and then we're going to set the
- 36:53parent of the coins to the leader stats
- 36:56and so now we have our leader setat but
- 36:59what we want to do now is we first want
- 37:01to fetch the player coins that exist
- 37:03within Roblox servers if it does exist
- 37:06so so what we're going to do is say
- 37:09local
- 37:11success current coins equals P call open
- 37:15and close parenthesis function open
- 37:16close parentheses enter
- 37:20return player coins
- 37:23colon get async open and close
- 37:27parentheses
- 37:28now up until this point we've been using
- 37:30a explicit key which is our name brawl
- 37:34battle but now you might ask we've made
- 37:37a player added event and we've added
- 37:38leader stats to our player so if we were
- 37:41to let's say have a player coins data
- 37:43store that we want to give the
- 37:45information to Roblox and send it back
- 37:46to us uh that's distinguishable from
- 37:49each player what's the key going to be
- 37:52ask yourself this question right now
- 37:54what would our key be for our specific
- 37:57play player if we were to designate a
- 37:59specific value to our player's key what
- 38:03would the player key be would it be the
- 38:06name I don't think it would be the name
- 38:08because if we had the player's name like
- 38:10brawl battle I could just simply change
- 38:12my name with with a 100 Rob with a th000
- 38:16robo to I don't know braw Dev and all of
- 38:19a sudden now when the when that player
- 38:20joins back into the game it's not going
- 38:22to be the same data associated with that
- 38:24player so what bit of information from
- 38:27the player can we use that will stick
- 38:30around for the entirety of that player's
- 38:32time on
- 38:34Roblox they user ID right their user ID
- 38:38is going to be the only thing that will
- 38:40stay within the player whenever they
- 38:43leave the game and then join back
- 38:45throughout their entire existence on
- 38:46Roblox well unless they get banned of
- 38:49course but they they they didn't deserve
- 38:51to play her game if they got banned in
- 38:52the first place anyway so that's not on
- 38:54us but with this in mind our key is
- 38:59going to be our player. userid and that
- 39:03is the key we're going to use for all of
- 39:05our data stores if we're deciding to
- 39:08save our player data this is going to be
- 39:10the key right here okay and we're going
- 39:12to check if this was successful so we're
- 39:13going to say if success then what we're
- 39:16going to do is set our coins int value
- 39:20so coins. Val we're going to set this
- 39:23equal to the current coins that exist
- 39:27ins side of the data store already we're
- 39:29going to set that equal to current coins
- 39:32and if it does not exist we're going to
- 39:34throw in an else and we're going to say
- 39:36coins. value equals z because this is
- 39:39going to be our default value and if it
- 39:41doesn't exist and if it does exists then
- 39:43we're going to set the coins value to
- 39:46what it currently does exist right now
- 39:47so what we can do to know whether this
- 39:49is working is by using increment async
- 39:53so that we can increment our value every
- 39:54single time we join to the game so what
- 39:56we're going to do is say local
- 39:59success updated value equals P call
- 40:03function open and close parentheses
- 40:04enter what we're going to do is return
- 40:07player coins colon increment async we're
- 40:13going to pass in our key which is going
- 40:15to be the player. user ID and then we're
- 40:17going to increment this by 10 every
- 40:20single time let's just say that as an
- 40:21example so if this was
- 40:23successful then what we're going to do
- 40:26is is update our coins. value to our new
- 40:30value that had that the datasaur has
- 40:33been incremented to so we're going to
- 40:34say coins. value equals updated value
- 40:39and so this is basically our entire
- 40:41script right here that we need to know
- 40:43that we need to do in order to test
- 40:45whether our leader stats is actually
- 40:46working properly or not so this is
- 40:49pretty much it let's go into the game
- 40:50let's hit test and let's hit play to see
- 40:53what happens when we join into the game
- 40:55okay there's one thing I forgot to do
- 40:56and that was to change the names of our
- 40:59leader stats and our coins my bad on
- 41:00that leader stats. name equals lowercase
- 41:04leader stats and then coins will be
- 41:06equal to uh coins. name equals coins
- 41:10simple as that okay so now let's go into
- 41:11the game and see our results now that we
- 41:14have this all sorted out properly okay
- 41:16so now that we're in the game um well I
- 41:19I joined into the game a couple of times
- 41:20so this doesn't really count but
- 41:22basically what ended up happening was
- 41:23that when I joined into the game it
- 41:25tried to fetch the information of coins
- 41:27that we had in Roblox servers and add 10
- 41:30to it since we joined into the game so
- 41:33it's currently at 30 let's stop the game
- 41:36and let's try joining into the game once
- 41:38again um to see our change so it's going
- 41:41to check if we have our um 30 coins
- 41:43first and then it's going to add 10 so
- 41:46first it was 30 and then it quickly
- 41:47added another 10 to it to now have it be
- 41:5040 and we can pretty much just do the
- 41:52same thing again if we leave the game
- 41:54and then join back into the game and you
- 41:56basically get the idea of how leader of
- 41:58how we can apply data stores to saving
- 42:00player data so this basically works
- 42:04every single time and we have now
- 42:06successfully saved our player data using
- 42:09all the information that we've learned
- 42:10about from this video uh and apply it to
- 42:13our Roblox games so this was a long
- 42:16video but this is one but I can't
- 42:19emphasize how important data stores are
- 42:21to Roblox games and how confusing it is
- 42:24if it's your first time using Roblox
- 42:25data stores so I hope this video gave
- 42:28you a really good insight into how data
- 42:30stores worked and it's okay if you still
- 42:33don't quite understand it well just yet
- 42:36it really just comes down to practice
- 42:37and the more you do it the better you
- 42:39will get at it so that you can
- 42:41successfully save player data within
- 42:43gameplay sessions before I end this
- 42:46video I want to say a couple of things
- 42:48about data stores that I think uh it's
- 42:51that I think are good tips to know about
- 42:52when you're implementing them is that
- 42:55data stores do have limitations you do
- 42:58somewhat have to be careful when when
- 43:00overusing data stores because roblox's
- 43:02servers can take in a specific amount of
- 43:06data before throttling it because
- 43:08there's just too much data overflowing
- 43:10within their servers so one tactic I
- 43:13would use for data store service is to
- 43:16instead of update the data store every
- 43:18single time that their coins change I
- 43:20would incrementally just save the data
- 43:23uh through certain sessions so what I'm
- 43:25talking about here is that I would
- 43:27probably have like a while true do
- 43:29statement here and then I would probably
- 43:31say like after waiting every 60 seconds
- 43:34we would try to successfully uh save all
- 43:37the data that's currently within the
- 43:39player or or things like that so we
- 43:42don't have to try and set the data uh
- 43:44every single time we update a value uh
- 43:46within the player we could just
- 43:48incrementally do save sessions
- 43:51periodically um to save the amount of
- 43:55time that we save our data within
- 43:58roblox's servers so that we're not
- 44:01overflowing their systems when we do
- 44:03that that's like a that's like a tip I
- 44:05can give for that another tip is to use
- 44:08Scopes in your data stores of course
- 44:10because it's very disorganized if you
- 44:12try to do get data store for every
- 44:15single bit of data that you're trying to
- 44:16save and so that's another thing I want
- 44:18you to try and get into practice of uh
- 44:21when you're using data stores and you're
- 44:23trying to save a lot of data what I
- 44:25would also try to do
- 44:27is try and use a table that can
- 44:31basically translate to the player's
- 44:33inventory so instead of having like a
- 44:36whole so instead of having like a whole
- 44:38data store as a scope for the player
- 44:40inventory what you could do instead is
- 44:43have a scope for let's say uh shop
- 44:46statistics or inventory statistics like
- 44:48I don't know specific sections of the
- 44:50player inventory that doesn't need to
- 44:53have a whole data store for instead what
- 44:55you could do is just have one table full
- 44:57of all this information to then have it
- 44:59be stored inside of one data store
- 45:01instead of all of these different data
- 45:03stores uh using Scopes cuz Scopes allow
- 45:07you to organize your data stores but if
- 45:09you don't need to use Scopes then you
- 45:11don't have to at
- 45:12all my general advice to this would be
- 45:15to use tables when you're trying to uh
- 45:17store multiple pieces of
- 45:20data that all sort of relate to each
- 45:23other that don't need to have different
- 45:25data stores for each single thing
- 45:27and so that's pretty much everything
- 45:29about data stores I hope you found this
- 45:30video to be extremely extremely valuable
- 45:33this I'm pretty sure is the longest
- 45:35episode inside of my Advanced scripting
- 45:37tutorial Series so if you can do
- 45:40whatever you can to support what I do
- 45:41with my channel and things like that
- 45:43because these videos are really fun to
- 45:45make but oh man these videos are getting
- 45:47harder and harder to make by the day so
- 45:50what's important to me is that you're
- 45:52watching my videos and you're taking in
- 45:54every bit of detail that I try to
- 45:56explain to the best of my ability uh
- 45:58with these videos that I tried to put
- 46:00out for the channel and I can't thank
- 46:02you enough for sticking around on this
- 46:04journey with like this episode that
- 46:06we're on like episode 18 or 19 and
- 46:08things like that I kind of just want to
- 46:10like say this a little bit before I go
- 46:11because I'm very proud of how far you've
- 46:14come with this series and and and this
- 46:18channel in general like I'm sending a
- 46:20message to you specifically the person
- 46:23who is watching my videos who is
- 46:25watching these very long videos of me
- 46:27explaining these things and putting them
- 46:29into practical use to become a better
- 46:31Roblox developer so that's just
- 46:33something I wanted to say now that we're
- 46:35we're at the end of the video this is
- 46:36probably one of my favorite videos that
- 46:38I've uploaded to this channel so I
- 46:39wanted to make it special so that's
- 46:41going to be it for data stores if you
- 46:42want to learn another somewhat confusing
- 46:45topic like C frames I made a video on
- 46:47that not too long ago so I encourage you
- 46:49to watch that video that I'm going to
- 46:51have for you right here if you haven't
- 46:52already but with that being said I will
- 46:54see you in the next episode take care
About this transcript
This page contains the full transcript of DataStore (Saving Player Data, pcall(), Scopes) - Roblox Advanced Scripting #17 by BrawlDev, generated from the public captions YouTube serves with the video. The transcript has 8,897 words across 1,167 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 choose a caption track available on the video.
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, caption language selection, AI prompts for ChatGPT, Claude, and Gemini, and exports to TXT, SRT, VTT, or Markdown.