godot: Listing directories in exported project returns only `*.import` files
Godot version: Godot v3.0.6 Stable x64
OS/device including version: Windows 8.1
Issue description:
Shortly I tried to scan my res://audio/supersounds directory for every .wav file it had into array, and then play track by picking randomly with randi() % array.size(). But i’ve met problem where already exported project return empty array. So thinking about it might be problem with .wav, i’ve added some .png and .ogg into the folder and even removed file type check and it did some progress, it returned only .import type files. That’s not what I wanted. In editor everything showed how expected.
Some guy in godot questions topic did reproduction and met the same problem. But he somehow got some .png and other types in output. Being surprised I also went and created empty project with same function to scan, but added custom .png into res:// and tried to list the thing. This is what’ve got:
[Node.gd.remap, Node.gdc, Node.tscn, airSpike.png.import, default_env.tres, icon.png, icon.png.import, project.binary]
Apparently default files and main scene are somewhat defended against it!?
After… I went already here to search for answer I thought it might be #25347, but i checked it’s reproduction and it works fine, so file_exists() isn’t the case.
Im at dead end now.
Steps to reproduce: Create new scene, add root node, add following script to it:
func _ready():
print(list_files_in_directory("res://"))
func list_files_in_directory(path):
var files = []
var dir = Directory.new()
dir.open(path)
dir.list_dir_begin()
while true:
var file = dir.get_next()
if file == "":
break
elif not file.begins_with("."):
files.append(file)
dir.list_dir_end()
return files
Export, launch. Executable debug console should print something similar to this:
[Node.gd.remap, Node.gdc, Node.tscn, airSpike.png.import, default_env.tres, icon.png, icon.png.import, project.binary]
Expected:
[Node.gd.remap, Node.gdc, Node.tscn, airSpike.png, airSpike.png.import, default_env.tres, icon.png, icon.png.import, project.binary]
Minimal reproduction project: exported.zip project.zip
About this issue
- Original URL
- State: open
- Created 5 years ago
- Reactions: 9
- Comments: 29 (16 by maintainers)
Links to this issue
Commits related to this issue
- Fix portrait loading in exported builds Workaroud for this Godot Engine bug :https://github.com/godotengine/godot/issues/25672 — committed to youre-perfect-studio/catherines-quest by TheRealCatherine 5 years ago
This seems unnecessarily confusing. I’m not sure why this has been a years long battle and yet no documentation under the load function mentions the fact that files will fail to load correctly after export if you don’t jump through a bunch of extra hoops.
I simply can get why this does not works properly. If it works in editor it’s intended to work everywhere, else this is either a huge issue or listing function is completely pointless to have in engine. I don’t believe in workarounds cause they tend to fail everytime you add minor changes to anything :S
You can use ResourceLoader.exists()
What is the proposed way of making sure a specific resource file exists in an exported game? I’m working in godot 4.0.3 on a plugin. The plugin will save a list of files to add at runtime, but as files could always be removed we check first, to show a warning if the file has been moved or removed.
This fails during export because file_exists() returns false. Do I manually have to check if .import, .remap have been added? It feels very weird that I can load a file that godot tells me is not there. I understand that FileAccess and DirAccess are supposed to represent the actual file system, but then what can I use use to list/test paths that are actually accessable (even if nonexistant)?
The only general purpose solution I can see is using
Which idk. Seems pretty clunky for such a simple task.
that is only true on the specific condition that
convert text resources to binaryis set to false in the project settings. if it is set to true, theload()function is incapable of fetching the resource. That should be mentioned in the documentation if that is intended functionality. currently, there are no references to that specific setting in either class, nor its effects on the capability to use theload()function. This would have relieved a massive headache, and i would not have had to rely on the luck of seeing the setting and changing it to see if it affects the way resources are remapped such that theload()method would function.The fix for this issue would be documenting in
get_files()method description that it lists the factual directory content and it will differ on export.Then we could add a method named
get_imported_files()(or similar) that returns the original files based on imports. It should likely also list.gdfiles based on.gdc, as it’s a similar thing (see #42507).You won’t be able to load any changed/added files (or any files at all it you do not distribute
.importfolder as well).Export is not much of protection. You can easily decompress PCK, you can convert scenes back to text versions and decompile gdscripts to the state almost identical to source. PCK does not store original files, but you still can restore it from
.importfolder stuff.Another option is to use the whole project folder and put the executable inside.
I just stumbled over this when I ran into https://github.com/godotengine/godot/issues/66014, for now I manually have to remove the
.remapsuffix to properly pass a path I get from DirectoryAccess to the ResourceLoader, this hardcoding of essentially implementations details seems not really ideal…If only
.importfiles are listed, why not look for.wav.importinstead of.wav? Every resource has its equivalent import file, so effectively it’s the same.Isn’t it a kind of absurd to distribute to other users access to all the sources of your game. Yes, the engine is open-source, but let’s say you have something related to micro-transactions in your game, or your saving data is encrypthed and the key is hidden within your code. You have to think ahead and outside the box of using your game on your machine only.
Would like to say that this solution fixed the issue of importing for me, now I’ve got files which export properly without a *.import, however now I’m getting a “no loader” error when I run the program, and I can’t use any of the files while running in the editor.
Make sure Godot is not running.
Create empty
.gdignorefile in the sub-folder you want to preserve as isDelete all
*.importfiles from this folder if there are anyAdd file extensions to “export non-resource files” in export options
Resulting
PCK content:Output:
[airSpike.png]Something like this:
@timCopwell I have the source code of my game on Github, so it doesn’t matter for me.