Saving and Loading a 1D Array Error

I’m still quite new to Godot so I’m still learning. I’m trying to save/load an array (fish1) and it’s giving me error messages I don’t really understand.


FishingRod Script

fish_chance = randi() % 16 + 101 # 101 to 116
print(fish_chance)
fish_number = fish_chance - 100 # 1 to 16
MainScene.fish1[fish_number] += 1
load_sfx(sfx_reeling_fish)
%rod_sfx.play()
await get_tree().create_timer(0.5).timeout
splash.show()
splash.play(str(fish_chance))
print(MainScene.fish1)

MainScene Script (Autoload)

var fish1 = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] #17 slots
var sanddollar = 0

func _on_book_button_pressed():
	save()
	get_tree().change_scene_to_packed(scene_collectionbook)
	
	
func save():
	var file = FileAccess.open(save_path, FileAccess.WRITE)
	file.store_string(value.text)
	file.store_var(fish1)
	print("Saved")
	
func load_data():
	if FileAccess.file_exists(save_path):
		var file = FileAccess.open(save_path, FileAccess.READ)
		value.text = file.get_as_text()
		fish1 = file.get_var()
		sanddollar = int(value.text)
		print("Loaded")
	else:
		print("No Data Saved")
		value = null

# Called when the node enters the scene tree for the first time.
func _ready():
	load_data()

func _on_save_button_pressed():
	save()

The saving and loading for value.text works perfectly fine, and fish1 array also worked before trying to save/load it.

You should look at the docs on what get_as_text() does and change it to sanddollar = int(file.get_var()).

Instead of storing a string during save you can just store the int and not have to cast it.

1 Like

Hello,

The first error indicates that you are trying to access an index(10) in a null variable. Make sure MainScene.fish1 is not null and is a valid Array.

For the second error, the issue arises because you saved a string and an array in the same file. These two different data has been merged. You need to choose whether to save “text” or a variable.

When you write:

file.store_string(value.text)
file.store_var(fish1)

Godot first store a string in the file. After that it appends the fish1 variable.
Your data file will be something like this: "my text"[]

When you try to load it back with file.get_as_text() it’s not "my text" which is returned but "my text"[].
Consequently, when you do fish1 = file.get_var() the returned value will not be a valid data type or will just be null as Godot can’t load this incorrect data. You try to assign this invalid data type to a valid data type so you get an error saying that FileAccess.get_var() can’t convert the content of the file in a valid data type.
You can use FileAccess.get_open_error() to have more details if the loading process fails.

Since you want to store different data types in a single file, I suggest using a Dictionary. This approach lets you store various data types in one file without worrying about data collisions. Additionally, you can easily iterate over your data and perform more complex operations.

And as @pennyloafers said you can just save the text as an int and not have to cast it.

Here’s an example:


func save():
	var my_data = {
		"text": value.text,
		"fish1": fish1,
	}
	
	var file = FileAccess.open(save_path, FileAccess.WRITE)
	file.store_var(my_data)
	print("Saved")


func load_data():
	if FileAccess.file_exists(save_path):
		var file = FileAccess.open(save_path, FileAccess.READ)
		# Make sure to verify the integrity of your data. Who knows what happened to the file ?
		var stored_data = file.get_var()
		
		# Use Dictionary.get(value, default) instead of Dictionary["value"] or Dictionary.value
		# Only if you want to prevent errors to be raised in case of non existing keys. See Dictionary.get()
		value.text = stored_data.get("text", "No text was found!")
		fish1 = stored_data.get("fish1",  [])
		sanddollar = int(value.text)
		print("Loaded")
	else:
		print("No Data Saved")
		value = null

Check out this article to learn more about saving and loading files in Godot.

1 Like

Hello, thank you for explaining! It’s still showing an error message though?

func save():
	var my_data = {
		"valuetext" = value.text,
		"fish1" = fish1,
	}
	
	var file = FileAccess.open(save_path, FileAccess.WRITE)
	file.store_var(my_data)
	print("Saved")
	
func load_data():
	if FileAccess.file_exists(save_path):
		var file = FileAccess.open(save_path, FileAccess.READ)
		print("hello") # this prints
		var stored_data = file.get_var() 
		print(stored_data) # this doesn't print
		value.text = stored_data.get("valuetext", "!!!")
		fish1 = stored_data.get("fish1", [])
		sanddollar = int(value.text)
		print("Loaded")
	else:
		print("No Data Saved")
		value = null

Hello,
The error indicates that there is no get function in the data stored in the loaded file. The data returned by get_var is not a dictionary.
Did you save the new data (dictionary) before trying to load the file?
Otherwise, the returned data will be "my_text"[].
You can save the new data over the previous one or simply delete the previous data.

1 Like

It works now, thank you so much for the help!!

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.