I had a problem with my save and load game system in Godot Engine 3.5

Godot Version

Godot 3.5

Question

Hello to all, I have a question with my system code for loading and saving games, I leave them here:

extends Node

var save_filename = "user://save_game.dat"

func _ready():
	load_game()
	
func save_game():
	var file = File.new()
	file.open(save_filename, File.WRITE)
	
	var saved_nodes = get_tree().get_nodes_in_group("Saved")
	for node in saved_nodes:
		if node.filename.empty():
			break
		else:
			var node_details = node.get_save_stats()
			file.store_line(to_json(node_details))
	
	file.close()
			
func load_game():
	var file = File.new()
	
	if not file.file_exists(save_filename):
		return
	else:
		var saved_nodes = get_tree().get_nodes_in_group("Saved")
		for node in saved_nodes:
			node.queue_free()
		file.open(save_filename, File.READ)
	
	while file.get_position() < file.get_len():
		var node_data = parse_json(file.get_line())
		var new_obj = load(node_data.filename).instance()
		
		get_node(node_data.parent).call_deferred('add_child', new_obj)
		new_obj.load_save_stats(node_data)
		
func _notification(what):
	if what == NOTIFICATION_WM_QUIT_REQUEST:
		save_game()

My question is: Why do I get an error in the part of the code where it says <get_node(node_data.parent).call_deferred(“add_child”, new_obj)> when I run my code once the data is saved? Thank you very much in advance!

What error are you having? It’s probably because node_data.parent is not found when trying to get_node()

The mistake was in the script part of my character, here it is:

extends KinematicBody2D

var speed = 150
var direction = Vector2.ZERO
var bullet = preload("res://Characters/Bullet.tscn")
var bullet2 = preload("res://Characters/Bullet2.tscn")
var can_shoot = true
var _eat_time 
var enemy_collide = false

func _physics_process(delta):
	alice_move()
	reload_energy()
	if Input.is_action_just_pressed("shoot") and can_shoot:
		shoot()
		
func alice_move():
	if Input.is_action_pressed("ui_down"):
		direction.y = speed
		$AnimatedSprite.play("caminando_abajo")
		$AnimatedSprite.flip_h = false
		
	elif Input.is_action_pressed("ui_up"):
		direction.y = -speed
		$AnimatedSprite.play("caminando_arriba")
		$AnimatedSprite.flip_h = false
		
	elif Input.is_action_pressed("ui_left"):
		direction.x = -speed
		$AnimatedSprite.play("caminando_lados")
		$AnimatedSprite.flip_h = false
		
	elif Input.is_action_pressed("ui_right"):
		direction.x = speed
		$AnimatedSprite.play("caminando_lados")
		$AnimatedSprite.flip_h = true
		
	else:
		direction.x = 0
		direction.y = 0
		$AnimatedSprite.play("respirando_x")
		
	move_and_slide(direction, Vector2.UP)

func shoot():
	if !$AnimatedSprite.flip_h:
		var bullet_instance = bullet.instance()
		bullet_instance.position = $Position2D.global_position
		bullet_instance.get_node("KinematicBody2D/AudioStreamPlayer2D").play()
		get_tree().get_root().add_child(bullet_instance)
		can_shoot = false
		yield(get_tree().create_timer(0.2), "timeout")
		can_shoot = true
		Global.lifes_player -= 1
		
	elif $AnimatedSprite.flip_h:
		var bullet_instance2 = bullet2.instance()
		bullet_instance2.position = $Position2D2.global_position
		bullet_instance2.get_node("KinematicBody2D/AudioStreamPlayer2D").play()
		get_tree().get_root().add_child(bullet_instance2)
		can_shoot = false
		yield(get_tree().create_timer(0.2), "timeout")
		can_shoot = true
		Global.lifes_player -= 1
		
func reload_energy():
	if Global.lifes_player <= 0 and shoot():
		direction.x = 0
		direction.y = 0
		can_shoot = false
		_eat_time = get_tree().change_scene("res://EatTime.tscn")
		
func _on_Area2D_body_entered(body):
	if body.is_in_group("enemy"):
		Global.lifes_player -= 2
		enemy_collide = true
		if Global.lifes_player <= 0 and enemy_collide:
			direction.x = 0
			direction.y = 0
			can_shoot = false
			game_over()
			
func game_over():
	var _game_over_screen
	_game_over_screen = get_tree().change_scene("res://GameOverScreen.tscn")

func get_save_stats():
	return {
		'filename': get_filename(),
		'parent': get_parent().get_path(),
		'x_pos': position.x, 
		'y_pos': position.y,
		'stats': {
			'points': Global.points,
			'lifes': Global.lifes_player
		}
	}

func load_save_stats(stats):
	position = Vector2(stats.x_pos, stats.y_pos)
	Global.points = stats.stats.points
	Global.lifes_player = stats.stats.lifes

I really don’t know what happened in the part where I put in the JSON code the word “parent”, what should I do there?

Bug found in Godot Engine 3.5: Invalid get index ‘parent’ (on base: ‘Dictionary’).