Ran into an interesting bug while working on no signal offline.
I noticed that when creating a new game and
skipping the PGEIST intro, Godot throws this error:
Trying to assign to invalid previously freed instance.
The code in question looks something like this:
static func reset_lighting(tree: SceneTree) -> void:
var lights := Lookup.children_where(
tree.root, func(a: Node) -> bool: return a is Light3D
)
# elided
# Wait for rendering data to be reset
await RenderingServer.frame_post_draw
# Re-enable rendering stuff
for light: Light3D in lights:
if is_instance_valid(light):
light.visible = trueThis doesn't make sense, because I explicitly
check if the light is valid before I try to access
the visible property.
Looking up this issue, I find this:
[...] When you specify a type for the iteration variable, it seems there is some reassigning/casting happening under the hood (I’m not completely sure and haven’t checked the source yet).
You can remove the type in the
forto fix it. [...]
In particular, it's important to note that
Lookup.children_where returns an
untyped array, even though every element in
that array is a Light3D. Since I set
debug/gdscript/warnings/unsafe_property_access
to true, it's necessary to specify the type later to
resolve the compilation warning. Changing the
affected section to delay setting the type fixes the
issue:
for light in lights:
if is_instance_valid(light):
var l: Light3D = light
l.visible = true