• Godot Help
  • Plugin's Autoload delete all arrays at runtime

Hello all,

In order to better learn Godot I've decided to start working on some plugins and am currently working on an Item Management system that adds an item creator to the editor that, on item created, appends it in a specifically created array in an automatic autoload script called "ItemManagement".

While in the editor, everything seem to work perfectly: the items are created and added to both the visual database in the editor and in the autoload array. If I debug the process with prints and all everything work perfectly,

The problem is that, when the game starts, the autoload gets instantiated into the remote tree and the array is immediately empty, losing all the data I appended to it in the editor.

Is there any way to prevent this?

I've recorded a little video to better explain this:

Thanks.

  • xyz replied to this.
  • Svalinn85 It's like with any tool that creates data. If you want this data to be available the next time you run the tool, you need to save this data to disk in the current session and re-load it in the next session. It's the same case here with your tool. Save (serialize) the data you've created in the editor, and then re-load (deserialize) it when you run the project. The easiest way to save/load data is to keep it as properties of a custom class inherited from Resource. Then use ResourceSaver::save() and ResourceLoaded::load() to store/retrieve the data.

    Svalinn85 An autoloaded node, like all other nodes, is instantiated anew when you run the project. Meaning that all initializations and assignments written in its script will be executed. So if its script has a line var items = [], the property items will be initialized as an empty array.

    If you want a property to retain values set in the editor, you can export it to editor: @export var items = []. This way its value set in the editor will be saved as the default value in the scene file and used to initialize the property at startup.

    The other solution that's suitable for handling more complex nested data is to use custom resource classes and (de)serialize them as needed.

      xyz Oh you may be right there. For some reason even if I use @export all the time I did not think that could work for the autoload script of the plugin.

      EDIT: actually managed to try this right now and it did not work. Even with the @export all the created items gets deleted at runtime.

      Just to understand things better, would you be willing to elaborate a little more on the last bit of your answer? In the specific what it is you mean by saying (de)serialize custom resources as needed. I know about resources and how to create them ofc m thanks a lot 🙂

      • xyz replied to this.

        Svalinn85 It's like with any tool that creates data. If you want this data to be available the next time you run the tool, you need to save this data to disk in the current session and re-load it in the next session. It's the same case here with your tool. Save (serialize) the data you've created in the editor, and then re-load (deserialize) it when you run the project. The easiest way to save/load data is to keep it as properties of a custom class inherited from Resource. Then use ResourceSaver::save() and ResourceLoaded::load() to store/retrieve the data.

          xyz Thank you very much for this answer. It's something related to Godot I wasn't aware of. Will try it out and then get back here 🙂

          Resources are the bee's knees when it comes to saving data between sessions. They are sort of like scriptable objects in Unity but in my opinion, much easier to deal with. More than data storage, they can also have their own functions that operate on their data. I'm pretty sure you have to export everything you want to save, even if you don't intend on assigning the value in the editor. You can nest resources inside other resources and only have one file on disk. Or, you can split them off into separate files and save references. I'm learning more about them every time I use Godot. They are handy in so many ways.

          the autoload gets instantiated into the remote tree and the array is immediately empty, losing all the data I appended to it in the editor.

          Is there any way to prevent this?

          As standstill suggested, use Resources. Nodes are not serialized, even Autoloads, so the data you passed to your node in editor is not "saved" anywhere and lost when you run the game (and when you close the editor)

          @xyz @standstill @AnidemDex thanks evryone for taking the time to answer. Had the time to go ahead and research the suggestion from xyz and finally made it work.

          Had to play around a lil bit casue I never worked with these methods before but managed to make it work finally.

          Thanks to your suggesiton I was able to save every resource item on a specific path and also managed to create an "item delete" button that delete the created file using DirAccess.remove_absolute(), just in case.

          Then added a function in the autoloaded singleton to fill up the item array on _ready like this:

          `func _ready():
          junkAppend()

          func junkAppend():
          var dir = DirAccess.open(junkPath)
          dir.list_dir_begin()
          while true:
          var file_name = dir.get_next()
          if file_name == "":
          break
          elif !file_name.ends_with(".tres"):
          break
          elif file_name.ends_with(".tres"):
          junkList.append(load(junkPath + file_name))
          dir.list_dir_end()`

          Really grateful for your answer, made me do nice step foreward and also learn a lot of useful things after researching a bit 🙂