Skip to content

Add retrieval methods to ResourceLoader for querying cached resource paths (C++, C#, GDScript) #13523

@TruelyMostWanted

Description

@TruelyMostWanted

Describe the project you are working on

Any game, tool or plugin, utilizing externally and internally located Resources that get loaded at runtime

Describe the problem or limitation you are having in your project

Projects often rely on resources located both internally (res://) and externally (user:// or absolute paths like C:/...). These can be traversed using DirAccess when paths are specifically known — but what if you dont know the specific paths and users to access (and filter) all of those assigned in all the different Nodes and Resources from a global database?

Whenever a user assigns a Resource to an exported field in the Inspector or sets it in code (set_deferred(name, value)), the engine updates that resource’s reference count and considers it as cached inside ResourceCache::resources, a HashMap<String, Ref<Resource>> mapping paths to resources.
Yet there’s currently no way to list or query all resources in usage across the project, regardless of how they were assigned or loaded as this cache is private and not exposed to C++, GDScript, or C#, preventing inspection, filtering, or analysis at runtime..

For Example: A large project with 1,000 resource files alone in res:// but only 800 are used. You might want a tool to identify and remove the 200 unused ones. Or you might want to query the 800 used resources to see which are of a specific type, extension, or filename pattern — all without knowing their exact paths.

Example queries could include:

  • Which resources have the type hint "Image"?
  • Which have the file extension "mp3"?
  • Which filenames contain "Level01_"?

Describe the feature / enhancement and how it helps to overcome the problem or limitation

This feature exposes the internal ResourceCache::resources for read-only access through query methods inside the ResourceLoader cass. It allows developers to retrieve and filter all cached resources in the project using flexible conditions, similar to a lightweight query system.

Example pseudo-SQL:

SELECT * FROM ResourceCache::resources
WHERE <TARGET> <COMPARATOR> <VALUE>
  • TARGET enum { TypeHint, Path, FileName, FileExtension, BaseDir, ResourceName, ResourcePath, ResourceClass }
  • COMPARATOR enum { Equals, NotEquals, BeginsWith, EndsWith, Contains }
  • VALUE (String)

Examples:

get_all_cached_paths()
get_cached_paths_by_filter(target: TYPE_HINT, comparator: EQUALS, value: "Image")
get_cached_paths_by_filter(target: PATH, comparator: BEGINS_WITH, value: "res://")
get_cached_paths_by_filter(target: FILE_NAME, comparator: BEGINS_WITH, value: "Spritesheet_") 
get_cached_paths_by_filter(target: FILE_EXTENSION, comparator: EQUALS, value: "png") 
get_cached_paths_by_filter(target: FILE_EXTENSION, comparator: BEGINS_WITH, value: "t")
  • "TYPE_HINT" = { Image, AudioStreamWAV, PackedScene, JSON, Shader, StandardMaterial3D, ... }
  • "PATH" = { "res://", "user://", "/data", "/materials", "/data/audio/", ... }
  • "FILE_NAME" = { "Spritesheet_", "IMG_", "Sprite_" }
  • "FILE_EXTENSION" = { "tres", "res", "mp3", "wav", "ogg", "jpeg", "png", "json", "csv", "cs", "gd", .... }

Results have the form of:

  • Array = [path1, path2, path3, path4, path5, path6]
  • Dictionary { "Path1"="TypeHint1", "Path2"="TypeHint2" }

Then these informations can be used to load the specific resources over the ResourceLoader.load(path, typeHint, useWorkerThreads, CacheMode) method --> No breaking changes to existing logic

By exposing the internal resource cache, it becomes possible to retrieve and filter all actively loaded or assigned resources — for example, by type, extension, or filename. This allows developers to build tools that:

  • Identify and list all resources currently used in the project.
  • Detect unused files (e.g., the 200 unreferenced ones in this example).
  • Provide automated cleanup features like a simple “Remove Unused Resources” button.

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

In resource_loader.h and resource_loader.cpp:

  • Add two enums: FilterTarget and FilterComparator.
  • Implement three private helper methods for validation and filtering.
  • Add four new public methods:
    • Retrieve all cached paths (array and dictionary forms).
    • Retrieve filtered cached paths (array and dictionary forms).

In core_bind.h and core_bind.cpp:

  • Register enums and methods for access in GDScript and C#.

If this enhancement will not be used often, can it be worked around with a few lines of script?

No. The ResourceCache API is not exposed to the scripting layer.

While users could build custom tracking systems, that would duplicate existing engine functionality, increasing maintenance complexity and inconsistency with Godot’s internal resource management.

Is there a reason why this should be core and not an add-on in the asset library?

Yes.
These methods directly interface with Godot’s core caching system and are essential for runtime inspection, debugging, memory management, and editor tooling.
Providing them in core ensures consistent and reliable access for all languages and prevents redundant reimplementation in addons.

Implementation

godotengine/godot#112217

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions