Help with save/load in platformer game

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By ben2420

Hi, I’m making a simple 2D platform game, I’ve set up a main menu (with New Game and Continue buttons) and a pause screen while in game (with Save, Resume and Menu) buttons.

My problem is: I can get my ‘Save’ button to produce a .DAT file in the required user folder stating ‘World 1’ in text but I’m not sure how to get this to then load the game from this point when I press the ‘Continue’ button on the main menu. I want the game to continue when I press the ‘Continue’ button from the scene I was at when I saved the game in the pause menu.

This is my ‘’ where my save/load scripts are stored (I have this set to autoload in project settings):

    extends Node

var level = 1
var pause = false

func _ready():

func _save():
	var data = ""
	data += "World_ " + str (level)
	var new_file ="user://save.dat", File.WRITE)

func _load():
	var new_file =
	if not new_file.file_exists("user://save.dat"):
		return"user://save.dat", File.READ)
	var data = new_file.get_as_text()
	data = data.split("\n")
	for line in data:
		if line.begins_with("level"):
			level = int(line.split(" ")[1])

This is my MainMenu scene where my ‘New Game’ and ‘Continue’ buttons are:

 extends Control

var main = load("res://").new()

func _on_PlayButton_pressed():

func _on_ContinueButton_pressed():

I’ve been through all the guides and documentation and I can’t get any further… Help would be much appreciated as I’ve been really struggling to get it to work! Thanks!

:bust_in_silhouette: Reply From: Wakatta

Your code has some oddities like why are you saving in the _load function?
The line that causes your issue would be data += "World_ " + str (level) so that when you call if line.begins_with("level"): the line would actually be World_ 1

Not that looping your save file line by line is wrong but you’ll find better usability using a Dictionary with JSON. that being said i’ve took the leeway of adjusting your code as its not a true ‘dat’

var save_data = {
	"level": 1,
	"power": 0,
	"vitality": 6, 
	"dexterity": 40

func _save():
	var new_file =
	var error = new_file.open_encrypted_with_pass(
		"user://save.dat", File.WRITE, OS.get_unique_id()
	assert(not error, "Could not create save file")

func _load():
	var new_file =
	var error = new_file.open_encrypted_with_pass(
		"res://save.dat", File.READ, OS.get_unique_id()
	if error:
		print("Failed to load save file")
	var data = parse_json(new_file.get_as_text())
	if typeof(data) != TYPE_DICTIONARY:
            print("Save data corrupt")
	save_data = data

For testing purposes you can use but the final product should use new_file.open_encrypted_with_pass() additionally the benefit of using a Dictionary is to easily store and access your variables like save_data.level = 200

Thank you for your response, using this I’m now able to save as a real .DAT file in the project data folder.

My confusion is how do I save the game in a particular scene (“World_1”, “World_2”, “World_3” e.t.c) (with World_ being the names of my level scenes) and then when reloading the game upon pressing the ‘Continue’ button I’m returned to the scene where I saved at?
At the moment I save the game, it sends a file to the project data folder but this doesn’t mean I can continue from where I progressed to previously.

ben2420 | 2021-02-19 15:21

Depends on how your code is structured. Lets say your _save _load functions are in a Singleton which they should be

if your “Worlds” are being instanced by code you can do

func _ready():
    save_data.level = filename

func _on_ContinueButton_pressed():
    var level = load(save_data.level)

If your “Worlds” are Nodes in the tree that are just hidden / shown

func _ready():
    save_data.level = get_path()

func _on_ContinueButton_pressed():

and in the Singleton call your save load functions like this:

func _notification(what):
	match what:

Wakatta | 2021-02-19 15:57

Thank you for your help Wakatta. Honestly I’ve been trying with your help to get this working however I just can’t get the Continue button to load the game from where it was previously, when pressed it just does nothing all I can get it to do is print text to the console… It’s down to my limited coding knowledge as I’ve only been using Godot for a few weeks without previous experience, I think the only way I’ll be able to get it working for my game is through a screen share zoom call or sending my script on GitHub but I do appreciate your help and I’m definitely closer to getting it working :slight_smile:

ben2420 | 2021-02-19 19:02