Skip to content

class_name classes become invalid on PCK scenes when unloading PCK files #82479

@rsubtil

Description

@rsubtil

Godot version

latest, with #61286 applied

System information

Arch Linux

Issue description

Note

This issue is only relevant with the functionality of #61286 applied

When implementing the functionality to unload PCK files (which involves clearing GDScript cache of the loaded pack to clear scripts; not sure if that's the root cause), reloading such files results in an error where a custom class_name class that's defined on the main project, works on the main project, but when running code on the loaded pack, Godot complains the class is not from the correct type:
image

This only occurs when the pack in unloaded; when the pack is loaded for the first time, or is reloaded without unloading it first, this issue doesn't occur.

Steps to reproduce

  • Have the main project and sub-project define some custom resource using class_name:
extends Resource
class_name MyResource

var text := "default"
  • In the sub-project, define some scene to be loaded, and a method receiving the custom object:
    image
extends Control

func got_info(info: MyResource):
	$Label.text = info.text
  • Export the sub-project as a PCK file.
  • In the main project, load the PCK file, instance the scene, then call that method:
func load_pck():
	print("Result: ", ProjectSettings.load_resource_pack(pck_file), false)
	
	var child = load("res://scene.tscn").instantiate()
	$SubViewportContainer/SubViewport.add_child(child)

	var my_res := MyResource.new()
	my_res.text = "test"
	child.got_info(my_res)

So far so good; there's no issues with reloading this pack file

  • Now add functionality on the main project to unload the PCK file before reloading it.
func _on_button_pressed():
	await unload_pck()
	load_pck()

func unload_pck():
	for child in $SubViewportContainer/SubViewport.get_children():
		$SubViewportContainer/SubViewport.remove_child(child)
		child.queue_free()
		while is_instance_valid(child):
			await get_tree().process_frame
	
	print("Result: ", ProjectSettings.unload_resource_pack(pck_file))
  • Now, when reloading the same scene, the issue will occur when got_info is called on the instanced child object.

Some other scenarios I've tested:

  • This issue still occurs if the pack is allowed to replace files.
  • This issue does not occur if in the got_info method, the argument type is not specified:
extends Control

func got_info(info):
	$Label.text = info.text

Minimal reproduction project

IssueRepro.zip

Note

Needs #61286 applied in order to get the unload pack functionality

This contains two projects: the main project on root, and sub-project on inner folder. The sub-project is already exported at inner/inner.pck. Run the main project, and click on the Load button to reload the pack and trigger the issue.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions