[SOLVED] Collectibles (Star coin-esqe) system

Add 2 object variables to the colletcibleMedallion object - call them levelId and Id. In the editor, set them to the level and medallion number each one belongs to (it would be better to do through events if you have more levels - create the collectible medallion and set the variables, but don’t worry about that for now)

Move the delete collectible action to a final sub-event, so it’ll be the last action performed when a player & collectible collision occurs (i.e. after the event that changes the collectibleMedallion animation).

In your code where the collectibleMedallon animation change occurs, remove the existing condition and replace it with the conditions
collectibleMedallion.levelId = collectible.levelId
collectibleMedallion.Id = collectible.Id

To get the collectibleMedallions showing at the start of the scene, try the adding the following event (I’m not 100% sure it’ll work, but let’sstart with it):

condition : at the start of the scene
action : set the animation number of collectibleMedallion = collectiblesObtained[“level”+ collectibleMedallion .VariableString(levelId)][collectibleMedallion .VariableString(Id)]

Alright, that seems to work well. However, for saving the data across scenes, the code provided seems to return an error saying that I’m missing an expression (Note: I adjusted some of the spelling and capitalization to match what I have):

This shouldn’t return any errors since it’s practically the same as the other code we worked with. Is there something else missing?

Wrap it in a GlobalVariable(…). GDevelop doesn’t know what collectibleObtained is (sprite, function, object variable, scene variable etc), so you need to tell it - previously you had it in an Update Global Variable expression, so it knew what it was dealing with.

It’s now working just like I imagined it would! Thanks.

However, there’s now one last problem: Storing the data. I want the data to be saved when collecting a collectible, and loaded once the game is booted back up. What I have so far doesn’t work:

I tried this with just making it load just the global variable by itself as well, and that doesn’t work either.
Wishforge Game’s tutorial looks so straightforward, but it’s probably not complex enough to handle what I’m trying to do.
What’s the last thing I need to put to properly store this data?

I don’t think writing to storage is automatically recursive over a variable structure. Have a look at this thread on saving a variable structure to storage

You mean store the structure as a JSON string, and then parse it back to a global variable when loaded?
I tried this, but for some reason, it’s not working:

I even checked the expressions reference on the GDevelop wiki, and GlobalVarToJSON exists. Why doesn’t it work here?

You want to write a text, not a value, to global storage. JSON is text.

Oh whoops. I fixed it now, and put the storage events and the parse. However, it still doesn’t work:

In the action where you read in the storage data, you’ve got the CollectibleStructureJSON variable in quotes. Remove those quotes, and see what happens.

Oh thanks, it works! I’m trying to reset the data now, so I made an event to delete the storage.
However, it’s not working. How do I delete the storage?

How do you mean, it’s not working?

Are you pressing the x key, then closing the game, then running it again and finding the status bar is not empty?

Well, it works when I close the game and reboot it, but I also just added an event that resets the scene. When the scene is reset, the data does not erase, but when the game shuts down it does. Is it possible to make the “Delete save data” instant so that players don’t have to reset their entire game?

(Edit: Both the data erase and scene reset are mapped to the same button, with the delete data on top)

It is instant. The problem is you’re not clearing out your global variables when the x key is pressed.

The data is still in the global variables. It’s not linked to the storage data. You’ve effectively got some original data (global variable), creating a copy (storage), removing the copy and wondering why the original still has values.

Ah, I understand. So I have to reset the variables in the event as well?
I did this, but it’s kind of buggy. Some data saves, but some doesn’t when the scene is reset. Is there another way to just turn every single child’s value to 0?

You’re only resetting one variable. You’ll need to loop through all the levelIds and Ids and clear them out.

Okay, I got something to kind of work:

One little error is that I have to reload the scene twice to get the data to reset.
Also, one major error is that the collectibles only delete depending on what level I’m in.
E.g. If I’m in level 1, only the level 1 collectibles get erased, and vise versa (This bug even works without the condition in the “Repeat” code block).

Any way I can fix these last two errors?

You really want 2 while loops and 2 extra variables (levelLoop and idLoop) controlling the loop. Something along the lines of:

levelLoop = GlobalVariableChildCount(collectiblesObtained)
while levelLoop > 0
   idLoop = GlobalVariableChildCount(collectiblesObtained["level" + GlobalVariableString(levelLoop)])
   levelLoop -= 1

   while idLoop > 0
    set collectiblesObtained[“level”+ GlobalVariableString(levelLoop)][Global.VariableString(idLoop)] = 0
    idLoop -= 1

Okay, I put the code in. However, it still doesn’t work. Did I format it incorrectly?

(Note: I tried moving the change scene action to the very end and it still didn’t work)

You’re creating levelLoop and idLoop as a scene variables, but referring to them as a global variables.

Also, I made a mistake - you’ll need to move the levelLoop -= 1 action into a final sub-event of the second while block. Otherwise the 3rd collectable is never updated.

Okay, I made the changes:

Unfortunately, it still doesn’t work. Is there an easier way?