Weird things with saving info to files

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

Hello there!

Okay hang with me this is very confusing, I’m trying to save the high score of my game and the “spending score” (which is just the past score you got added on to each other) but I am having issues saving these both to the same file (stick with me) but when I do it adds the “spending score” as it should but it also does the same thing with the high score, I checked my code to make sure it’s not doing anything to add

How do I know it’s not me being an idiot (hopefully) in my code.
I tried saving them both to a different files and it worked! (sort of) high score wasn’t getting added it was keeping the high score and “spending score” was being added onto itself,
But whenever I close Godot and reopen it “spending score” gets wiped but high score stays.

here’s my code -

spending score -

func save_spend_score():
print("saving spending score")
var save_dat = File.new()
save_dat.open(SAVE_FILES_PATH, File.WRITE_READ)
save_dat.store_var(spending_score)
save_dat.close()
func load_spend_score():
var file = File.new()
if file.file_exists(SAVE_FILE_PATH):
	file.open(SAVE_FILES_PATH, File.READ)
	spending_score = file.get_var(spending_score)
	print("this is the spending score    ", spending_score)
	file.close()

high score -

func save_highscore():
var save_data = File.new()
save_data.open(SAVE_FILE_PATH, File.WRITE_READ)
save_data.store_var(highscore)
save_data.close()

    func load_highscore():
var save_data = File.new()
if save_data.file_exists(SAVE_FILE_PATH):
	save_data.open(SAVE_FILE_PATH, File.READ)
	highscore = save_data.get_var(highscore)
	print("this is highscore   ", highscore)
	save_data.close()

forgive me for the code being spaced weird the code sample was being weird and only let me put the code in like that

If you can help me on this HUGE thanks!

:bust_in_silhouette: Reply From: jgodfrey

Your main issue here is that for each of the score saves, you do the following:

  • Open the file
  • Write the data
  • Close the file

With the above, the file’s ModeFlag (that second arg on the open call), is really important.

You’re using File.WRITE_READ) which is documented as:

Opens the file for read and write operations. The file is created if it does not exist, and truncated if it does. The cursor is positioned at the beginning of the file.

So, that means, even if the file exist, it’ll be emptied on open. So, if you saved something in it the first time, when you open it for the second save, you’re effectively wiping out the contents you just put in it.

It’d be easier to change your save and load code to save and load everything all at once if possible.

So…

  • Open the file
  • Save (or load) everything
  • Close the file

That way, the “truncation” doesn’t matter. If you really do need to “open | write | close” for each item, then you’ll have to get fancier.

Specifically, you’ll want to change your ModeFlag to READ_WRITE, which is documented to NOT truncate the existing file. But, even then, the open will leave the cursor at the beginning of the file. To “append” data, you’ll need to manually move the cursor to the end - likely via File.seek_end().

well I’ve been trying to get my file system to work all day to a very frustrating end, here are all the problems I cannot solve to save my life,

  • whenever I close my game my files don’t save UNLESS I call a function to reopen it and close it again I already close the file at the end of all my code whenever I do anything with files

  • when I try to use file.get_as_text() I only have two of these :slight_smile: in the file

  • if I open the file and get data from it before I put any new numbers in it, it works fine and doesn’t break BUT if I first put data ( a number) into it and then later try to get that data again from the file it just gives me null instead of a number (I do use file.seek(the_variable_name) before any calls and if I don’t use it also gives me null and print(file.get_error) gives me error 18 (end of file) I also have a check before I call it to make sure that var is not null it only becomes null after I call get_var

my code -

func save_spend_score():
var file = File.new()
file.open(SAVE_FILES_PATH, File.READ_WRITE)
if file.get_var(spending_score) == null:
	print("null")
else :
	file.seek(spending_score)
	print(file.get_error())
	spending_score = file.get_var(spending_score)
	print(spending_score)
	print(file.get_error())
	spending_score += score
	file.seek(spending_score)
	file.store_var(spending_score)
	print("ready score  ", spending_score)
file.close()

Tentamens | 2022-08-12 02:14

File.seek doesn’t work like you (apparently) think it does. The value passed to function is the number of bytes from the beginning of the file. So, if you have a file containing 20 bytes and you do a file.seek(16), that moves the cursor to the 16th byte in the file. Following that, any read or write operation will start from that file position.

Honestly, rather than attempting to read/write individual values to your file, I’d recommend that you manage all of the values you want to save in a dictionary. Then, when it comes time to persist the data, you can read and write the entire dictionary all together.

jgodfrey | 2022-08-12 02:38