0 votes

So basically i want to create a lot of instances for certain object (lets just say chests).
Now i want to be able to put stuff into these individual chests, which is my first problem. How do i send a signal to a very specific chest among all other "copies" (instances)?

Furthermore, i want to read what items / how many are in the chest. That's basically the same problem as above, i need to read different information from different chests.

Finally, what is a good way to store this information? Is it appropriate in this case to just use an array or something similar in one general script? Or is it better to store the information in each individual chest somehow?

Thanks a lot!

asked Apr 22, 2019 in Projects by Dr. Numerus (33 points)

You could define some global singleton (see docs for globals example) which also contains a dictionary. Each chest instance probably has a unique node name. Use that name to put an entry in that dictionary which contains another dictionary with the chests contents. When chests want to know what is in them then they just look it up in the global dictionary with their node name.

var chest_contents = { 
     "chest1" : {"iron":10,"sword":{"material":steel,"value":10},"gems":10},
     "chest2" : {"gems":2,"jack":1}
    }

Such dictionaries can be saved in text files. Serialized to the JSON format. On the next run you just read the text file again and parse the JSON contents into the dictionary. (As is often done with other game settings)

Ok, thank you, this was indeed very helpful. But why do i need to transform this dictionary to a text file in the first place? I often read that it is not recommended to save information in the script itself, but why? Can't i just make a long 2d-array with all chest items or something?

Sure, you can put a declaration of a dictionary or array in the code. If it is very big then it may be a bit tedious to edit.

But that is static. It'll be the same every time you start the game. So if you want to change the contents of the chests and restore those contents the next game the game is run then you need to save that dictionary to a file.

Storing/Loading a dictionary is quite simple. The following code is written from memory. So it may contain errors.

const CHESTS_SAVE_FILE = "user://chests.txt"

var default_chests = {"chest1": {"iron":1}, "chest2": {"gold":1}}
var chest = null

func load_chests():
    var file = File.new()
    chests = null
    if file.file_exists(CHESTS_SAVE_FILE):
        var err = file.open(CHESTS_SAVE_FILE, file.READ)
        if err==OK:
            data = file.get_as_text()
            file.close()
            chests = parse_json(data)
        else:
            print("Error opening "+CHESTS_SAVE_FILE+" for read: "+str(err))
    if chests == null: #init chests with default values
        chests=default_chests.duplicate()

func save_chests():
    var file = File.new()
    var err = file.open(CHESTS_SAVE_FILE, file.WRITE)
    if err==OK:
        file.store_string(to_json(chests))
        file.close()
    else:
        print("Error opening "+CHESTS_SAVE_FILE+" for write: "+str(err))

Great! Thank you so much!

1 Answer

0 votes
Best answer

So, thanks to the help of @wombatstampede i found the answer:

The solution was a dictionary, which can be accessed by a script of every individual chest, via a singleton. Each chest then just needs to check this global singleton dictionary. The distinction happens through the names or "IDs" from each chest, which is different every time a chest-scene is being instanced. This can be done just by calling the global method from a chest with the keyword "self":

Global.checkDictionary(self)

Then, the chest "knows" the items, which belongs in itself. Adding or removing items is just the manipulation of that dictionary.

Problem solved!

answered Apr 23, 2019 by Dr. Numerus (33 points)
Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.