I’m developing a 2D web browser game on Godot and ran into a problem where the skins in the store are not showing up. The problem seems to be that I’m using the path “res://Resource/skins/”, but I know that (res://) doesn’t work in the browser version.
What can be used instead of it for the correct loading of resources? Any help would be appreciated!
I also add the complete code that I use to upload skins to the store:
func load_skins():
var skins_path = "res://Resource/skins/"
var dir = DirAccess.open(skins_path)
if dir:
dir.list_dir_begin()
var file_name = dir.get_next()
while file_name != "":
if file_name.ends_with(".tres"):
var skin_name = file_name.get_basename()
skins[skin_name] = skins_path + file_name
file_name = dir.get_next()
dir.list_dir_end()
print("Skins: ", skins)
#A function that displays skins
load_skins_ui()
Does this work exported to a desktop platform? I think not, when exported most resources take on a .remap suffix, but you still have to load the .tres path, it’s a big mess as of right now; you might be able to modify your code like so to support .remap files
if file_name.ends_with(".tres") or file_name.ends_with(".tres.remap"):
var skin_name = file_name.get_basename()
At the end of that discussion this pull request is slated for 4.4, that offers a new function in ResourceLoader to help this situation.
You might find this discussion helpful (I’m not sure; I don’t have a direct answer to your question). I didn’t think file access issues were different in web exports vs other exports, but I don’t know for sure.
If these are skins that need to be saved/loaded during runtime:
var skins_path = "user://skins/"
(I might be misunderstanding the issue, But this seems to be your problem?)
(Also sorry gert for sniping your threads lol)
(Ah nevermind, I see where you literally said you know this would work lol. Im gonna leave this comment up for posterity for other web users but just know im dumb.)
print error? I’m not sure exactly how to decipher that message. Seems like it does print an empty skins or fails to serialize the dictionary.
If it really cannot open the file you would add else statements to better understand the control flow
func load_skins():
var skins_path = "res://Resource/skins/"
var dir = DirAccess.open(skins_path)
if dir:
dir.list_dir_begin()
var file_name = dir.get_next()
while file_name != "":
if file_name.ends_with(".tres") or file_name.ends_with(".tres.remap"):
var skin_name = file_name.get_basename()
skins[skin_name] = skins_path + file_name
else:
##
print("Found file with invalid extension ", file_name)
file_name = dir.get_next()
dir.list_dir_end()
else:
##
print("Failed to open dir ", skins_path)
print("Skins: ", skins)
#A function that displays skins
load_skins_ui()
It looks like you’re trying to use a previously loaded skin (which is a file) as if it were a directory? This is a different problem than just the res:// path issue.
Yeah that seems confusing! Make sure you are rebuilding the game for web when testing, gotta have a clean slate. The first line, "Not directory: { "black": "res://Resource/skins/black.tres" }" is there any other DirAccess being opened? On a dictionary too?
Test it in a desktop export first, I do not think it’s a Web export specific issue, though web exports do have their own unique problems like these print errors. It should be easier to debug if there is an issue through a desktop export.
Try this. I really gotta stop opening this website at 4 am 3 hours before work and doing more in 30 mins then I do in 3 days of coding at my real job lol.
extends Node
var skins = {}
var current_skin = null
var skin_container = null
func _ready():
create_skin_ui()
load_skins()
func load_skins():
# Clear the skins dictionary first to avoid contamination
skins.clear()
if OS.has_feature("web"):
var skin_files = ["black.tres", "blue.tres", "red.tres", "green.tres"]
print("Web export detected. Using explicit skin list.")
for file in skin_files:
var skin_path = "res://Resource/skins/" + file
var skin_name = file.get_basename()
var skin_resource = load(skin_path)
if skin_resource:
skins[skin_name] = skin_resource
print("Loaded skin: ", skin_name)
else:
print("Failed to load skin: ", skin_path)
else:
var skins_path = "res://Resource/skins/"
print("Desktop/mobile export. Scanning directory: ", skins_path)
var dir = DirAccess.open(skins_path)
if dir:
dir.list_dir_begin()
var file_name = dir.get_next()
while file_name != "":
if file_name.ends_with(".tres"):
var skin_name = file_name.get_basename()
var skin_resource = load(skins_path + file_name)
if skin_resource:
skins[skin_name] = skin_resource
print("Found and loaded skin: ", skin_name)
else:
print("Failed to load skin resource: ", skins_path + file_name)
else:
print("Found file with invalid extension: ", file_name)
file_name = dir.get_next()
dir.list_dir_end()
else:
print("Failed to open directory: ", skins_path)
print("Error code: ", DirAccess.get_open_error())
print("Total skins loaded: ", skins.size())
print("Available skins: ", skins.keys())
load_skins_ui()
func create_skin_ui():
if not skin_container:
skin_container = VBoxContainer.new()
skin_container.name = "SkinContainer"
add_child(skin_container)
var label = Label.new()
label.text = "Available Skins"
skin_container.add_child(label)
print("Created skin UI container")
func load_skins_ui():
for child in skin_container.get_children():
if child is Button:
child.queue_free()
for skin_name in skins.keys():
var button = Button.new()
button.text = skin_name
button.name = "Skin_" + skin_name
button.pressed.connect(_on_skin_selected.bind(skin_name))
skin_container.add_child(button)
print("Updated skin UI with ", skins.size(), " options")
func _on_skin_selected(skin_name):
print("Selected skin: ", skin_name)
if skins.has(skin_name):
current_skin = skins[skin_name]
apply_current_skin()
else:
print("Error: Selected skin not found!")
func apply_current_skin():
if current_skin:
print("Applied skin: ", current_skin)
else:
print("No skin selected to apply")
func has_skin(skin_name):
return skins.has(skin_name)
func get_skin(skin_name):
if skins.has(skin_name):
return skins[skin_name]
return null
Also thanks to my dad who helped me write this. Shout out to you pops.
You’re getting errors because your game is trying to load .remap files directly, which isn’t supported in Godot. The .remap files are typically generated during export and aren’t meant to be loaded directly.
Cool, very interesting that it found black.tres, but finding the .tres.remap files is good.
You may have to use a more complex naming system as load doesn’t work on .remap files, it sadly still expects a .tres extension. This substr will truncate to the first . found, not just the extension; I doubt you intend to add dots as part of the filename. Then it re-applies the .tres extension to the stored path. This should work for both .tres and .tres.remap files
if file_name.ends_with(".tres") or file_name.ends_with(".tres.remap"):
var skin_name: String = file_name.substr(0, file_name.find('.'))
skins[skin_name] = skins_path.path_join(skin_name + ".tres")
The "You skins: " error is intersting, I don’t see that in the code.
I am very grateful to you, and in general to everyone who helped me, the problem was fixed, now the skins are loaded in the store. But there are two more mistakes: