0 votes

I want to make a function that will save data onto a file within a designated file path.
The function being

static func writeToFile(data, filePath, fileName):
    if (getDataType(fileName) == "string"):
        var file = File.new()

        if (getDataType(filePath) == "string"):
            if file.open("user://"+filePath+fileName, File.WRITE) != 0:
                print("Error opening file")
                return
        else:
            if file.open("user://"+fileName, File.WRITE) != 0:
                print("Error opening file")
                return
        return
        file.store_line(data)
        file.close()
    return

getDataType() is a function i made to return a string to classify what type of data is it.

Anyways, the result is that it only works if there is no filePath being added. I have a feeling this might not work if the desired folder/path doesn't exist. For that reason, I would like to ask if there is a way to make folders or even zips using gdscripts. If there isn't then is it possible with nativeScript? I heard godot can use c++,
while I do know you can do that whole file saving, making folders and so on using c++, I have no clue to what extent c++ is capable of in godot.

asked Jul 1, 2019 in Engine by Xian (241 points)
edited Jul 1, 2019 by Xian

As for why I am doing this, it is because I am making a voxel game like minecraft or 7 days to day. You can't just save your saved game in saveGame.sav file. Voxels need actual folders to store save games and chunk files. Because saving everything in a single file makes file reading and file saving slow since data is will be add and read sequentially so it saves a lot of process speed if the chunks are stored in separate files. This is the same reason minecraft also stores chunks separately :)

1 Answer

+1 vote
Best answer

You need to create new directories if they haven't already existed.

I also cleaned up unnecessary checks by adding typing so you won't need to call your getDataType() which you can probably replace with typeof():

if typeof(fileName) != TYPE_STRING:

Anyway, here's the function:

static func writeToFile(data, fileDir:String, fileName:String):
    var filePath = "user://%s" % fileDir
    var directory = Directory.new()
    if not directory.dir_exists(filePath):
        directory.make_dir_recursive(filePath)

    filePath = filePath.plus_file(fileName)

    var file = File.new()
    if file.open(filePath, File.WRITE) == OK:
        file.store_line(data)
        file.close()
    else:
        print("Error opening file")

Will even create sub-directories if not existed:

writeToFile("Hello World!", "", "hw.txt")
writeToFile("Hello Underworld!", "under/world", "hw.txt")

Regarding zipping, it's not been implemented yet in GDSript. You can probably do it with C++, but that's beyond my knowledge.

answered Jul 1, 2019 by Dlean Jeans (3,911 points)
selected Jul 1, 2019 by Xian

@Dlean Jeans, Thank you! you are seriously like a miracle worker. Thanks :) and getDataType() is actually typeof(), i just added a string array to replace numbers to strings coz strings are easier hehe xD BUT! thanks the way u did it was a lot more efficient i really appreciate it :)

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.