Is item in resources required?

Godot Version

4.1.1

Question

I’m trying to write a simple function that loops over all the images, music, text and good stuff in the res:// folder and determine if it is used in the game.

ie So I can delete without worry, any old stuff that I’m no longer using in my game.

This is complicated by the fact that
get_all_files(“res://”) no longer works
ResourceLoader.exists(f) # where f a valid file, works… but seems to be true even if I’ve just added a random file to the res folder which I know it doesn’t need

Any ideas?

What method are you talking about for get_all_files?

What do you mean “doesn’t need”? The method checks if the file exists, how do you mean it should check if it’s needed?

What about using RefCounted and the get_reference_count method?

That won’t work unless every user is loaded

Ok let’s take a step back. One of us has autism and well… there may be gaps in communication

I’m trying to sort out game assets that aren’t loaded or needed. And by not needed I mean never seen used or heard in the game. I put a red skeleton sprite in the game and he was never used - it can be deleted. That sort of thing.

This could probably be done by hand but may take a while…

I’m hoping this could be done automatically with a game script - however, I am aware that Godot may assume that everything that goes in the res folder is needed.

I tried get_all_files() - but that just resulted in an error

var the_files = get_all_files("res://")

results in error Function “get_all_files()” not found in base self.

I suspect I’m confusing matters with my previous understanding of ResourceLoader.exists()
Which now seems to be ResourceLoader.exists is similar to File.exists

Does that help?

Let’s say you have a function that finds all unused files. Only instead of deleting them, you use this function to load these files as part of the game. You now have a paradox: the function uses all unused files, so the unused files are used, which means that they are not unused, which means they are not used. Therefore no such function can exist, because its existence would lead to a contradiction.

1 Like

To iterate over all project files use DirAccess. This example function could take "res://" and print all the files and folders.

func dir_contents(path):
	var dir = DirAccess.open(path)
	if dir:
		dir.list_dir_begin()
		var file_name = dir.get_next()
		while file_name != "":
			if dir.current_is_dir():
				print("Found directory: " + file_name)
			else:
				print("Found file: " + file_name)
			file_name = dir.get_next()
	else:
		print("An error occurred when trying to access the path.")

To see what resources each resource is using is going to be rather difficult and will not include any loaded from scripts using load. For reference even Godot cannot accurately keep track of this dependency tree. If we assume all of your Godot resources are text files (.tscn or tres) then you could read through them looking for “ext_resources”. Here’s a truncated example of that file.

[gd_scene load_steps=9 format=3 uid="uid://1766vt3un62j"]

[ext_resource type="Theme" uid="uid://conbsco7p51x" path="res://UITheme/blippy_ui.tres" id="1_3kcgj"]
[ext_resource type="Script" path="res://System/ServerBrowser/server_menu.gd" id="2_ewgxt"]
[ext_resource type="Script" path="res://System/ServerBrowser/LAN_broadcast_listener.gd" id="3_8l13l"]
[ext_resource type="Texture2D" uid="uid://cyrk1i5fcu8i0" path="res://Assets/Interface/Icons/Scifi/23.png" id="3_73yge"]
[ext_resource type="Texture2D" uid="uid://cj5eum62kiss0" path="res://Assets/Interface/Icons/Scifi/03.png" id="4_cmibt"]
[ext_resource type="Texture2D" uid="uid://bq17lu48jk4rq" path="res://Assets/Interface/Icons/Scifi/21.png" id="4_yewsp"]

By parsing each line of the text resource we can get a path as a String array. For scripts we need to look for the preload function.

func get_ext_resources(path: String) -> Array[String]:
	var ext_resources: Array[String] = []
	
	var file := FileAccess.open(path, FileAccess.READ)
	while file.eof_reached() == false:
		var line := file.get_line()
		if line.begins_with("[ext_resource"):
			var path_start := line.find("path=\"")
			var path_end := line.find("\"", path_start + 1)
			var path_len := path_end - path_start
			var path := line.substr(path_start, path_len)
			ext_resources.append(path)
	return ext_resources

Now we would have to go back through DirAccess and find any unclaimed files.

1 Like