Need Help in Save and loading system

Godot Version

Godot v4.2.2

Question

So I am working on a game where u collect certain pages or artifacts, and once u collect N artifacts you go to your world, but the thing is , I need a save and load feature, I search the mountain peaks and ocean depths but chat-gpt lol gave me some code to work with, but that saves only the position of the player not the scene and it’s alot buggier , here is the code snippets, might have done some errors ;-; , (is it cuz i added it in the player script or something ?)

here is the code

extends CharacterBody2D

@export var speed: int = 35
@onready var animated_sprite_2d: AnimatedSprite2D = $AnimatedSprite2D
var isAttacking = false
var facing_right: bool = true

const SAVE_FILE_PATH = "user://save_game36.save"

func _ready():
	load_position()

func handleInput():
	var moveDirection = Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down")
	
	velocity = moveDirection * speed
	
	if not isAttacking:  # Check if not attacking to allow movement
		if moveDirection.length() > 0:
			if moveDirection.x == 0:
				if moveDirection.y > 0:
					animated_sprite_2d.play("walk_front")
				elif moveDirection.y < 0:
					animated_sprite_2d.play("walk_down")
			else:
				if moveDirection.x < 0:
					animated_sprite_2d.play("walk_left")
					if facing_right:
						animated_sprite_2d.flip_h = true
						facing_right = false
				else:
					animated_sprite_2d.play("walk_right")
					if not facing_right:
						animated_sprite_2d.flip_h = false
						facing_right = true
		else:
			animated_sprite_2d.play("idle")
			
	if Input.is_action_just_pressed("attack") and not isAttacking:
		animated_sprite_2d.play("attack")
		isAttacking = true
		$Area2D/CollisionShape2D.disabled = false
		if animated_sprite_2d.flip_h==true:
			$Area2D/CollisionShape2D.disabled = true
			$Area2D/CollisionShape2D2.disabled=false
		

func _physics_process(delta):
	handleInput()
	move_and_slide()

func _on_animated_sprite_2d_animation_finished():
	if animated_sprite_2d.animation == "attack":
		$Area2D/CollisionShape2D.disabled = true
		if animated_sprite_2d.flip_h==true:
			$Area2D/CollisionShape2D.disabled = true
			$Area2D/CollisionShape2D2.disabled=true
		isAttacking = false

func save_position():
	var save_file = FileAccess.open(SAVE_FILE_PATH, FileAccess.WRITE)
	if save_file:
		var scene_file_path=get_tree().current_scene.filename
		var save_data={
			"scene":scene_file_path,
			"position":global_position
		}
		save_file.store_var(save_data)
		save_file.close()
		print("Game saved!")
	else:
		print("error")

func load_position():
	if FileAccess.file_exists(SAVE_FILE_PATH):
		var save_file = FileAccess.open(SAVE_FILE_PATH, FileAccess.READ)
		if save_file:
			global_position = save_file.get_var()
			save_file.close()
			print("Game loaded!")
	else:
		print("No save file found, starting from the beginning.")

func _exit_tree():
	save_position()

    

In your save-method under “save_data” you have to put everything in that you want to save and do the same for the load-method. normally you would do an extra script for saving and loading. I suggest watching a tutorial on how to save and load.

I have seen , but most of them are for one scene or just Saving position, the scenes aren’t saved, can u suggest some ?, sorry this is new to me

It might help to know what exactly is being saved and why. At the end of the day scenes are just positions (and other properties) of things, if you can make a list of what change is really needed to be stored then it will be easy to code.

I need the character position, aswell as the scene to get saved, so after restarting the game, the saved scene begins

I was able to get my scenes to save by doing this in my save game function:

	var scene = PackedScene.new()
	scene.pack(get_node("SCENE PATH").get_child(0))
	savedGame.mainScene = scene

This method allowed me to specify a scene to save.
To load i did this in the load game function:

	var scene = get_node("SCENE PATH").get_child(0)
	scene.queue_free()
	
	var r = savedGame.mainScene
	r = r.instantiate()
	var root = get_node("SCENE PATH")
	root.add_child(r)

You could simply repeat this for each scene you need saved, although you still need to save/load whatever variables would affect the scene.
Good luck!

p.s. might be worth mentioning that I used a custom Class and the Godot resource saver to save/load, so my method might not work for you unless you do the same. I followed this video tutorial to learn: https://www.youtube.com/watch?v=TGdQ57qCCF0&t=699s

1 Like

Ohh okay, will try it out, the gdquest video also I have seen it :pensive:, thankx alot