[Solved] Is there a way to save all the child variables of a Structure more easily? + Centering text objects?

I’ve been using GDevelop for quite a while now and I’m LOVING IT, so much. Making games has never been this fun to me, as an artist the engine feels absolutely dream-like! This is also my first post on this forum, so hello!

I wanted to ask - Is there a way to save Structures more easily? As in, writing the values of all the child variables of a Structure variable into the Storage without having to manually make an event for each child variable?
I’ve already read on the documentation how to do that with the Inventory, and it works perfectly, but I wanted to know if there’s a way to do the same with ANY structure variable? As in, write it all in a single group in the Storage and then read it back into the scene as a Structure variable again?

Also, second question, and a lot less important: How to center text objects properly, in a way where no matter the length of the text, it will always be centered? I’ve managed to do it on a few very specific cases, but I wanted to know if there’s an easier way of going about it!

And also, I’m SO sorry if these questions have already been answered in another thread - I did take a quick search around and didn’t find what I was looking for, so that’s the only reason why I’m making the post!

Thank you so much in advance, I appreciate any kind of help! <3 Thank you for reading!

2 Likes

So, it’s been a while and I got no responses, BUT I’ve figured out the answer for both of these questions already, gladly! I found the answer for the first one in the Wiki, and the answer for the second one in a thread in this forum.

A way to save Structures more easily in the Storage would be by converting it to a JSON string with an expression and writing it in the Storage as a text, and the way to load it would be by reading the text from the Storage into the string of a scene variable, which is not yet a structure, but rather just the raw JSON string - and parsing it into a Structure variable with the “Convert JSON to Global Variable” action found in Network. It’d look something like this:

// Save //
Write GlobalVarToJSON(YourStructure) on "Structure" of storage "A"

// Load //
Read "Structure" from storage "A" and store as text in "StructureJSON"
Parse JSON string VariableString(StructureJSON) and store it into global variable "YourStructure"

It doesn’t need to be a Global Variable, obviously, the same works for scene variables. It’s really neat and definitely makes things much easier, I love it!

And for the answer of the second question - how to center a text - I’m not yet sure how I can make the text inside the text object to be centered, but I know how to center the text object itself within the screen or within another object.

Centering the Text object within the screen:

Do = SceneWindowWidth() / 2; = SceneWindowHeight() / 2 to the position of Text

Centering the Text object inside another object:

Do = NewObject.X() + (NewObject.Width()/2) - (Text.Width()/2) ; = NewObject.Y() + (NewObject.Height()/2) - (Text.Height()/2) to the position of Text

Both using the “Position of an object” action found in “Common Actions For All Objects > Position”. It’s a good way to keep the Text centered when the text string keeps on changing.
I hope this helps someone at least! I’m loving the program so much so far!

10 Likes

About the saving structure. How would i impliment that as a save game/load game type scenaario.

Example: completed lvl 1. Save game.
From that point onwards, when user clicks “start” do level 2 ect. I’ve already got this: “player collides with object: win; change scene to level 2”

I think an easier workaround for that would be to have a “Loading Scene” - a scene JUST for the file to be loaded, and the scene that “takes you to the game”. It’s not the best nor the only way to do it, of course - it’s just my preferred way to do it!

In the Main Menu of your game, when the player presses “Start”, instead of just sending the player to the game itself, send them to a “Loading Screen”. In the “Loading Screen” scene, add events to:

  1. Check if there’s already a save file. You can do that by using a condition to read a special value from the Storage - a value that’s always written whenever the player saves, and the vaue you can use to check if the player has ever saved. We’ll call it “firstSave”.

     If "firstSave" exists in storage "A"
       do = 2 to scene variable "PlayerHasSaved"
    
     If "firstSave" exists in storage "A" (Inverted Condition)
       do = 1 to scene variable "PlayerHasSaved"
    

    ( Inverted Conditions mean the opposite of the condition, so if the condition is true it means "firstSave" does not exist in the storage. )

  2. Then, we use a condition to check what the value of the “PlayerHasSaved” variable is, and let it decide what will happen - if the player has already saved, then the game will load the storage and take the player to the scene where they stopped. If they have never saved, the game will start normally.
    Also, the reason why I’m not using the value “0” to test the variable is because that’s the initial value of every variable - and that would lead to a glitch. Every variable starts at 0, so the actions would play before the game even had time to read the storage. By using 1 and 2, I prevent that from happening.

     // Has Not Saved //
     If scene variable "PlayerHasSaved" = 1
       change to scene "Scene One".
    
     // Has Saved //
     If scene variable "PlayerHasSaved" = 2
       do = 1 to scene variable "Load"
     // The "Load" variable should start the loading events necessary, reading the values from the Storage. I'm gonna explain the Timer in a minute. //
    
  3. If the player has already saved, the Load variable should start the loading process - and in order to send the player to the correct scene where they stopped, you’ll have to use a scene variable, and - well, if you want - a timer (I’ll explain).
    The SCENE NAME should be written in the Storage when the player saves. If the player has just completed “Level 1”, and you want the player to be taken to Level 2 next time they hit the “Start” button, then the Scene Name should be written as “Level 2” for the next load.
    The reason why I like using timers in Loading Screens is not only because it gives it a bit of a charm, but it also kind of helps give the game time to load things correctly. It’s more for the charm, though.

     // Reading the Scene Name //
     If "SceneName" exists in storage "A"
       read "SceneName" from storage "A" and store as text in "SceneVar"
    
     // Taking the Player to the Scene //
     If the timer "LoadingTime" is greater than 1.5 seconds
     If the text of scene variable "SceneVar" is != "" (if it's different from nothing, if it isn't empty)
       change to scene VariableString(SceneVar)
    
     ( This should take the Player to the scene by the name written in the storage. If the scene name written in the storage is Level 2, then the player will be taken to Level 2. )
    
  4. If you want to load scene-specific things in Level 2 (or whatever scene the player is taken to), you can add a group of events in Level 2 that will only be triggered if the player loads the game.
    When the player loads the game, make sure to do a +1 to a global variable - we will call it “LoadingScene” - and if that global variable equals 1, the events will be triggered.

     If global variable "LoadingScene" = 1
       read "PlayerScore" from storage "a" and store it in "SceneScore"
       read "PlayerColor" from storage "a" and store it in "SceneColor"
       do = 0 to global variable "LoadingScene"
    

And this way, you can really load anything you need into the scene. ^^ Make sure to add all the “Read Storage” actions above the “do = 0 to global variable” action, that one should be the last one.

I hope this helps!

1 Like

so i’ve added in the events and created the variables but nothing happens. can you create a tutorial? also, i don’t know how to create a storage file.

What do you mean nothing happens? What happens, exactly? Did you make sure to add all the actions properly?
And in order to create a storage file, all you really have to do is add an action to write something in the storage and if the file doesn’t exist it’ll automatically create itself.

Also, if you want, you can make your own thread about your issue and provide screenshots and such, maybe other people could jump in and help too. ^^;; It’s more practical, as this one is already marked as “solved”.

Ok, I’ll make my own thread. Sorry to keep bumping your thread that was about your problem instead of mine. And thanks for helping out a newbie in the right direction. :wink:

2 Likes

Hi Mayhem, just want to drop a note of thanks for sharing this method.
I tried this and found that it works across all platforms and all three different variable types.

Having Variable Structures by itself is already a godsend, this method of yours just made this game engine perfect!

4 Likes

Please don’t bump 2 year old threads

Separately, GlobalVarToJSON() exists and works fine with global variables.

I’m actively using it in my game project today. You can see valid expressions and their required parameters here: Expressions reference - GDevelop documentation

4 Likes