I want to implement a threaded loading component into my game. I am currently saving all my settings and other level files as bytes externally (meaning not in the res:// folders), as I want to be able to export files and send them to others, so they can use them as well. There is the ResourceLoader.load_threaded_request() method, but that only returns Resources and not PackedByteArrays. As far as I can tell, there is only the FileAccess.get_file_as_bytes() method for importing byte files, which has to run in the main thread (and thus blocking it until the load is complete). Does someone know if I am missing some method here?
EDIT: I have put my fix for this into the comments
Fix: Run the FileAccess.get_file_as_bytes() method in a thread. I thought a thread wouldn’t allow for loading files using FileAccess, but it seems I was mistaken. I personally just make the Thread run my _threaded_loading(file_path:String) method and then call a signal named loaded_bytes(data:PackedByteArray). The _threaded_loading method looks like this:
func _threaded_loading(path:String) -> void: print("I am the thread and I will now load this file") var file:FileAccess = FileAccess.open(path, FileAccess.READ) print("i have opened the file") var bytes:PackedByteArray = file.get_buffer(file.get_length()) print("I have the bytes of the file") file.close() print("I have closed the file") call_deferred_thread_group("emit_signal", "loaded_bytes", bytes) return
It is important to emit the signal deferred, as a Thread on its own can’t emit a signal on its own. I did print a lot in the method just to check that everything is working as intended. I hope this helps someone!
I have found that this is incredibly fast. Loading files in threads in insane. Here is a demo where Godot loads 456 files, which all together add up to 1.6 GB in size in less than four seconds https://files.catbox.moe/g28op4.webm