Open bkane opened 3 weeks ago
Bisecting points to #81577 as the culprit:
@anvilfolk ^^
@matheusmdx I've noticed you have been doing a lot of bisecting of issues, that's awesome! Like @dalexeev did, it might be worth tagging the author of different PRs so they can follow up!
Circular dependency work, truly the gift that keeps on giving 😅
I will try to take a look at some point though I've got a sick toddler atm so not too soon :) I glanced at the MRP and couldn't immediately find circular references, which is surprising! I'll try to sketch it out and see if I didn't miss something. This might be really hard to track down because of how many different components, so we'll see! :)
I have debugged the MRP. The problem here is not a circular dependency but the order in which resources and scripts are imported paired with the call to GDScriptCache::get_shallow_script
that replaced GDScriptCache::get_full_script
from https://github.com/godotengine/godot/pull/81577.
The way it works is that when the main_scene.tscn
gets loaded, it loads ParentNode.gd
which in turn loads ClassThatInstantiates.gd
. When ClassThatInstantiates.gd
gets compiled ResourceB
gets shallow loaded which registers res://my_resource_b.gd
in ResourceCache
. Afterwards ClassThatPreloads.gd
gets loaded which in turns loads test_resource.tres
. Here my_resource_b.gd
gets loaded, however since it was already registered in the ResourceCache
and the loading is done with REUSE
it returns the Resource which has not been compiled yet and thus has no _base member set in its script.
Unfortunately, I don't know what the intended behaviour is in this case. @anvilfolk If you can give me a hint, I can try to fix it.
Great detective work! 🥰
You're right, the issue isn't cyclic dependencies directly, it's that for them to work we needed to restrict the use of get_full_script
to very specific stages of the script compilation pipeline! The original PRs should have some documentation about how/when we can use get_full_script
.
I'm afraid I can't offer much in terms of advice right now, I'm stuck with another PR and worked on this too long ago to remember many specifics. Definitely feel free to give it a try though, and join the developer chat for support! There's tests for cyclic dependencies so hopefully if something breaks in the process of figuring out, it'll get caught! If not, we add more tests! ☺️
Tested versions
System information
Godot v4.3.stable - Windows 10.0.19045 - Vulkan (Mobile) - dedicated NVIDIA GeForce RTX 2080 (NVIDIA; 31.0.15.3713) - Intel(R) Core(TM) i7-9700K CPU @ 3.60GHz (8 Threads)
Issue description
With a very specific set of Resource subclasses and sub-resources, use of preload, use of
@onready
, and instantiation in script, the following error occurs:This occurs when attempting to run the project. The data in the sub-resource will not be loaded, and will be removed from disk when saved. Additionally, validation performed by the editor when loading the project will similarly remove the 'offending' data and give a similar error.
However, it seems that if you don't have a call to instantiate the sub-resource in code (or preload, or
@onready
in this specific way), then this configuration of resources/subresources is fine to load, use, and save. This may suggest that the class structure is supported but there is some issue arising in the validation process.Steps to reproduce
Error and automatic deletion of sub-resource at startup
When you open the included minimal reproduction project, you will see the following error in the output window:
At this point, the included resource
.tres
file will be automatically modified to remove the problematic data. You should see its contents go from something like this:to this (where the sub_resource has been removed)
Automatic deletion at runtime if you attempt to add it back
At this point, you could run the project without errors, but that's because the sub-resource has been automatically removed. If you add it back in:
test_resource.tres
Add Element
for MyResourceContainer -> DataNew MyResourceB
Now when you run the project, you will see the two errors:
Additionally, the data will not be available if you load the resource. It will also be removed from disk if you save the project.
Interactions with preload,
@onready
, and moreThis is a very specific set of scripts! If you remove the
@onready
references, the type hints, the function call to instantiateMyResourceB.new()
, or the preload call, the issue appears to go away.I have tried to simplify the project further but this eliminates the issue. For example, simply having "a resource class that contains a sub-resource of a type that itself is a subclass of Resource" is not enough to trigger this error.
Godot 4.2.2:
In v4.2.2.stable.mono.official [15073afe3], the startup error is a little different:
The result is the same however, as the sub-resource data is removed from the
.tres
file.And at runtime (if you replace the automatically removed sub-resource as described above):
Minimal reproduction project (MRP)
resource-bug.zip