Make several save files player can find

I know basic how to write/read into a storage and I am using ID counter, here is my simplyfied test version of what I have done so far:

But how to make that the player can write a name for the “savefile” and later find it? It is basically the selected animations of many instances of 3 different objects I want to save.

Here some thoughts about how I possibly(?) could achieve what I want and questions about the steps:

Naming for saving
So if I have a Text Entry and a Text called SaveName, I activate capture by Text Entry and change the text of SaveName and write to that storage. Then I try to load from it by putting the same text in LoadName:

  1. Why isn’t this working? It didn’t work without the variable SavedName either. If I just call storage “save” it works fine. Is this just a too senstive system; because I did manage to make a save this morning that I can still load, but not overwright with the same name; it just reads the old (I do not know of changing anything essential since then). Can I make this work and if, how?

Loading:

  1. Is there then a way to find all storages that exists, without having to remember the exact name of every storage? Maybe something equivalent for repeat for each instance, but repeat for each storage? Or “check all existing storages” and list them somehow?

  2. If there is something like this, I am thinking that I could then create a text object for each storage, showing the SaveName, but how to do this? It depends on what I get from the previous step, I suppose :wink:

  3. Is there a way to position these created text objects in relation to each other so that if I have just a few saved storages, they will come under each other in a column, but if that column is full, it will make 2 columns?

  4. When I then read a storage, it makes it to a scene variable, but if I wish to have my list of storages on a separate scene, how does it work then? Do I have to make a global variable of it and then “translate” it back to a scene variable when back on the first scene, or?

And finally some more questions:

  1. Is there a way to prevent the condition “if cursor is on an object” and “mouse button was realesed” from taking into account objects from another layer? I tried with different “if layer/object is visible/not”, but however I tried, it just went in circles as some other command made that visible…

  2. If I have loaded from my storage and close Gdevelop without again writing to storage (with/without saving the project), all is GONE when I re-open my project :frowning: Any suggestions how to fix this problem…?

  3. Or is it possible to test if the player is trying to X-out from the game without saving?

  4. Is there a list somewhere of the things that can be put into a group name and then actually be used? I mean what other functions are there like the way it gives the information about the Object ID?

  5. Is it possible to put a variable in the storage name? I am thinking if I somehow then could check if a storage already exists, and if not add one to the variable and use that as the storage name. The player can write a name (for the sheet music my project is used for), and that is written into storage and could be used to create a text object for the player to click on to open the right saved file.

  6. Can some other useful information be put into the storage name?

If anybody knows an easier way to do this, I am very open for suggestions! :wink: And I am also very greatful for answers to any of my questions.

Can’t answer all of these, but I’ll tackle the ones I know:
Loading:

  1. No. You must know the storage name you’re looking for.

  2. Not as far as I know. However, why do you need the storage to have the savename as the storage name? Why not just have a variable named “SaveName” that stores the player’s save name within something like named “SaveSlot1/2/3/4/etc”, and then you always know the storage name?

  3. Probably. Off the top of my head, I’d

    1. give each text object an ID variable that is a number. (At start of the scene, do a for each object for your text objects, do a “Set Scene Variable “TextObjCount” + 1”, then also do a “Set Object Variable TextObject.ID = Variable(TextObjCount)”.
    2. Then say you only want 10 items in column 1, you’d basically just have a condition of “if TextObject.ID <= 10 | Position X/Y blah”, then for column 2 it’d be TextObject.ID > 10 AND TextObject.ID < 20, etc.
  4. Yes, currently you’ll need to take your scene variables to a global variable “SaveInfo” of some kind. You don’t have to convert it back to Scene, as you can save info into storage directly using the Convert Global Variable to JSON and Convert From JSON expressions. Read more into those as they’ll make your process easier.

Some more questions:

  1. There should be no way to go into a circle unless you’re trying to show/hide the same layers between the two buttons. If so, you need to implement some kind of “Button must be released” toggle variable. Something like setting up a global variable of “ButtonPressed”, add a condition to each of your events that show/hide layers where “ButtonPressed = 0” but ALSO add an action of “Set Global Variable “ButtonPressed” = 1” on each event. This will prevent them from activating sequentially until ButtonPressed = 0 again. Then you can just set up a separate event that checks for “button released” with an event of “ButtonPressed = 0”. (Make sure you use trigger once conditions or you’ll break everything after the first time.

All of the answers above are conceptual. You will need to make sure you fully understand variables and expressions before you try to implement them, and I strongly don’t recommend copying and pasting anything I have above into your events, as they won’t work. (it’s nearly 5 am and I am too tired to look up the exact naming). However, I hope it helps. I know all of the above will work as I’ve done all of these things in separate instances in the past (not in the exact same context, but the exact same type of events).

Thank you for your answers! I am impressed you are so dedicated as to answer at 5 a.m.!

Loading
2. No, you are right, I do not necessarily need to have the storage name as savename, I could use the system you are suggesting, but I would still need a system to check which storages are already “occupied” (and ask if player wants to overwright it). If I would like, say 18 different Saveslots, it would be rather much work to do the programming separately for each. Well, I suppose it is (too?) complicated anyway… :wink: Maybe it could work somehow with a variable, if it is < or equal to some other variable, then add one system…? That would probably require some reading before showing Saveslots, and add the risk of doing something wrong or going in circles. Variables apparently can be used in group names, even if i don’t completely understand how and all the possibilities with that. I would prefer a system that is safe, that if some reading/writing goes wrong (or GD just doesn’t react on some click, which is unfortunately not that uncommon I have noticed), it won’t ruin everything that is saved. And some test if the saving was successful would be nice too.

Some more questions

  1. Unfortunately I am trying to show/hide the same layers… I have a little difficulty to see how it would help with a button released variable; wouldn’t that too change when mouse button is released on both objects (if they are on top of each other)? Maybe I should just choose an easy solution and make sure the show/hide objects are far enough from on top of each other :wink: Or maybe some timer could work.

For loading:
I may be misunderstanding the question. You shouldn’t have to do coding for each save slot. You do the coding once, but set it up to dynamically select the save slot to load based off which the player selects.

(e.g. Your saveslot variables are named “SaveSlot1”. Your player selects slot 12. You store the player’s selected slot as a variable “PlayerSelectedSlot”. Your events are set up to do “Load game data from ToString(“SaveSlot” + Variable(PlayerSelectedSlot))”. This will then work regardless of which save slot is selected)

For your question on the button released: The idea is that you use “Mouse Click/button selected/etc” to actually activate the button, AND the “Button Released” variable has to be true. So the action to ACTIVATE your game buttons is the mouse click action, but only if the mouse button has been released before. And you immediately set “Button released” to not true as part of your game button actions NOT as a separate event (so it only gets set to not true as part of your button activating).

This means, your first game button click works because your mouse button had been released before, however it cannot immediately activate the next button (once visible) because you haven’t released the mouse button yet. If you do release the mouse button once the second button is visible, it won’t activate until you click again, basically.

The idea is this “must be released” events prevent continual triggers.

Thank you for your answers! I am not sure I quite get it though…

This is what I have worked up:

And Preview like this, the white boxes are my SaveSlots:
Save3

The problem is, whatever I try to code, it will just change the text of the first slot and whichever slot I then click on, it will load the last saved text and animations. I tried also with a “if cursor is on SaveSlot” and “Left mousebutton was released”, set Variable ChosenSlot to SaveSlot:s variable ID" and then: “repeat for each instance of SaveSlot” IF "Object Variable SlotChosen of SaveSlot is = SaveSlot.Variable(ID) then read from “SavedName” + ToString(SaveSlot.Variable(SlotChosen)), but it doesn’t work any better (and usually not even changing any text then).

I also tried directly with “cursor is on SaveName” and an ID for SaveName, if the linking between SaveSlot and SaveName might be the problem, but it seems it is not possible to check if the cursor is on a textobject, as it is not working to change the text that way…

I hope this explanations are not too messy… Any ideas what I might be missing are highly appreciated! :slight_smile:

I think is repeating all the time, try to add Trigger Once on each event when the cursor is on, this way you ensure the event runs one time when the object is clicked

1 Like