DirAccess to create variables with file information works in engine but not when exporting

Godot Version

All versions

Question

This works in the engine, but not after exporting.
When I thought “hmm, that’s odd why?” I remember reading something some months ago that came to mind. If I take the liberty to paraphrase that, it was something like: “After export, the game doesn’t actually use the res://path/to/file structure”.

Why doesn’t this work and what is the proper way to keep track of where everything is? I want to just be able to add a new sprite to a folder and it will automatically be known in a variable, without having to manually hardcode it every time…

Here is what tried to do:

var resource_sprites = get_filenames_of_type("assets/sprites/resources", "png")

# Returns a dictionary with file name as key
func get_filenames_of_type(folder, suffix = null):
	if not folder.begins_with("res://"):
		folder = "res://" + folder
	if not folder.ends_with("/"):
		folder += "/"
	var dir = DirAccess.open(folder)
	var file_names = {}
	if dir:
		dir.list_dir_begin()
		var file_name = dir.get_next()
		while file_name != "":
			if not dir.current_is_dir():
				var append_file = true
				if suffix and not file_name.ends_with(suffix):
					append_file = false
				if append_file:
					var file_name_parts = file_name.split(".")
					file_names[file_name_parts[0]] = {
						"full_path": folder + file_name_parts[0] + "." + file_name_parts[1],
						"folder": folder,
						"suffix": file_name_parts[1]
					}
			file_name = dir.get_next()
		dir.list_dir_end()
	return file_names

Example output:

print(resource_sprites)
=> {
  "Silver": {
    "full_path": "res://assets/sprites/resources/Silver.png",
    "folder": "res://assets/sprites/resources/",
    "suffix": "png"
  },
  "Gold": {
    "full_path": "res://assets/sprites/resources/Gold.png",
    "folder": "res://assets/sprites/resources/",
    "suffix": "png"
  }
}
1 Like

at export, the resources folder is basically gone, compacted down into a more optimal, minimal structure. That will complicate your directory walking. Two approaches come to mind. 1, try ResourceLoader.load(). It will still take the same res:// relative file paths and return the resource. So that might be enough right there. But me personally, I’d probably opt for a custom Resource that stores all your encoded special information into some kind of collection, save that resource and at runtime just use it for the details, not actual directory contents.

I’d go with option 2. GL!

also, read this:
https://forum.godotengine.org/t/cannot-traverse-asset-directory-in-android/20496

I’d probably opt for a custom Resource

While I do use custom resources for some things, I don’t see how this would make sense in this specific case.
With my solution, every time I want to add a new “vehicle” I just pop the .png image in the assets/sprites/vehicles folder.
That way I don’t have to fiddle with any custom resources, I just create the image, call it something like:
Dunebuggy_3.png

Where vehicle.name = "Dunebuggy" and vehicle.tier = 3

Everything else gets handled… probability of encounter, etc…

I just have to create the sprite, put it in place and set the filename.

And that’s the same with anything.

assets/resources/Aluminium_1.png
assets/resources/Gold_4.png

Aluminium which is a tier 1 resource and Gold is a tier 4 resource

With custom resources, I have to create the image, create a resource for it, define the stuff there and it’s just not as simple as creating an image and set a file name on that.

I already have created separate scenes for each enemy and that was not ideally how I wanted to do it. It just turned out to be more convenient because they would need to have different types of stuff located at distinct positions.

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.