Hey man, I know that it's almost 5 years later but these videos still help with a basics understanding of things. Seriously helping me a lot with my first skill tree and having my controller remember what has been learned and not learned. Thanks again!
Dude, you are absolutely the best thing to happen to the UA-cam Gamemaker community in a looooooong time. Those subscribers are well-deserved. Keep it up! On a more related note, I'm just about finished with an in-engine level editor for my current project, so this tutorial came out at a great time. Thanks! :)
Great stuff. The levels in my game consist of multiple rooms, and I obviously don't want all enemies/collectibles to respawn if you re-enter a room. This solution solved the entire problem of checking whether something has been collected/defeated before and if it should respawn.
I am ADDICTED to data structures. I VERY rarely use arrays anymore. But, it really comes down to coding style and what you want to do with the values. All a data structure is is an array with functions built around it to work with the data (not really, but it's a good way to think about it). If the way you are working with the data is built into a specific data structure (such as shuffling in a ds_list, or adding a block of values in a ds_grid) then you should definitely be using a data structure as whatever you are doing is likely slower than the built in method. Thanks for watching!
Awesome video! I was able to adapt the code to my needs; Instead of using "ds_map_secure_save", I was able to save the ds map inside a json file along with other variables.
Yeah, this tutorial is ancient at this point. You shouldn't be using ds_maps or ds_grids at all anymore. maps should be structs, grids should be arrays of structs or arrays of arrays, etc. And then you can just json_encode the whole structure and save it to a file with like 2 lines of code.
Man I wish I could hire you to work on my game with me. But at least we've got these awesome tutorials. Thanks for putting so much time and effort into these.
great video, so glad I found this. this is exactly the kind of save system I was hoping to find before I got too far into building games. hope to see more amazing tutorials from you.
who knows gms 2 might have better save options it looks like its heading in right direction in development yoyogames have done a fantastic job cant wait to see how gms2 grows next year into stable. Thanks again
thanks Pixelatedpope for the feedback yes sadly everytime i do any update evn just change a color of a sprite(anything) i do lose the ini data its a real pain ill keep a eye on forums and youtube in the future to find more about why this may happen with ini files. Thanks again.
Thanks alot for this ( and all the other) really great tutorial. I really love watching them and I'm always amazed how you manage to explain that much very clearly in such short a time :) One thing I wanted to add to this video: There are occasions when saving stuff in an ini file is handy. i.e. if you want to save game settings and have the option to change those from outside gamemaker studio. Maybe you even want to allow users to manipulate those ini files :)
As far as I know, ds_map_secure_save/load functions only work in the same computer. If you save a file in computer A and try to open it in computer B, it won't work. That's not very handy when you want to save data on the cloud and have it available in any computer (ex: Steam Cloud). At least, that's how it worked time ago. I don't know it that behavior has changed in latest GMS updates.
Yes, you could save data from your map into a INI file, and encrypt that file. You'll have to make your own function for reading your map structure and store the data in a convenient way into the INI file. Also the contrary, you'll have to make a function for reading the data from the INI file and store it into a map. For encryption/decription of the file you could use an asset called Protected INI (marketplace.yoyogames.com/assets/1351/protected-ini) available on the Marketplace. This way of storing data is multiplatform.
This is completely out of the scope of the tutorial. The point of the tutorial was so you don't have to use an INI, which he even stated. It is not ds_maps that are the problem, but the secure functions.... so don't use the secure functions. It's also kinda messed up that you are using someone else's tutorial as a means to advertise your marketplace preferences.
if you guys happen to experience in issue with getting keys to be unique to the instance like I did a couple days before, I would recommend object_get_name(instance_id). your welcome.
This. Is. Magnificent. Thank you so much for the work you put into this! "Of course not - that would be horrible!" ... This is pretty close to the method I was using to save important instance states and other information, haha! *facepalm* So glad I found your channel!
First off thank you for this tutorial. This is the first one that's made saving my game understandable for me. This is probably a long-shot given how old the tutorial is, but is there anyway to get an updated drop-box link for the Example Project? I'm curious how you were saving other character data, but the link doesn't seem to work anymore. Thanks again!
11:40 How is saving the x/y values integrated, exactly? I tried putting this in the step event: ds_map_replace(o_game.save_data,x_key,true); ds_map_replace(o_game.save_data,y_key,true); And this in the Create event: if !is_undefined(_x_data) x = _x_data; if !is_undefined(_y_data) y = _y_data; But when I load the save, the object's x/y values seem to default to 0, i.e. it spawns at the top-left of the room.
Thanks for this. What is the encryption like for this? I see in the help index you can use a .json extension. Do you use this at all on your games? Just wondering if it's good enough to keep the average Joe from easily changing the file to get items and stuff.
I have yet to touch any json stuff yet, but the encryption is good enough to keep the average joe out. Especially compared to using an INI file that I know a lot of users use for save data.
Hey there! This is a really great video! If you can for further have the big icon set on and maybe have the big fonts/zoom in codes so it's easier to see what you're doing, this is just a feedback ^^
...huh. I've been using ds_list to keep data for objects like locked doors, keys, bosses, and other stuff based on the assigned rooms. It works, but only if there's one object type per room. This might help a bit better. Thanks!
Can't the key be the Instance ID that Game Maker creates for each individual object instance??? That way if you have two of the same objects in the same room, x and y it would still be unique.
If you want to trust that, I suppose that would be okay. I haven't used the room instance ID very much so I'm not sure how it is generated or if it ever changes as you make changes to your room or project. I guess if you set the ID/Name yourself that would be super safe. So, yeah, good suggestion!
I know this tutorial is pretty old at this point, but I've run into an issue that I can't figure out. No matter what I try, when I try to load the data after just starting the game, it takes me to the next room. I can't figure out what could be causing this. When I save the game and reload, it works fine, but when I close the game and try to reload right away, it takes me to the next room. I really don't understand
@@PixelatedPope I appreciate the response! I meant that when I hit “load” it takes me to the next room in the room tree. In any case, I decided to try out json saving and loading based on shaun spaldings tutorial.
Be sure to check the follow up if you feel like this doesn't quite fit your needs. If you were using persistent rooms, you may be wanting to save a LOT more information, which is covered in the next vid.
You briefly mentioned what you would do if you needed to save the position of an object. I have an object that gets created at a random position with a random scale and there could be multiple in the room at once. How would I go about saving / loading that? I have tried all I can and can't figure it out! They are created after game start. Thanks!
That's going to be more difficult. You won't be able to save that object's stuff with a "tag" based on it's position, obviously. So you'll need to give each item to be saved a unique tag. You'd probably need to go into more detail about what, specifically, you are trying to save and the rules around how it is spawned and when it shouldn't come back to give more help.
Its basically a randomly created poop object, im making a virtual pet game. It is created at random with a random scale and position. The only way to remove them is to click them or to press a button that washes the screen. Other than that if theres any onscreen when saving they should obviously reload with the correct position and scale. I couldn't figure it out though :/ Thanks.
Yeah. That's gonna be tough, but it's not impossible. Essentially, in your save data, you need another data structure of some sort. This is sort of nuts, but you can create a ds_grid and then use ds_grid_write to write to your ds_map and save that grid along with the rest of your save data. Here's the basic step. Keep in mind this is not something you'll want to do every single step. Try and only do this when you need to save or load. 1. In your save data map, have an entry for "poops" and default it to "". That's an empty string. If there is ever save data here, it will be in a string format. 2. When saving, create a new ds_grid. for each poop in the room add a new row and store the x and y position in column 0 and 1. So if you have 5 poops you should have 5 rows with the x and y values for each. Once you have the grid, use ds_grid_write() to turn that grid into a string and store it in your ds_map under the "poops" key. Then destroy the grid. 3. When loading, see if save_data[?"poops"] == "". If it doesn't, then there is save data there, and you should load it. Grab the string, and use ds_grid_read() to shove it into a fresh ds_grid. Loop through the grid and create each poop. Once you are done, destroy the ds_grid. If your poops eventually get more complex, like varying degrees of smelliness or other disgusting attributes, just add more columns to the grid and grab those values along side the poop's posiiton. I know this is really complex, but I hope this has been helpful. If you need more help, I recommend joining the /r/gamemaker discord group. Lots of very smart people there who can help you with problems. discord.gg/By6u9pC
Yeah I actually thought about that, I'm just new to data structures and didn't know where to start. I think for now i might set this feature out differently but in the future I'll try to sort it out. Thanks again for the responses.
This tutorial I wrote is a little old, but it's a good place to start. www.reddit.com/r/gamemaker/comments/1vzdug/tutorial_gms_gml_data_structures_part_1_crash/?st=iylrw1gz&sh=9059be5c
So I have a setup where when the game starts there is a room that initializes all of my controllers (ScreenResize, save data, menus, etc.) and then goes to the next room. But I am having an issue where only one of my controllers is being brought to the next room (My screen controller) so the game crashes because one of my objects is referencing GameManager which acts like it isn't there. What would be the most efficient way of making sure all of my controllers are being initialized properly? Also all of my controllers are marked as persistent.
Interesting. So you would expect an instance of GameManager to be there, right? In which event is the code where it crashes? Have you set a breakpoint and checked your instance list to make sure an instance doesn't exist?
Actually kind of embarrassing, I forgot that I remade the initialization room and forgot to replace the instance of GameManager in there. I originally thought that only ScreenController was getting passed to the next room because it's the one handling the transfer to the next room. But a followup question, I saw that your zelda project had a script that initializes all of the necessary items in your ds file. If I were to put this in my GameManager(that is created everytime someone starts up the game) would the constant creation of ds files result in a memory leak? Or would it just be overwritten when I load the ds file?
Data structures are cleared when the game is closed, so as long as you aren't constantly creating data structures while your game is running, then don't worry about leaks. That being said, if you are using "game_restart()" anywhere in your game, you MIGHT have a problem with a memory leak, as I don't think created data structures are properly cleaned up (but all your variables that held the IDs of those structures have been. If you are using game_restart() I recommend not, and creating your own "exit to main menu" script that properly cleans things up, destroys data structures and other dynamically created resources, etc.
My entire game has this save system, but I ran into a problem. I will change hard drive and go to a new pc, is there any way to find the save file? I do not see it anywhere
Nope! Two issues: 1. Save data is always on the pc you played the game on unless you are using a cloud save service, like Steam. 2. And even if you did, or if you went into your files, found the save file, and copied it to another PC, it wouldn't work because of the ds_map_secure_save and ds_map_secure_load functions won't allow it.
Does the file extension matter? or does it just open it the same way anyways, I wanna make mine something ridiculous so people might be more inclined to leave it alone, or maybe not even recognize it in the first place.
And, Is it possible to keep a DS_Map without an Object? For Example, If I create an Object that contains the Game manager and I destroy that Object, Do I still have access to the Map Like a Global Variable, or do I lose the Map and get a error?
Think of data structures like their own instances. When you do instance = instance_create(x,y,obj_player) you are creating an instance of object player. And even if you destroy the object that created it (and has the variable "instance" in it) the instance still exists, you've only lost the variable that has the "address" to find the instance; it's ID. Data structures are the same. When you say variable = ds_map_create(); You are creating an "instance" of a ds_map object type. And unless you destroy it, it will hang around forever. And if you lose the "variable" variable that holds the address to that specific ds_map, you'll have a hard time finding it to clean it up when you are done with it. This is causes a memory leak, especially if you are rapidly creating data structures as needed without destroying them. tl;dr Yes. The ds_map still exists even if you destroy the object that created it. Make sure you keep track of the value returned from ds_map_create() so you can destroy the map when you are done with it.
Uhh... what do you mean your key is a list? That's not a good thing to use as a key. You want your key to be static and predictable as often as possible, and the ID of a data structure is not static.
Can I just use an INI file with the DS map, then Encrypt ( *However Game maker Calls it.* ) the INI file so people can't Modify it, or Don't know how to...?
I suppose so. Instead of using ds_map_secure_save/load you would just us ds_map_write/read to output the data structure to the INI file as desired. This is the recommended method especially if you want to support cloud saves or any sort of save transferring.
Basically the same reason you can't use the room ID as I explain in the video. It's unreliable. Instance IDs are not GUARANTEED to be the same every time your run the game, especially as you are still developing it. If you add/remove an instance to your room or change the order of the instances, you run the risk of breaking all existing saves. This would especially be a problem if you are patching a released game... you could break all of your player's save data, which is obviously not good.
Well I was using the method for the death count and to keep enemies dead. I'm going to change it to use Ids but then use it to determine if a certain area was complete and then have the save data go by areas completed rather then all individual enemies.
Oh, and thanks for the quick reply before. I have to say out of all of the youtube videos out there that I've watched since I've started using GMS. You're videos are the best for a few big reasons. You obviously know what you're going to say BEFORE you make the tutorial and you know how to speak. You explain things very well and in simple terms. Of course my biggest thing is the whole video isn't just GMS screen open while you talk.
Thanks! Yeah, I put a lot of effort into planning, scripting, recording and editing to make sure that you don't spend 30 minutes watching a video that could be done in 10. Always glad to hear the effort is appreciated. Thanks for watching.
Absolutely. But instead of using ds_map_secure_save/load you'll just use ds_map_write out to a standard text file. Don't worry, give it a shot and then go and open that text file... it is not exactly easy to read or edit for a player, so it won't make it easier to cheat.
No worries. Yes, game dev is tough. Programming in general is tough, and games especially are difficult. It never really gets easier because as you learn more, you push yourself into more unknown territory. So the things you struggle with now you will stop struggling with, but you never stop struggling all together.
hi Pixelatedpope looks like a good tutorial ive never used ds saving before. i use ini speaking of ini im happy with ini files but whenever i update my game sadly my ini files saved data is always lost its a pain because it means i cant update games in googleplay without players having to start fresh with saved files each update so i have a few questions 1.are you at some stage be making a ini tutorial or 2. with ds saving would my players have the saved files lost each time i update my games, and 3. Are you at some point going to dive into teaching about how we can cloud save data i have not seen ANY tutorials on youtube that teach cloud saving(its the future) i would like players on googleplay or whatever to be able to not worry what device they have saved game data on because they can install the same game on tablet and phone and just pickup from the saved place they left of on whatever device they play the game on. Thanks again for the tutorials .
Great questions. 1. I honestly have never used INIs (never seen a need for it) so I'm not sure what I would be able to add that other tutorials out there don't already cover. 2. This SHOULDN'T happen. The only way to invalidate your save data with a map would be to move something in the room editor in your update. But even if you do that, you could just manually type in the key that would have been generated for that specific instance. Releasing an update that changes save data is always going to be a complicated problem, but you shouldn't just flat out lose your data by releasing an update. 3. Cloud saving would be really cool, but again I have no experience with it myself. My understanding is that this method for save data is NOT suitable for cloud saving (as secure save/load seems to use a local machine salt or something to "secure" the data). Instead apparently you are supposed to use JSON maybe?... a bit outside of my expertise. But it's still a possibility for the future. Thanks for watching.
The instance ID is something that is generated at run time (unless you are talking about the instance name that gets set in the room editor). As such, it is not reliable as the next time you run the game, instances will be created in different orders and those IDs will no longer be the same.
I followed the tutorial and it almost work. It work as long as i don't close the game.When I close and open it my value are set to undefined. It's like my file get reset. Anny idea of what goes worng ? I realy don't understand since i used this in another project and it worked fine.
Yeah, I can't tell you exactly what's going on without being in your project, but this is likely a problem with your loading code. To make sure, use the debugger to set a breakpoint right before the ds_map_write() call and observe the values of the map. Then, set a breakpoint on the ds_map_read() call and observe the values coming back in. If the values in your map are correct before the write, and the values are incorrect after the read in... then something screwy is going on...
Thx for you quick respond. I wanna say your tutorial are graet bye the way! So i did what you told me the value is still the same when i save and load until i close the game then it become undefined. One thing wird is that if i set a breakpoint on the ds_map_read() it just skip i have to set it a litle farther. it all in a scrip. At the end of the day i think it's over complicate for my needs all i whant is to save the progression in a tower defence and that's it. Sorry for my bad english it's not my first language.
No worries. If you'd like me to look at your project, you can export your project (file > Export project) and send me that file and I'll see if I can see what's going wrong. You can also join my discord and get help in real time if you'd like. discord.gg/CjcB2R
Great video! What is the difference between this and Shaun Spalding's JSON system ( ua-cam.com/video/QmxQb1BFQRE/v-deo.html )? I am asking this because I am kinda new to Gamemaker and I don't know which system to use, and which is better for my game.
I haven't actually watched the Shaun Spalding video, but if he's using Json_encode and json_decode, then that's probably the one to use. I'd like to create an update to these two videos once v2.3 releases as there are a number of things I would have changed.
@@PixelatedPope Yes, he did use json_encode and json_decode, but he did that video two years later than you, so I can't really compare the two systems:) Thank you for the quick reply!
So I've changed my local example project to use touch to switch rooms and it all worked great. So the system itself works great on android, but the example project that is currently in the description doesn't allow for switching rooms on android. That's simple enough to add to the step event of obj_game manager right below all the keyboard_checks if(device_mouse_check_button_pressed(0,mb_left)) { var _margin=50; if(device_mouse_x(0)room_width-_margin) _right=true; else if(device_mouse_y(0)room_height-_margin) _down=true; }
oh sorry for not clarifying the problem from the beginning ... the problem ihave is with the saving system when i compile with windows it works well, if i close and run the game again it loads the data , but when using android compile if i close the game and run it again, it dose not load !! i dont know why ... should i create target executable or it should just work on the compile mode ? and am really thankful for your reply
I'm honestly not sure. I've never taken the system that far. It may be related to how GM "sandboxes" data on Android depending on if you are using the compiler or not. I imagine once you create an APK everything should work fine.
Room persistence is essentially "baby's first save system" and is really, really resource heavy. Also, how do you save everything when you close and re-open the game? That room may be persistent, but only for as long as the game is running. You could do "game_save" and "game_load" but this is the same problem. It's essentially a save state and removes all control from you.
Excellent video.
Hey man, I know that it's almost 5 years later but these videos still help with a basics understanding of things. Seriously helping me a lot with my first skill tree and having my controller remember what has been learned and not learned. Thanks again!
Dude, you are absolutely the best thing to happen to the UA-cam Gamemaker community in a looooooong time. Those subscribers are well-deserved. Keep it up!
On a more related note, I'm just about finished with an in-engine level editor for my current project, so this tutorial came out at a great time. Thanks! :)
Thank you! Hopefully you can make use of this system in your project.
Omg you have no idea how much time you have saved me. I was making huge scripts to save/load each important variable of my game. Thank you so much!
Same here. I was making a really elaborate script to save enemy alive/dead states and this just saved me a bunch of work.
Great stuff. The levels in my game consist of multiple rooms, and I obviously don't want all enemies/collectibles to respawn if you re-enter a room. This solution solved the entire problem of checking whether something has been collected/defeated before and if it should respawn.
Never heard a tutorial more clear in my life, many Thanks :)
Thanks for this short, straight to the point, and very informative tutorial. I was able to implement a simple login system with this video in GMS2.
This is the first thing I ever seen that convinced me to use a ds besides having to use it for Asynchronous events . Nice video :).
For my purposes, there is probably a lot of situations where DS's are probably better to use than array.
I am ADDICTED to data structures. I VERY rarely use arrays anymore. But, it really comes down to coding style and what you want to do with the values. All a data structure is is an array with functions built around it to work with the data (not really, but it's a good way to think about it). If the way you are working with the data is built into a specific data structure (such as shuffling in a ds_list, or adding a block of values in a ds_grid) then you should definitely be using a data structure as whatever you are doing is likely slower than the built in method.
Thanks for watching!
It is really good to see someone do something different to everyone else's save system, keep up the work!
i liked your way of explaining things, very organized and crystal clear, Many thanks for your great videos
Exactly what i was searching for. An obfuscated save data method is wonderfull.
Awesome video! I was able to adapt the code to my needs; Instead of using "ds_map_secure_save", I was able to save the ds map inside a json file along with other variables.
Yeah, this tutorial is ancient at this point. You shouldn't be using ds_maps or ds_grids at all anymore.
maps should be structs, grids should be arrays of structs or arrays of arrays, etc. And then you can just json_encode the whole structure and save it to a file with like 2 lines of code.
Another great tutorial that I will be implementing into my game! It's super helpful to see how you manage variables in your resource files
Man I wish I could hire you to work on my game with me. But at least we've got these awesome tutorials. Thanks for putting so much time and effort into these.
I wish I could hire myself for my own games! lol. Thanks for watching!
great video, so glad I found this. this is exactly the kind of save system I was hoping to find before I got too far into building games. hope to see more amazing tutorials from you.
I love these cause its hard to find videos about background work which is SO importand!
who knows gms 2 might have better save options it looks like its heading in right direction in development yoyogames have done a fantastic job
cant wait to see how gms2 grows next year into stable. Thanks again
Super cool tutorial! Thanks for explaining everything so clearly!
thanks Pixelatedpope for the feedback yes sadly everytime i do any update evn just change a color of a sprite(anything) i do lose the ini data its a real pain ill keep a eye on forums and youtube in the future to find more about why this may happen with ini files. Thanks again.
these video still help
Huge thanksssss
Awesome tutorials! Keep up the great work, you deserve every new sub!
Thanks alot for this ( and all the other) really great tutorial. I really love watching them and I'm always amazed how you manage to explain that much very clearly in such short a time :)
One thing I wanted to add to this video: There are occasions when saving stuff in an ini file is handy. i.e. if you want to save game settings and have the option to change those from outside gamemaker studio. Maybe you even want to allow users to manipulate those ini files :)
Really clear and helpful. Thanks
Would this method work for an HTML5 only game?
Yup!
Thanks for this, man. Good stuff.
OMG! i've been searching for two days and doing trial and error coding and thank you tahkn you!
Glad you found it helpful.
Such a great video. Thank you so much.
As far as I know, ds_map_secure_save/load functions only work in the same computer. If you save a file in computer A and try to open it in computer B, it won't work. That's not very handy when you want to save data on the cloud and have it available in any computer (ex: Steam Cloud). At least, that's how it worked time ago. I don't know it that behavior has changed in latest GMS updates.
Do you have a suggestion how to otherwise do it?
Yes, you could save data from your map into a INI file, and encrypt that file. You'll have to make your own function for reading your map structure and store the data in a convenient way into the INI file. Also the contrary, you'll have to make a function for reading the data from the INI file and store it into a map. For encryption/decription of the file you could use an asset called Protected INI (marketplace.yoyogames.com/assets/1351/protected-ini) available on the Marketplace. This way of storing data is multiplatform.
Okay, I know where to start then. I think.. Thanks!
By the by, Bot Vice is great!
You can use ds_map_write and ds_map_read.
This is completely out of the scope of the tutorial. The point of the tutorial was so you don't have to use an INI, which he even stated. It is not ds_maps that are the problem, but the secure functions.... so don't use the secure functions. It's also kinda messed up that you are using someone else's tutorial as a means to advertise your marketplace preferences.
thank you for gamemaker video
Really nice and helpful.
if you guys happen to experience in issue with getting keys to be unique to the instance like I did a couple days before, I would recommend object_get_name(instance_id). your welcome.
This. Is. Magnificent. Thank you so much for the work you put into this! "Of course not - that would be horrible!" ... This is pretty close to the method I was using to save important instance states and other information, haha! *facepalm* So glad I found your channel!
First off thank you for this tutorial. This is the first one that's made saving my game understandable for me. This is probably a long-shot given how old the tutorial is, but is there anyway to get an updated drop-box link for the Example Project? I'm curious how you were saving other character data, but the link doesn't seem to work anymore. Thanks again!
I mean, we can edit the data anyway with a simple memory editor. Then save.
Doesn't matter what your using to save the info.
11:40 How is saving the x/y values integrated, exactly?
I tried putting this in the step event:
ds_map_replace(o_game.save_data,x_key,true);
ds_map_replace(o_game.save_data,y_key,true);
And this in the Create event:
if !is_undefined(_x_data)
x = _x_data;
if !is_undefined(_y_data)
y = _y_data;
But when I load the save, the object's x/y values seem to default to 0, i.e. it spawns at the top-left of the room.
@@Studio-Animow d'oh! Thank you so much
Thanks for this. What is the encryption like for this? I see in the help index you can use a .json extension. Do you use this at all on your games? Just wondering if it's good enough to keep the average Joe from easily changing the file to get items and stuff.
I have yet to touch any json stuff yet, but the encryption is good enough to keep the average joe out. Especially compared to using an INI file that I know a lot of users use for save data.
Ok thanks.
The in between rooms save works, but not the actual close game and reopen file does not. Any help?
If it works for me and not for you, you've missed a step somewhere.
Hey there!
This is a really great video!
If you can for further have the big icon set on and maybe have the big fonts/zoom in codes so it's easier to see what you're doing, this is just a feedback ^^
I thought this was a recent video, but i just realized this was an older one :P
No worries. Yeah, I'll try to remember to zoom the fonts from now on.
Hey, just to say, if you save your game and it doesnt load properly, *don't use ds_map_secure_save or load.*
Use "ds_map_write" and "ds_map_read"
...huh. I've been using ds_list to keep data for objects like locked doors, keys, bosses, and other stuff based on the assigned rooms. It works, but only if there's one object type per room. This might help a bit better. Thanks!
Can't the key be the Instance ID that Game Maker creates for each individual object instance???
That way if you have two of the same objects in the same room, x and y it would still be unique.
If you want to trust that, I suppose that would be okay. I haven't used the room instance ID very much so I'm not sure how it is generated or if it ever changes as you make changes to your room or project. I guess if you set the ID/Name yourself that would be super safe. So, yeah, good suggestion!
Not if you want the save to work after closing the game. The IDs are generated differently every time you run the game.
I know this tutorial is pretty old at this point, but I've run into an issue that I can't figure out. No matter what I try, when I try to load the data after just starting the game, it takes me to the next room. I can't figure out what could be causing this. When I save the game and reload, it works fine, but when I close the game and try to reload right away, it takes me to the next room. I really don't understand
What do you mean "next room"?
And, really, you should join the GM Discord for code help. UA-cam comments are the worst place to get help with code. discord.gg/By6u9pC
@@PixelatedPope I appreciate the response! I meant that when I hit “load” it takes me to the next room in the room tree. In any case, I decided to try out json saving and loading based on shaun spaldings tutorial.
@@musicjre Honestly, that's how I'd do it now. I'd do everything with structs and arrays. No maps, no grids.
Wow, really helpful!
Be sure to check the follow up if you feel like this doesn't quite fit your needs. If you were using persistent rooms, you may be wanting to save a LOT more information, which is covered in the next vid.
Oh, thanks!
You briefly mentioned what you would do if you needed to save the position of an object. I have an object that gets created at a random position with a random scale and there could be multiple in the room at once. How would I go about saving / loading that? I have tried all I can and can't figure it out! They are created after game start. Thanks!
That's going to be more difficult. You won't be able to save that object's stuff with a "tag" based on it's position, obviously. So you'll need to give each item to be saved a unique tag. You'd probably need to go into more detail about what, specifically, you are trying to save and the rules around how it is spawned and when it shouldn't come back to give more help.
Its basically a randomly created poop object, im making a virtual pet game. It is created at random with a random scale and position. The only way to remove them is to click them or to press a button that washes the screen. Other than that if theres any onscreen when saving they should obviously reload with the correct position and scale. I couldn't figure it out though :/ Thanks.
Yeah. That's gonna be tough, but it's not impossible. Essentially, in your save data, you need another data structure of some sort. This is sort of nuts, but you can create a ds_grid and then use ds_grid_write to write to your ds_map and save that grid along with the rest of your save data.
Here's the basic step. Keep in mind this is not something you'll want to do every single step. Try and only do this when you need to save or load.
1. In your save data map, have an entry for "poops" and default it to "". That's an empty string. If there is ever save data here, it will be in a string format.
2. When saving, create a new ds_grid. for each poop in the room add a new row and store the x and y position in column 0 and 1. So if you have 5 poops you should have 5 rows with the x and y values for each.
Once you have the grid, use ds_grid_write() to turn that grid into a string and store it in your ds_map under the "poops" key. Then destroy the grid.
3. When loading, see if save_data[?"poops"] == "". If it doesn't, then there is save data there, and you should load it. Grab the string, and use ds_grid_read() to shove it into a fresh ds_grid. Loop through the grid and create each poop. Once you are done, destroy the ds_grid.
If your poops eventually get more complex, like varying degrees of smelliness or other disgusting attributes, just add more columns to the grid and grab those values along side the poop's posiiton.
I know this is really complex, but I hope this has been helpful. If you need more help, I recommend joining the /r/gamemaker discord group. Lots of very smart people there who can help you with problems. discord.gg/By6u9pC
Yeah I actually thought about that, I'm just new to data structures and didn't know where to start. I think for now i might set this feature out differently but in the future I'll try to sort it out. Thanks again for the responses.
This tutorial I wrote is a little old, but it's a good place to start.
www.reddit.com/r/gamemaker/comments/1vzdug/tutorial_gms_gml_data_structures_part_1_crash/?st=iylrw1gz&sh=9059be5c
So I have a setup where when the game starts there is a room that initializes all of my controllers (ScreenResize, save data, menus, etc.) and then goes to the next room. But I am having an issue where only one of my controllers is being brought to the next room (My screen controller) so the game crashes because one of my objects is referencing GameManager which acts like it isn't there. What would be the most efficient way of making sure all of my controllers are being initialized properly? Also all of my controllers are marked as persistent.
Interesting. So you would expect an instance of GameManager to be there, right? In which event is the code where it crashes? Have you set a breakpoint and checked your instance list to make sure an instance doesn't exist?
Actually kind of embarrassing, I forgot that I remade the initialization room and forgot to replace the instance of GameManager in there. I originally thought that only ScreenController was getting passed to the next room because it's the one handling the transfer to the next room. But a followup question, I saw that your zelda project had a script that initializes all of the necessary items in your ds file. If I were to put this in my GameManager(that is created everytime someone starts up the game) would the constant creation of ds files result in a memory leak? Or would it just be overwritten when I load the ds file?
Data structures are cleared when the game is closed, so as long as you aren't constantly creating data structures while your game is running, then don't worry about leaks. That being said, if you are using "game_restart()" anywhere in your game, you MIGHT have a problem with a memory leak, as I don't think created data structures are properly cleaned up (but all your variables that held the IDs of those structures have been. If you are using game_restart() I recommend not, and creating your own "exit to main menu" script that properly cleans things up, destroys data structures and other dynamically created resources, etc.
My entire game has this save system, but I ran into a problem.
I will change hard drive and go to a new pc, is there any way to find the save file? I do not see it anywhere
Nope! Two issues: 1. Save data is always on the pc you played the game on unless you are using a cloud save service, like Steam.
2. And even if you did, or if you went into your files, found the save file, and copied it to another PC, it wouldn't work because of the ds_map_secure_save and ds_map_secure_load functions won't allow it.
Does the file extension matter? or does it just open it the same way anyways, I wanna make mine something ridiculous so people might be more inclined to leave it alone, or maybe not even recognize it in the first place.
Nope. It's just a text file regardless of the extension. Use whatever you'd like.
I figured, Thank you!
Neat! Subscribed!
Looks incredibly good! Would this system work with GameMaker Studio 2?
Yup!
@@PixelatedPope Thanks!
And, Is it possible to keep a DS_Map without an Object?
For Example, If I create an Object that contains the Game manager and I destroy that Object, Do I still have access to the Map Like a Global Variable, or do I lose the Map and get a error?
Think of data structures like their own instances. When you do instance = instance_create(x,y,obj_player) you are creating an instance of object player. And even if you destroy the object that created it (and has the variable "instance" in it) the instance still exists, you've only lost the variable that has the "address" to find the instance; it's ID.
Data structures are the same. When you say variable = ds_map_create(); You are creating an "instance" of a ds_map object type. And unless you destroy it, it will hang around forever. And if you lose the "variable" variable that holds the address to that specific ds_map, you'll have a hard time finding it to clean it up when you are done with it. This is causes a memory leak, especially if you are rapidly creating data structures as needed without destroying them.
tl;dr Yes. The ds_map still exists even if you destroy the object that created it. Make sure you keep track of the value returned from ds_map_create() so you can destroy the map when you are done with it.
My key is a list of 2D arrays That I manually wrote in? How do I use this as a Key?
Uhh... what do you mean your key is a list? That's not a good thing to use as a key. You want your key to be static and predictable as often as possible, and the ID of a data structure is not static.
Can I just use an INI file with the DS map,
then Encrypt ( *However Game maker Calls it.* ) the INI file so people can't Modify it, or Don't know how to...?
I suppose so. Instead of using ds_map_secure_save/load you would just us ds_map_write/read to output the data structure to the INI file as desired. This is the recommended method especially if you want to support cloud saves or any sort of save transferring.
Any reason you can't just use the instance ID instead of making the tag with x,y coords?
Basically the same reason you can't use the room ID as I explain in the video. It's unreliable. Instance IDs are not GUARANTEED to be the same every time your run the game, especially as you are still developing it. If you add/remove an instance to your room or change the order of the instances, you run the risk of breaking all existing saves. This would especially be a problem if you are patching a released game... you could break all of your player's save data, which is obviously not good.
Well I was using the method for the death count and to keep enemies dead. I'm going to change it to use Ids but then use it to determine if a certain area was complete and then have the save data go by areas completed rather then all individual enemies.
That sounds like a good plan.
Oh, and thanks for the quick reply before. I have to say out of all of the youtube videos out there that I've watched since I've started using GMS. You're videos are the best for a few big reasons. You obviously know what you're going to say BEFORE you make the tutorial and you know how to speak. You explain things very well and in simple terms. Of course my biggest thing is the whole video isn't just GMS screen open while you talk.
Thanks! Yeah, I put a lot of effort into planning, scripting, recording and editing to make sure that you don't spend 30 minutes watching a video that could be done in 10. Always glad to hear the effort is appreciated. Thanks for watching.
Can I use separate Maps and save it in one File?
Like, A Player Data Map, Chest Map, Objective Map, & Inventory Grid (DS Grid).
Absolutely. But instead of using ds_map_secure_save/load you'll just use ds_map_write out to a standard text file. Don't worry, give it a shot and then go and open that text file... it is not exactly easy to read or edit for a player, so it won't make it easier to cheat.
Thanks.
Sometimes, when I use Game Maker Studio I always feel like that I Don't know what to do.
#GameDevIsTough
Sorry for many replies, P.S. My Brain hurts from coding...
No worries. Yes, game dev is tough. Programming in general is tough, and games especially are difficult. It never really gets easier because as you learn more, you push yourself into more unknown territory. So the things you struggle with now you will stop struggling with, but you never stop struggling all together.
hi Pixelatedpope looks like a good tutorial ive never used ds saving before. i use ini speaking of ini im happy with ini files but whenever i update my game sadly my ini files saved data is always lost its a pain because it means i cant update games in googleplay without players having to start fresh with saved files each update so i have a few questions 1.are you at some stage be making a ini tutorial or 2. with ds saving would my players have the saved files lost each time i update my games, and 3. Are you at some point going to dive into teaching about how we can cloud save data i have not seen ANY tutorials on youtube that teach cloud saving(its the future) i would like players on googleplay or whatever to be able to not worry what device they have saved game data on because they can install the same game on tablet and phone and just pickup from the saved place they left of on whatever device they play the game on. Thanks again for the tutorials .
Great questions.
1. I honestly have never used INIs (never seen a need for it) so I'm not sure what I would be able to add that other tutorials out there don't already cover.
2. This SHOULDN'T happen. The only way to invalidate your save data with a map would be to move something in the room editor in your update. But even if you do that, you could just manually type in the key that would have been generated for that specific instance. Releasing an update that changes save data is always going to be a complicated problem, but you shouldn't just flat out lose your data by releasing an update.
3. Cloud saving would be really cool, but again I have no experience with it myself. My understanding is that this method for save data is NOT suitable for cloud saving (as secure save/load seems to use a local machine salt or something to "secure" the data). Instead apparently you are supposed to use JSON maybe?... a bit outside of my expertise. But it's still a possibility for the future.
Thanks for watching.
I tried to open your zeldaproject link and it seems to no longer be available, I'd like to see it can you repost a link?
Great tutorial as always!
I've updated the link! Thanks for letting me know.
www.dropbox.com/s/6ijcn0xqtkm81oo/Zelda1.gmz?dl=0
Could you just use the object's instance ID as the ds key?
Great video btw!!
The instance ID is something that is generated at run time (unless you are talking about the instance name that gets set in the room editor). As such, it is not reliable as the next time you run the game, instances will be created in different orders and those IDs will no longer be the same.
PixelatedPope oh of course! Thanks for the reply!
U R gawd.
Thanks!
I followed the tutorial and it almost work. It work as long as i don't close the game.When I close and open it my value are set to undefined. It's like my file get reset. Anny idea of what goes worng ? I realy don't understand since i used this in another project and it worked fine.
Yeah, I can't tell you exactly what's going on without being in your project, but this is likely a problem with your loading code. To make sure, use the debugger to set a breakpoint right before the ds_map_write() call and observe the values of the map. Then, set a breakpoint on the ds_map_read() call and observe the values coming back in. If the values in your map are correct before the write, and the values are incorrect after the read in... then something screwy is going on...
Thx for you quick respond. I wanna say your tutorial are graet bye the way! So i did what you told me the value is still the same when i save and load until i close the game then it become undefined. One thing wird is that if i set a breakpoint on the ds_map_read() it just skip i have to set it a litle farther. it all in a scrip. At the end of the day i think it's over complicate for my needs all i whant is to save the progression in a tower defence and that's it. Sorry for my bad english it's not my first language.
No worries. If you'd like me to look at your project, you can export your project (file > Export project) and send me that file and I'll see if I can see what's going wrong. You can also join my discord and get help in real time if you'd like. discord.gg/CjcB2R
I would like to join your discord but the invitation id expired
Oh. Thanks for letting me know! discord.gg/BuDDgG
How is your code text so colorful? It looks beautiful!
www.dropbox.com/s/p5e51l02fv82umv/Sublime.col?dl=0
Download that and then File > Preferences > Scripts and Code > Import it into your GM.
i cant download it
its just text
and i dont understand, should i put it somewhere in the gamemaker file?
nevermind now i understand thanks
Who knew this famous redditor had such a smooth sexy voice
Oh man the text is too small ._. Can’t see the code on my phone
That's okay. You should probably be using structs and arrays these days anyway. Check out Shaun Spalding's more recent video on saving and loading!
where you get money pop out at
You can download the example project and check out the coin and chest objects to see how I do it.
Ok good looking out fantastic how to vid. I feel like I gain a lot of Exp from this Thank you
Great video! What is the difference between this and Shaun Spalding's JSON system ( ua-cam.com/video/QmxQb1BFQRE/v-deo.html )? I am asking this because I am kinda new to Gamemaker and I don't know which system to use, and which is better for my game.
I haven't actually watched the Shaun Spalding video, but if he's using Json_encode and json_decode, then that's probably the one to use. I'd like to create an update to these two videos once v2.3 releases as there are a number of things I would have changed.
@@PixelatedPope Yes, he did use json_encode and json_decode, but he did that video two years later than you, so I can't really compare the two systems:) Thank you for the quick reply!
@RyuBlade I'd like to. Now that 2.3 is out hopefully I'll do some new videos soon.
it didn't work on android !!
any one knows why ?
Odd. What about it didn't work. I guess I haven't tested it on android directly, but I can try it tomorrow and see if I have the same problem.
So I've changed my local example project to use touch to switch rooms and it all worked great. So the system itself works great on android, but the example project that is currently in the description doesn't allow for switching rooms on android. That's simple enough to add to the step event of obj_game manager right below all the keyboard_checks
if(device_mouse_check_button_pressed(0,mb_left))
{
var _margin=50;
if(device_mouse_x(0)room_width-_margin)
_right=true;
else if(device_mouse_y(0)room_height-_margin)
_down=true;
}
oh sorry for not clarifying the problem from the beginning ... the problem ihave is with the saving system when i compile with windows it works well, if i close and run the game again it loads the data , but when using android compile if i close the game and run it again, it dose not load !! i dont know why ... should i create target executable or it should just work on the compile mode ?
and am really thankful for your reply
I'm honestly not sure. I've never taken the system that far. It may be related to how GM "sandboxes" data on Android depending on if you are using the compiler or not. I imagine once you create an APK everything should work fine.
PixelatedPope I had the same problem and it didn't work so I just used INI files lmao
Just make the room persistent?
Room persistence is essentially "baby's first save system" and is really, really resource heavy. Also, how do you save everything when you close and re-open the game? That room may be persistent, but only for as long as the game is running.
You could do "game_save" and "game_load" but this is the same problem. It's essentially a save state and removes all control from you.
way to over my head, sry.