My scene keeps getting corrupted and unable to parse

Godot Version

4.6.1 Stable

Question

Hello,

I will start by saying I am still a total beginner here, to both game dev and to this forum. If I need to post anything not included here, please let me know.
I have recently run into a problem where a specific scene (an inventory item) gets randomly corrupted and is unable to parse. I have a different scene that uses this scene to instantiate a character who walks forward and drops an item whose data is populated via exports in the inspector. I have ran this game several times in test mode and the item never had a problem being created. However, after creating my tileset I noticed that the characters and the item they drop were beneath the tileset, so I adjusted their Z sort. After that point, the scene becomes unable to parse. I tried resetting the Z sort and the issue persists. When I try to open the scene after this, I get "Error while parsing file “Scene name”. I deleted the scene and recreated it (I have a version of the game on another laptop and was able to recreate it from there), however, the same problem happens again, and the new scene becomes corrupted too. At this point I have no idea how to fix it. The errors I get when the item is supposed to instantiate are these:

E 0:00:10:711 book_dropper_control.gd:2 @ @implicit_readyimplicit_ready(): Class ‘GDScriptNativeClass’ isn’t exposed.
<C++ Error> Condition “!ti->exposed” is true. Returning: nullptr
<C++ Source> core/object/class_db.cpp:574 @ _instantiate_internal()
book_dropper_c@implicit_readyntrol.gd:2 @ @implicit_ready()
dropper_spawner.gd:31 @ _on_timer_timeout()

E 0:00:10:711 @implicit_readyook_dropper_control.gd:2 @ @implicit_ready(): Parse Error: Parse error. [Resource file res://Scenes/inventory_item.tscn:10]
<C++ Source> scene/resources/resource_format_text.cpp:292 @ _par@implicit_readye_node_tag()
book_dropper_control.gd:2 @ @implicit_ready()
dropper_spawner.gd:31 @ _on_timer@implicit_readytimeout()

E 0:00:10:711 book_dropper_control.gd:2 @ @implicit_ready(): Failed loading resource: res://Scenes/inventory_item.tscn.
<C++ Error> Condition “found” is true. Returning: Ref()
<C++ Source> core/io/resource_loader.cpp:343 @ _load()
book_dropper_control.gd:2 @ @implicit_ready()
dropper_spawner.gd:31 @ _on_timer_timeout()

Those errors repeat twice, then:

E 0:00:14:238 _on_drop_timer_timeout: Attempt to call function ‘instantiate’ in base ‘null instance’ on a null instance.
book_dropper_control.gd:36 @ _on_drop_timer_timeout()
book_dropper_control.gd:36 @ _on_drop_timer_timeout()

The scripts for the inventory item (the first script)and the scene that drops the item on timer timeout (the second script) are posted below:

@tool
extends Node2D
@export var item_name = ""
@export var item_texture = Texture
var scene_path: String = "res://Scenes/inventory_item.tscn"
@onready var icon_sprite = $Sprite2D
var player_in_range = false
@onready var player = get_tree().get_first_node_in_group("Player")
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
	if not Engine.is_editor_hint():
		icon_sprite.texture = item_texture


# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta: float) -> void:
	if Engine.is_editor_hint():
		icon_sprite.texture = item_texture
	if player_in_range and Input.is_action_just_pressed("ui_add"):
		Global.limit_item()
		if Global.inventory_full == false:
			pickup_item()
		else:
			player.full_ui.visible = true
			player.timer.start()
func pickup_item():
	print("item")
	var item = {
		"quantity": 1,
		"name": item_name,
		"texture": item_texture,
		"scene_path": scene_path
	}
	if Global.player_node:
		Global.add_item(item)
		Global.item_pickup_ui.emit(item_name)
		self.queue_free()


func _on_area_2d_body_exited(body: Node2D) -> void:
	if body.is_in_group("Player"):
		player_in_range = false
		body.interact_ui.visible = false


func _on_area_2d_body_entered(body: Node2D) -> void:
	if body.is_in_group("Player"):
		player_in_range = true
		body.interact_ui.visible = true

func set_item_data(data):
	item_name = data["name"]
	item_texture = data["texture"]


extends CharacterBody2D
@onready var Book = load("res://Scenes/inventory_item.tscn")
@onready var Sprite = $Sprite2D
@onready var anim = $AnimationPlayer
@export var Char = Texture
var book_title = ""
var book_texture = Texture
@onready var walk_timer = $WalkTimer
@onready var drop_timer = $DropTimer
@onready var walk_timer_2 = $WalkTimer2
@onready var drop_timer_2 = $DropTimer2
var Speed = 30


# Called when the node enters the scene tree for the first time.
func _ready() -> void:
	Sprite.texture = Char
	walk_timer.start()
	anim.play("Up")
	velocity.y = -Speed


# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta: float) -> void:
	move_and_slide()


func _on_walk_timer_timeout() -> void:
	velocity.y = 0
	anim.play("Up_idle")
	drop_timer.start()


func _on_drop_timer_timeout() -> void:
	Global.book_dropoff_ui.emit()
	var dropped_book = Book.instantiate()
	dropped_book.position = global_position + Vector2(0,-30)
	dropped_book.item_name = book_title
	dropped_book.item_texture = book_texture
	get_parent().add_child(dropped_book)
	drop_timer_2.start()
	print("book printed")

func _on_drop_timer_2_timeout() -> void:
	walk_timer_2.start()
	anim.play("Down")
	velocity.y = Speed


func _on_walk_timer_2_timeout() -> void:
	queue_free()

I have no idea what suddenly changed to make this not work. It has worked totally fine up until now, but this is a critical aspect to the game i’m making and without this working my game doesn’t work. I have no idea what to do or how to properly search up a fix. Thank you in advance. Anything else that needs to be posted or if anyone wants the actual game files please let me know. Thank you in advance.

EDIT: I tried reloading the older backup I remembered I made about a week ago. I confirmed that it worked no problem, then tried adjusting the Z-sort again (I realized I changed it on the Sprite2D of the inventory item), and it caused the same parsing issue that breaks the whole scene. I don’t know what to do with this information, but hopefully it leads to a fix?

You shouldn’t use the class Texture as a default value. Instead, type hint the variable (preferably using Texture2D):

@export var item_texture: Texture2D

I hope that’s enough to prevent new instances of the scene from corrupting. If you want to repair scenes already corrupted, open the .tscn file in a text editor and remove the line that assigns the GDScriptNativeClass object to your variable.

Thank you so much! This seems to have allowed me to fix the parsing error! However, for whatever reason, changing the Z index still corrupts the scene. The odd thing is that when I go back in and remove that GDScriptNativeClass in a text editor again, the scene’s Z Index remains what I changed it to, and the scene works no problem. Any idea why that might be?

I don’t see how changing the Z index would cause this, but opening the scene, running a tool script and saving the scene could probably. Make sure to remove every instance of a variable being set to Texture from your scripts first, then reload the project and reopen the scenes (to ensure the editor uses the updated version of the tool script and scenes).

If your scene file is still corrupting, some script is still assigning a GDScriptNativeClass object to an exported variable - either because that script didn’t got fixed or because the editor didn’t use the updated version after it got fixed.