Dynamically finding and loading resources from the Filesystem for Android and Web Exports
A little while ago, I created a type of AudioManager to make it easier to work with sound files in bulk: Rather than assigning audio streams by hand, I was doing it programmatically; reading the contents of a directory and using
load()
to get the resources. It worked great and saved a lot of time over assigning hundreds of sound resources by hand. While this worked during development and for Windows exports, it failed on Android and Web exports.
Godot Engine 4 will, at export time, relocate these resources. So if you are reading directly from the directory where you’re expecting a file to exist, it may no longer be there after the project is exported. Instead, you will find the same file with a “
.remap
” suffix added in its place. Just strip off that “.remap” suffix and use
ResourceLoader.load()
, which understands the resource mapping and can retrieve the proper resource for you.
The reason for the resource remapping is that some platforms require assets to be bundled in specific ways or stored in specific locations. The original asset has been moved, but Godot will instead have the same filename with an added “.remap” suffix to indicate that.
If you need to load something dynamically, use the ResourceLoader, and if you’re trying to discover content, scan the directory, and strip off the .remap suffix.
As long as you’re aware of this pitfall, you should be able to handle resources in your Godot game dynamically.
I’ve abstracted this into a general-purpose resource finder:
class_nameGGResourceFinderextends RefCounted## Iterates over files in a directory## making it easy to load contents from disk at run-time.#### This finder helps find resources that are remapped for Android## and Web exportsstaticfuncfind(directory:String,suffix:String) -> Array[String]:varfiles:Array[String] =_dir_contents(directory,suffix)files.sort()returnfiles## Recursively find files from a directorystaticfunc_dir_contents(path:String,suffix:String) -> Array[String]:vardir=DirAccess.open(path)if!dir:print("GGResourceFinder: An error occurred when trying to access path: %s" % [path])return []varfiles:Array[String]dir.list_dir_begin()varfile_name=dir.get_next()whilefile_name!="":file_name=file_name.replace('.remap','')ifdir.current_is_dir():files.append_array(_dir_contents("%s/%s" % [path,file_name],suffix))eliffile_name.ends_with(suffix):files.append("%s/%s" % [path,file_name])file_name=dir.get_next()returnfiles
This script can then be used to find scenes from a particular directory. This may be relevant if you’re looking to support mods or DLCs in your Godot game since the game will have to have some way to discover and load the new content.
Anyway, path remapping is something to be aware of. I feel like that’s one of those things that’ll sneak up on you. Everything works great up until exporting, then suddenly everything’s broken for trying to be too data-driven. Some additional reading:
Any sufficiently large code base needs documentation. Documentation tends to come in all sorts of shapes and sizes. Among them are high-level architecture and design docs, class and method interface documentation, and inline comments to explain optimized or complex algorithms so the reader doesn’t have to parse the logic in their head (often, this is …
When I think of video games, I generally still think of an application that is downloaded and runs on the client. Technically, that’s still the case with web-based exports from Godot Engine, since the web browser has to download the files before being able to run them. I thought maybe I could just run the …
Godot Engine 4 has a bug (#50824) that causes particle jitter when the game is paused. It does look quite distracting. The Bug in Action This is a proof-of-concept wave shooter running in Godot Engine 4.0.2. Pausing the game was initially just a simple process_mode toggle. But as shown in the video clip above, there …
This release improves weight management. Inventories can now configure an option weight limit, and item stacking and item transfer strategies are weight-aware. The crafting demo and crafting mechanic in the inventory tour have been improved. Auto-crafting is limited to the crafting slide, so that items don’t automatically and unexpectedly get crafted while stepping through the …
Dynamically finding and loading resources from the Filesystem for Android and Web Exports
A little while ago, I created a type of AudioManager to make it easier to work with sound files in bulk: Rather than assigning audio streams by hand, I was doing it programmatically; reading the contents of a directory and using
load()to get the resources. It worked great and saved a lot of time over assigning hundreds of sound resources by hand. While this worked during development and for Windows exports, it failed on Android and Web exports.Godot Engine 4 will, at export time, relocate these resources. So if you are reading directly from the directory where you’re expecting a file to exist, it may no longer be there after the project is exported. Instead, you will find the same file with a “
.remap” suffix added in its place. Just strip off that “.remap” suffix and useResourceLoader.load(), which understands the resource mapping and can retrieve the proper resource for you.The reason for the resource remapping is that some platforms require assets to be bundled in specific ways or stored in specific locations. The original asset has been moved, but Godot will instead have the same filename with an added “.remap” suffix to indicate that.
If you need to load something dynamically, use the ResourceLoader, and if you’re trying to discover content, scan the directory, and strip off the .remap suffix.
As long as you’re aware of this pitfall, you should be able to handle resources in your Godot game dynamically.
I’ve abstracted this into a general-purpose resource finder:
This script can then be used to find scenes from a particular directory. This may be relevant if you’re looking to support mods or DLCs in your Godot game since the game will have to have some way to discover and load the new content.
Anyway, path remapping is something to be aware of. I feel like that’s one of those things that’ll sneak up on you. Everything works great up until exporting, then suddenly everything’s broken for trying to be too data-driven. Some additional reading:
Related Posts
Generating documentation for GDScript
Any sufficiently large code base needs documentation. Documentation tends to come in all sorts of shapes and sizes. Among them are high-level architecture and design docs, class and method interface documentation, and inline comments to explain optimized or complex algorithms so the reader doesn’t have to parse the logic in their head (often, this is …
Quickly deploying Godot games on the web with Netlify
When I think of video games, I generally still think of an application that is downloaded and runs on the client. Technically, that’s still the case with web-based exports from Godot Engine, since the web browser has to download the files before being able to run them. I thought maybe I could just run the …
The Pause Handler: Working around Godot 4’s particle jitter bug
Godot Engine 4 has a bug (#50824) that causes particle jitter when the game is paused. It does look quite distracting. The Bug in Action This is a proof-of-concept wave shooter running in Godot Engine 4.0.2. Pausing the game was initially just a simple process_mode toggle. But as shown in the video clip above, there …
Inventory System 2 Alpha 3 available
This release improves weight management. Inventories can now configure an option weight limit, and item stacking and item transfer strategies are weight-aware. The crafting demo and crafting mechanic in the inventory tour have been improved. Auto-crafting is limited to the crafting slide, so that items don’t automatically and unexpectedly get crafted while stepping through the …