Difficulties with loading resources in browser

Godot Version

v4.3.stable.steam [77dcf97d8]

Question

I’m making simple 2d game and trying to deploy it to ithc.io
I’ve encountered problem with resource loading.

I have a global LevelsManager scripts with

extends Node

const LEVELS_PATH := "res://scenes/levels/"

var level_names := DirAccess.get_files_at(LEVELS_PATH)
var current_level_index: int = 0

func get_next_level() -> String:
	current_level_index = posmod(current_level_index+1, len(level_names))
	return LEVELS_PATH + level_names[current_level_index]

Whenever I need to change scene to next level I call

var next_level_path = LevelsManager.get_next_level()
get_tree().change_scene_to_file(next_level_path)

It works perfectly on PC, but browser gives me error like “NO LOADER FOR THIS RESOURCE resource name

I found solution in preloading levels, now my LevelsManager looks like this

extends Node

var levels: Array[PackedScene] = [
	preload("res://scenes/levels/level_01.tscn"),
	preload("res://scenes/levels/level_10.tscn")
]

var current_level_index := 0

func run_next_level() -> void:
	current_level_index = posmod(current_level_index + 1, levels.size())
	get_tree().change_scene_to_packed(levels[current_level_index])

It works, but I wonder is, there more slick solution to preload list of files from given directory without need of listing all this files “by hand”?

What resource type is it? Are they all .tscn files? You might be able to instantiate a new DirAccess with the open() function. The documentation says you can’t just use DirAccess:

DirAccess can’t be instantiated directly. Instead it is created with a static method that takes a path for which it will be opened.

Also, the note for the get_files() method might be helpful.

Thanks for your answer.

What resource type is it? Are they all .tscn files?

Yes, they are all *.tscn in this case
I have almost identical issue with sound files.

by the docs:

get_files()
Returns a PackedStringArray containing filenames of the directory contents

DirAccess can’t be instantiated directly. Instead it is created with a static method that takes a path for which it will be opened.

Doesn’t it just means you can’t call on

var dir_access = DirAccess()
dir_access.some_instance_method(some, args)

and have to call

var result = DirAccess.some_static_method(some, args)

instead?

DirAccess.get_files_at(LEVELS_PATH)

returns same array of strings as

DirAccess.open(LEVELS_PATH).get_files()

.
.
But! I found strange thing! Hooray!

list of files looks like this

["level_00.tscn.remap", "level_10.tscn.remap", "level_20.tscn.remap", "level_90.tscn.remap"]

Every file have a *.remap suffix

so I’m just trimming them

return load(LEVELS_PATH + level_names[current_level_index].trim_suffix('.remap'))

Almost the same issue with sound files, they have ‘.import’ suffix, triming fixes it for web, but now i have 2 instances of every sound while debugging not in browser. So it either relatively complex and not very elegant code, either search for better solution.

There is a long thread about same issue and discussion about solutions options on git hub