How to store that i collected collectables so they don't respawn

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By lincolnpepper

I want my levels to have a lot of skull collectibles, just sitting in the open, coming out of chests, and as drops from enemies. However, i don’t want them to respawn after i collect them, as i only want to collect them once. I’ve been thinking about it for a while, but i don’t know what the best solution is. My level scenes are kept in level classes, which are kept in a list in a level manager that allows me to easily go between levels, which is kept in a game information class that stores information about that game (i need to update what levels i have unlocked and what levels i have completed per game information class) and game information is stored inside a global script. I bring this up because it seems like a bad solution to store what skulls i have and have not collected inside the level classes, because i want to save it, so it would make sense to go into the game information class somehow.

Sorry if i don’t make sense my brain is basically dead right now but tl;dr how do i store that i collected collectables so i don’t recollect them in a way so that i can save that in a json

:bust_in_silhouette: Reply From: johnygames

One way I can think of is by storing in a list and referencing the names of the objects that have already spawned a skull collectible. I do not know whether your objects are generated procedurally via script or if they are already placed at fixed positions, but by giving them a unique name/id, you could easily crosscheck which objects have been ‘used’.

Every time a skull-spawning chest is opened or a skull-spawning monster is slain, make sure to store their name in a list accessible from your global script. The next time said item is encountered, iterate through the list and if its name is already included, skip the skull-dropping part.

You could even run this check while generating a skull-spawning object. Just give particular objects the “skull-spawning” property (a boolean variable) and turn this variable to false if the object’s name is in the list.

This might work for manually placed skull spawners, but I don’t know how well it would work for procedurally generated ones. In any case, make sure to save the list of used spawners in a json file which will load everytime you run the game.

That makes sense. At first I didn’t want to put them all in one list cause i didn’t want to search a huge list but i guess it really shouldn’t be a problem. Is there a reasonable way for me to give every object a unique ID without putting it in myself every time i place an object or it being random (so that it’s not different when you reload the game)?

lincolnpepper | 2019-09-28 04:09

How do you spawn your objects exactly? Are they manually set in the scene or are you using a script to generate them? If you use a script, are you having it generate all the skull-dropping objects at specific positions? Are you using a list or dictionary for that?

johnygames | 2019-09-28 13:13

I haven’t exactly finished setting up how my skulls will spawn. But there should be some just lying around in the world i place manually and some that drop from enemies by code.

lincolnpepper | 2019-09-28 16:01

What about the monsters that spawn those skulls? Will they be generated by code? If not, the procedure is straight-forward: When you place a skull-spawning object in the scene manually, the name of that object is created automatically. Suppose you have a node called Monster in your scene; if you duplicate that monster manually, another one will be created with the name Monster2. If you duplicate that again, you will get a Monster3… I think you see where I am getting with this. You don’t need to name everyting manually

Unfortunately, the object IDs change when a scene spawns again, so I don’t think you can use those to keep track of the objects that have already spawned a skull. What is more, groups do not behave as expected when they are managed via code (which might be a bug). You could, however, use the unique names of the objects. ^^

The idea is that a skull spawning monster or chest should have a property which controls whether it can spawn a skull or not. This property should be a boolean variable set to true by default.

Here’s the tricky part: when a skull-spawning monster is slain, you register its unique name in a list in your global script. That way the program will crosscheck the list every time the same monster dies, and if both the boolean variable of that monster is set to true AND its name is NOT in the list, then it will spawn a skull. If any of the above conditions is not satisfied, then said monster will NOT spawn a skull. Needless to say that you should save that list as a json file!

In other words, every skull-spawning object should check if its name is contained in the global list. If so, it will NOT spawn a skull. If it is the first time the player encounters that object, then it will spawn a skull, it will have its skull-spawning boolean variable set to falseand its unique name will be placed in the global list of “used” skull spawners for future reference.

That goes for when you place skull-spawning objects manually. If you do that via code, it is trickier. You would have to find a way to give every monster and chest a unique name every time it spawns, so that you can keep track of their names.

All in all, I think that for your purpose this system should work. If I have answered your question, please tell me so that I can update my answer.

johnygames | 2019-09-28 17:20