How to Save and Load your game | The Basics | A Godot Game Engine Tutorial

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
progress your way through the different types of enemies that appear and figure out how we're gonna save them all right to download the project all you have to do is use the link below in the description it's gonna bring you to this page this is just the main save and load project the main branch is fine should be the starting point of the project to get started all you have to do is click on this code button and click download the zip if you just want the file you can also clone if you want it it's up to you once you've opened up the project you'll see something like this open up this block dodge folder go to screens open the save and load example tscn we're going to press f6 wasd or wasta keys are used for moving your block around your goal is to dodge all the flying blocks coming to hit you the progress increases these red blocks come out of nowhere and you're trying to not die but if you do die you're given this game over screen and the load last save button does not work let's go ahead and get started saving let's go ahead and open the save and load example.ge script file there's a lot of code in here you don't have to worry about pretty much any of it in fact we're going to scroll all the way to the bottom and then we're going to go in here and newline this and create a new function and we'll call it save then we're just going to set up paths we got our save function stubbed out let's go ahead and stub out our load function which you cannot use load because it's a reserved word function load save colon and we'll just pass there first thing we want to do is figure out how we're going to save and where we're going to use file directories and put it into just a save file put this in a directory of its own and not mixed with other files to get started let's create a new variable call it der directory equals directory dot new we need to check that the save file exists because it could be the first time they're running the game if not the directory dot directory exists for a user and slash slash save and if this is the case directory go ahead and make us a directory and let's use that same path now a quick note on these uh this user path here that is different based on windows linux and mac i will post a little image screenshot of the different directories here just note you can also customize this in the settings go ahead and get rid of that pass now we're going to say hey i want to save my game is a file new let's go ahead and try to open it save game dot open we're going to use that same file folder structure this time we're going to say gamedata.savefile.right and then we're just going to define a variable where we're going to store the save data in this case it'll be a var save data equals just an empty dictionary we're going to come back to actually saving players and enemies right now we're just trying to make sure that the framework is in place so that you can scale it to all of your entities in the future go ahead and leave a comment to do then take the save data convert that to a string so that we can then save that down to a file var data string equals var to string this is a handy utility method that takes any variable and turns it into a string we're going to reference our save data object we're going to say hey save game file let's go ahead and store string data stream say save game dot close now let's go ahead and step out the load save method we can get rid of this pass we're going to create a variable which is the save game file dot new if not save game dot file exists user slash directory and the same file game gamedata.save the column at the end print there was no save file detected now that we have a file save game dot open user again save game data dot save file dot read we're gonna do the same actions we did to save it but in reverse data stream let's go ahead and get the save games text get as text save data is a dictionary there is a string to variable method that allows us to take that data string and turn it into a dictionary we can even print save data and we can now save game dot close because we do not want a memory leak we can test this and let's go ahead and save coin test we should see that shown here these methods are not being called yet so let's go ahead and in the on ready let me put it in the front here load save to add the save we just need to put it in a place that makes sense we're gonna put it on this on progress timer timeout after the progress has increased for the player go ahead and just save it'll save for every percentage tick which isn't a bad idea but it's not perfect either now we're gonna run this that's interesting it doesn't tell me it's wrong but this is file dot read with caps lock but it didn't give me an error how interesting let's try this again notice a file detected we get killed by the red bar of death and look there it is a save test next we're going to talk about saving the player now i know i said we would go right into saving the player but there is one tiny optimization we're gonna need to do that is to really notice when you end up repeating yourself we're using the user save and user save often here and there's a chance you could mess up one of the spellings like uzier instead of user and then your whole save system will not work to protect you against that best put these in a constant so then you can change it one place and you don't have to change it in three to five places later go ahead and copy this user save bring it all the way up to the top here create a new variable and let's call it the save directory and then copy this down [Music] come down here we're going to replace the save directory and let's save here this game data save let's copy that come up to the top like we did here and let's go ahead and make it a save file gamedata.save come back down here string and then we're going to say save directory comma save file now it's cleaner you know this is the same directory it's opening the save directory with a save file and now you can just copy this and paste it everywhere you'd like and now it's in one place and it's reusable if we go ahead and run this you'll see that everything still works game didn't crash you still die like normal and the save test is still being loaded properly let's get on to saving the player to add saving to your player we need to open the actors folder player.tscn file and all we're going to do is come over here to the node tab by the inspector we have to select the player root node and then you see these signals and groups we're going to click on groups and in this little box here we're going to add the word savable now that that's done click on add save the file now go to the script and make sure you open the player.gd or you can double click on the player.gd file here and similar to what we did in the save and load example file we're going to create a new function in here and we are going to call it save we're going to return progress progress dot value get the position on the x position dot x position y position that y and then just to make the indentation clean you can kind of set them up like this now let's come down here and let's copy that same load function from the save and load example and call it load save this time we're going to do something a little different because we're expecting to get data from that save and load file what we care about is then just some data that's going to be passed over to the player that data could be null it could be bad data first thing you should do is just check if not if not data then just return we're not even going to try to load anything if the data is invalid uh to get the data back out we're actually expecting it to be in this same exact format progress dot value equals data progress and this is the key that we created here and we can do the same here we can say position.x equals data position x position position dot y equals data position y this wraps up the player side of implementing a save go back to our save and load example let's go back to the save method here now we want to get the save from our player we see the player here and we notice that the group is there so we can get rid of this test because we don't need it now we need a way to get all of the objects that are subscribed to the saveable group bar find savable nodes and we're going to get the tree we're going to get the nodes in group and we're gonna make it savable for savable and find savable nodes now we've got all of the nodes that are going to be saved if not savable dot has method save savable node is missing a save function skipped continue we then get to use this save data object save data saveable dot name player in this case equals savable dot call save this is going to call the save method return that dictionary we created put it into the save data we can actually test this before we even worry about loading it to the player again we can run this instead of save test we're gonna see player their position and the progress come through here get hit die hit start over player their position and the progress being five we now need to say if the save data has layer which i've already done here then we can say player dot load save and then just pass it save data with player if we run this f6 notice that it saved us at five percent loading last save doesn't do anything yet but if you start over notice that our progress is there our position was saved that moves us to our next section which is hooking up this load last save and truly making the start over button start over the scene now that we have saving our player done we have ran into the issue where every time we click start over it's loading the save we now need to distinguish the difference between a start over and loading the last save to do that we just need to come over to the game over screen which is this gameover.tscn file and you can see it here has load last save start over and quit the associated code is in the gameover.gd and you'll notice it says uncheckpoint pressed that's only because when i was first building this i figured i was going to build a checkpoint system i'm just trying to make it really simple uncheck point pressed is the same as clicking on load last save the onstart over pressed here reloads the scene and on that on ready function it loads the save file which then acts just like load last save so all we need to do to make load last save work is actually do the same thing that start over is doing so we can copy this method and replace pass with that method and now load less save is working the last thing we need to do is make this start over delete the save files that we have we should just create a new method and we'll call that clear save data as simple as that function doesn't exist because we need to come on down here create a new function called clear save data and then what we're going to do to clear the save data is just find the directory where our saves are held and just delete all the files that are there this way if you have multiple files you can just delete them all here and you don't worry about it blowing away any other important files you might need which is why i always create a save directory so let's go ahead and say variable der for a directory make a new one of those next we need to make sure that the directory exists because you don't want to run into an issue where they load the game for the first time and there's nothing to delete and it fails so to get around that we just say if directory can open our save directory and this ok check here lets us know that yeah i can open it the directory system can say yep it's fine i got this now that we've opened the directory let's go ahead and get all of the contents of that directory to do that we say directory dot list the directory again which really just starts streaming in all the data that's within the directory and we only care about the files within this current directory so we can actually skip some navigational items by saying true feel free to look up online what that does exactly and it makes more sense next we want to get the actual file name within the directory so we say hey equals directory dot get the next one uh in our case that will be the only uh file in this folder but if you had multiple files this would go through all of them while the file name does not equal any string let's go ahead and then just say hey directory let's go ahead and remove this file and we can use what we did earlier and do string user slash save slash comma file name so now that'll delete every file in this directory and then the last thing we need to do is take this file name and get the next object in the stream and there we go you have successfully cleared all of the data so we can test that out real quick go into f6 do it from the game over screen let's say we start over here we're at zero that's great we're in the center if i come down to the corner and load last save i should be in this corner and there i am granted the enemy's not saved yet but that's what we're on to next before we dive right into saving them let me explain these enemies the red blocks that come down and try to hit you and you have to move out of the way after you hit roughly 20 the blue style of these enemies show up but this time they appear on the left and they come towards the right and you have to dodge those and the red ones coming from the top and then roughly around 45 50 percent we have these red square enemies that rotate and are just flung right in your direction trying to hit you these are all spawned in and dynamic open up the actors folder click on the enemy long.tscn file if you look at the 2d view this is that red enemy we saw click on the enemy long click on the node that's savable there's not like a blue enemy long that's because the blue ones are actually this same enemy they're just rotated 90 degrees and they're colored blue by saving it here we account for both types then this enemy rect we do the same thing make sure you're in the node click on the groups put in savable let's go ahead and open up this enemy's script file add the save and load data methods like we did for the player function save return a dictionary and if you ever want to know what you should be saving you can just look at the variables that are defined and either just save those or look to see in the code what gets transformed i'm just gonna fill this out real quick and you're gonna see it when it's completed power of editing you didn't have to watch me type all that just did these primary variables do the same for load save and we're going to pass in that data object we're going to always say if there is not any data just return let's be safe just like we did for the player we're gonna just load the data like before i'm gonna go set this up real quick and i'll be back in a moment hillary deposits just like the player we're setting the position the trajectory based on the data set we're gonna move over to the enemy long script file we just need to know what's changing between the variables and the functions so position rotation color function save turn a dictionary free to pause the video and then enter the values of the save dictionary and let me know if you prefer this versus me typing it out i want to try to strike that balance now that we have the save data of the enemy there's one more thing we need to do that's different than everyone else in the save and load example scene there are two containers the top container and the left container this enemy can both be red and come from the top and be blue and come from the left we need to account for that when we're saving our data so we know how to bring it back and put it in the right container all we need to do is go and add the parent name to the save data so we can just check which one it should belong to come in here and add let's just add parent name to the save data here get parent dot name we need to add the load save with the data i'm gonna really quickly skip through this and you can see it in a second the setting of the data here looks familiar the only difference here for the color the black color is a color object we're setting the red green and blue we just want to make sure that the two different color wrecks are set to this new color let's head back to our save and load example here and now we're going to finish this up and here's a cool part we don't need to add anything to our save method it's done just by adding that group saveable to the node it now automatically calls that safe method we defined we don't have to worry about that anymore now we just need to worry about loading the data now we know that these are dynamic and everything that gets saved is gonna need to have to be created and added to the scene tree we can actually just find out how many nodes exist in this saved data object and then just create a node for everyone that's in there now we don't need to create one for the player because we have already created them by this load save we don't need that data anymore in memory save data dot erase the player now we can iterate through the data set within the dictionary pretty easily and it'll be by the node's name which is perfect for when we need to create the node in the scene for node name in the safe data get all the keys now we can check to see if the name of the node matches which enemy we're wanting to load in this case let's just load that flying square there's no extra which container does it live in logic they have to worry about if enemy rectangle in node name bar entity equals null entity equals enemy tangle dot instance enemy container top dot add child entity entity dot load save from the save data for this node's name let's now take care of the other type of enemy enemies long in node name set up a new entity the entity the enemy long instance it now we need to determine which container does it live in is it in the left or is it in the top to do that we need to actually get the safe data create a new variable we first need to make sure that the parent even exists in the data set if not save data for the node name as parent name let's just skip create a new variable call it enemysave data get the save data for the node if top in enemy save data for parent name enemy container top at child entity else enemy container left but mad child entity entity dot rotate degrees and color vector 2 dot right break out of the if else and just say entity load save enemy save data disable both use the save data let's take it for a spin i like to start on the game over screen just to start from a scratch just in case there is any save data that we just want to clear out we've got these enemies here and if i get killed by this one now i should have a chance to try again load last day there we go and nice save obviously there are ways to improve the when it should be saving but this will get you going to save your data that's saving for json dictionaries i hope you learned something new today hit that like button if it was helpful it really helps me know that these tutorials work or are useful it really helps me and i appreciate it subscribe for more content especially when part 2 drops and as always stay safe stay awesome and i don't know maybe check out this video it might help you
Info
Channel: Hex Blit University
Views: 386
Rating: undefined out of 5
Keywords: programming, coding, godot, godot tutorial, godot engine, godot tutorial 2d, godot games, game development, saving data, game development process, godot engine tutorial, godot engine 2d game tutorial, game development course, godot save and load game, godot save game, godot save scene state, save game tutorial
Id: _ZiVYuTw2Fk
Channel Id: undefined
Length: 24min 35sec (1475 seconds)
Published: Fri Oct 15 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.