Godot 4.3
i have problem in making a save system i am tried many ways but nothing happened
if anyone have script and worked with him please help me
Godot 4.3
i have problem in making a save system i am tried many ways but nothing happened
if anyone have script and worked with him please help me
Well, if you ask me, building a save system every time is very old-fashioned and taking the time to design it slows down the development process a lot, so:
Install GProgress plugin and just:
GPro.save_progress(user_id, game_state) #save game
game_state = GPro.load_progress(user_id, progress_id) #load game
Install SLib and just:
SLib.save_file(path, value) #save file
your_var = SLib.load_file(path) #load_file
iam sorry can you tell me the steps i should do
You have to show your script for us to help, aka what you have tried. You also need to explain what you expected to happen versus what really happened (any errors)?
This appears to be a duplicate of this thread you started save file system , but with less information.
extends Node
var SAVE_PATH = “user://savegame.data”
func save() → Dictionary:
return {
“total_coin”: Event.total_coin,
“level_data”: Event.level_data
}
func save_game() → void:
var save_file = FileAccess.open(SAVE_PATH, FileAccess.WRITE)
if save_file:
save_file.store_var(save())
save_file.close()
print(“Game saved successfully.”)
else:
print(“Error: Could not open save file for writing.”)
func load_game() → void:
if not FileAccess.file_exists(SAVE_PATH):
print(“No save file found, creating new save.”)
save_game()
return
var save_file = FileAccess.open(SAVE_PATH, FileAccess.READ)
if save_file:
var saved_data = save_file.get_var()
save_file.close()
if saved_data.has("total_coin"):
Event.total_coin = saved_data["total_coin"]
else:
Event.total_coin = 0
if saved_data.has("level_data"):
Event.level_data = saved_data["level_data"]
else:
Event.level_data = {}
print("Game loaded successfully.")
else:
print("Error: Could not open save file for reading.")
func _notification(what):
if what == NOTIFICATION_WM_CLOSE_REQUEST:
save_game()
extends Node
@onready var points_Label = $“…/UI/Panel/points”
@export var hearts: Array[Node] # Array of heart nodes for lives display
var total_collectables = 0
var curr_level: int = 0
var points = 0
var lives = 3
var is_ui_ready = false # Flag to check if UI is ready
func _ready():
# Set the flag indicating UI is ready
is_ui_ready = true
func _process(delta):
if is_ui_ready:
# Load game data and set points from saved data
FileManagerSingleton.load_game()
points = Event.total_coin
# Update the points display in the UI
if points_Label:
points_Label.text = "Points: " + str(points)
else:
print("Error: points_Label is null! Check the node path.")
# Set the flag to false so it only runs once
is_ui_ready = false
func decrease_health():
lives -= 1
print("Lives remaining: " + str(lives))
# Update heart icons based on remaining lives
for h in range(3):
if h < lives:
hearts[h].show()
else:
hearts[h].hide()
# Reload the current scene if lives reach zero
if lives == 0:
print("Game Over!")
get_tree().reload_current_scene()
func add_point():
GameData.points += 1 # Increment points in GameData
# Update points display in the UI
if points_Label:
points_Label.text = "Points: " + str(GameData.points)
# Update total coin count in Event and save the game
Event.total_coin = GameData.points
FileManagerSingleton.save_game() # Auto-save after collecting points
# Check if all collectables are collected and emit signal
if GameData.points == total_collectables:
emit_signal("all_collectables_collected") # Trigger level completion
func set_total_collectables(count: int) → void:
total_collectables = count
func change_level(next_level: int):
curr_level = next_level # Update current level
Event.level_data[next_level] = false # Unlock next level
FileManagerSingleton.save_game() # Auto-save before level change
# Change scene to the next level
get_tree().change_scene_to_file("res://scenes/levels/level_" + str(next_level) + ".tscn")
extends Area2D
@export var target_level: PackedScene
@export var level_index: int # Identifies the current level
@onready var game_manager: Node = %GameManager # Reference to the Game Manager
func _on_body_entered(body):
if body is CharacterBody2D:
# Unlock the next level (make sure next level exists in level_data)
if Event.level_data.has(level_index + 1):
Event.level_data[level_index + 1] = false # Unlock next level
FileManagerSingleton.save_game() # Auto-save progress
get_tree().change_scene_to_file(“res://scenes/hud.tscn”) # Move to the next level
extends Control
@onready var scene_tree = get_tree()
@onready var level_complete: TextureRect = $LevelComplete
@onready var game_manager: Node = %GameManager # Reference to the Game Manager
@onready var coin_count_label = $“…/UI/Panel/points” # Assuming “points” is a label to display points
var total_collectables = 0 # Track total number of collectables
var coin_count = 0 # Coin count initialized
func _ready() → void:
Event.level_completed.connect(_on_level_completed)
func display_level_complete() → void:
if Event.curr_level >= Event.level_data.size():
$LevelComplete/TextureRect/HBoxContainer/NextLevelButton.visible = false
scene_tree.call_group(“buttonContainer”, “hide”)
level_complete.visible = true
func _on_level_completed():
coin_count = game_manager.get_coin_count() # Assuming GameManager manages coin collection
$LevelComplete/TextureRect/MoneyTexture/MoneyLabel.text = str(coin_count)
Event.total_coin += coin_count
var next_level = Event.curr_level + 1
print(Event.level_data)
if Event.level_data.has(next_level):
Event.level_data[next_level] = false # Unlock next level
FileManagerSingleton.save_game() # Save after level completion
display_level_complete()
func goto_home() → void:
get_tree().change_scene_to_file(“res://scenes/menu/main_menu1.tscn”)
func goto_level_select() → void:
get_tree().change_scene_to_file(“res://scenes/menu/Level select/levelselect.tscn”)
func goto_next_level() → void:
var next_level := “res://scenes/levels/level_” + str(Event.curr_level + 1) + “.tscn”
if FileAccess.file_exists(next_level):
Event.curr_level += 1
get_tree().change_scene_to_file(next_level)
extends Control
@onready var scene_tree = get_tree()
@onready var moneylabel = $MoneyTexture/Label
@onready var level_grid = $TextureRect/LevelGrid
func _ready():
FileManagerSingleton.load_game() # Load saved data
connect_level_selected_to_level_box()
# Set level data or initialize the levels for the first time
if Event.level_data.is_empty():
setup_level_box() # First-time setup for locked levels
else:
for box in level_grid.get_children():
box.level_num = box.get_index() + 1
# Unlock levels based on saved data
box.locked = Event.level_data.get(box.level_num, true) # Default to locked if no data
moneylabel.text = str(Event.total_coin)
func setup_level_box() → void:
if level_grid:
for box in level_grid.get_children():
box.level_num = box.get_index() + 1
box.locked = true # Lock all levels initially
level_grid.get_child(0).locked = false # Unlock the first level
func change_to_scene(level_num: int) → void:
# Ensure the level data reflects the correct state before transitioning
Event.curr_level = level_num
scene_tree.change_scene_to_file(“res://scenes/levels/level_” + str(level_num) + “.tscn”)
func connect_level_selected_to_level_box() → void:
if level_grid:
for box in level_grid.get_children():
box.connect(“level_selected”, change_to_scene)
func _on_home_button_down() → void:
scene_tree.change_scene_to_file(“res://scenes/menu/main_menu1.tscn”)
func on_level_completed(level_num: int) → void:
# Unlock the next level after completing the current one
if Event.level_data.has(level_num):
Event.level_data[level_num] = false # Unlock the level
# Update the `locked` state of the level button
for box in level_grid.get_children():
if box.level_num == level_num + 1: # Unlock the next level
box.locked = false
# Save the updated game state
FileManagerSingleton.save_game() # Save progress after level completion
@tool
extends TextureButton
signal level_selected
@export var locked: bool = true:
set(value):
# Avoid recursion by directly setting the locked status and calling appropriate functions
if locked != value:
locked = value
if locked:
level_locked()
else:
level_unlocked()
@export var level_num = 1
func level_locked() → void:
level_state(true) # Disable button and show label for locked state
func level_state(value: bool) → void:
disabled = value # Button is disabled when locked
$Label.visible = not value # Show label when locked (hidden when unlocked)
func level_unlocked() → void:
level_state(false) # Enable button and set label text when unlocked
$Label.text = str(level_num)
func _on_pressed() → void:
if not locked: # Only emit signal if the level is unlocked
level_selected.emit(level_num)
extends Node
var completed_levels = {} # Store completed levels (e.g., {1: true, 2: false})
var total_coin = 0
var level_data = {} # Add level data if needed
var curr_level = 1 # Default starting level
signal level_completed
func mark_level_completed(level: int) → void:
completed_levels[level] = true
# Unlock the next level
level_data[level + 1] = false # Set the next level to unlocked (false)
emit_signal(“level_completed”)
save_game()
func save_game() → void:
# Use FileManagerSingleton to save the game state
FileManagerSingleton.save_game()
func load_game() → void:
# Check if the save file exists
if FileManagerSingleton.file_exists(“res://path_to_save_file”):
# If the save file exists, load the saved game data
FileManagerSingleton.load_game()
else:
# If no save file exists, initialize the level data and coins
level_data = {1: false, 2: true} # Example: level 1 unlocked by default, level 2 unlocked after level 1
total_coin = 0 # Initialize total coin to 0 (or any starting value)
# Optionally save the initial data
save_game()
this is the codes the error when finish level 1 level 2 didnt work
Make sure to format your pastes, if it’s a long script maybe you can trim the paste to relevant parts or highlight where the error occurs
Can you share the errors you get? Looks like at most 11 in the Debugger panel.
Seems like you are setting locked here, sounds correct enough to me, does your box
have a locked
setter? can you print Event.level_data
before this for loop is run?
If this is run it seems like it will always load the default level data, since the file “res://path_to_save_file” will never exist.
no error appear when i finish level 1 level 2 should unlocked
it didnt happen
this is the file
# in finish.gd
if Event.level_data.has(level_index + 1):
Event.level_data[level_index + 1] = false # Unlock next level
Your level complete checks if the next level exists before unlocking it, it doesn’t exist in the level_data
because you give it a empty dictionary on start, no level data exists, so it will never unlock the next level.
Also none of your finish nodes have their level index set correctly.
The level select should check for locked nodes like this, instead of using the not operator
box.locked = Event.level_data.get(box.level_num, true)
The save file was never the issue, make sure to use prints or breakpoints to debug your project. I found these issues by print(Event.level_data)
at various points like I asked in this post
Event.level_data before level select: { 1: true }