0 votes

So I tried making a save file for my game, so that the user can keep their settings even after the game is closed. I followed this tutorial and I tried changing some things to fit Godot 4 by reading documentation.

I get this when running the game Invalid get index 'play_music' (on base: 'Dictionary')., for context, here's the code that gives this error:

# music.gd - added to AudioStreamPlayer nodes who play music.
extends AudioStreamPlayer

func _ready():
    # Only play music if it is configured to do so.
    if FileAccess.file_exists(Settings.SAVED_SETTINGS_FILE):
        playing = Settings.settings_data["play_music"]

And here is Settings:

# settings.gd - This file is autoload.
extends Node

const SAVED_SETTINGS_FILE := "user://saved_settings.save"

var settings_data: Dictionary = {}

func _ready() -> void:
    save_settings()
    load_settings()

func save_settings() -> void:
    var file = FileAccess.open(SAVED_SETTINGS_FILE, FileAccess.WRITE)
    file.store_var(settings_data)

func load_settings() -> Dictionary:
    if not FileAccess.file_exists(SAVED_SETTINGS_FILE):
        settings_data = {
            "auto_walk": true,
            "play_music": true,
        }
        save_settings()
    var file = FileAccess.open(SAVED_SETTINGS_FILE, FileAccess.READ)
    settings_data = file.get_var()

    # I'm not sure if this is necessary, but it was in the documentation.
    return settings_data

I don't really know why this is happening, although it could be that music.gd's _ready() function is being called before setting.gd's.

I tried using resources which caused a lot of problems that were too complex for me and I heard they can run arbitrary code so I decided to try something else.

user:// here is in ~/.local/share/godot/app_userdata/game_name (I'm on Linux) which I have read and write permissions to, and saved_settings.save is present there.

Godot version 4.0.beta10
in Engine by (32 points)

Edit: This doesn't actually fix it, the issue only happens when the save file doesn't exist yet

I just had to change the save file from user://saved_settings.save (what the video used) to user://saved_settings.dat, I found it after re-reading the FileAccess documentation.

Here's what settings.gd looks like now (not many changes):

extends Node

const SAVED_SETTINGS_FILE := "user://saved_settings.dat"

var settings_data: Dictionary 

func _ready() -> void:
    #save_settings()
    load_settings()

func save_settings() -> void:
    var file = FileAccess.open(SAVED_SETTINGS_FILE, FileAccess.WRITE)
    file.store_var(settings_data)
    file = null

func load_settings() -> Dictionary:
    if not FileAccess.file_exists(SAVED_SETTINGS_FILE):
        settings_data = {
            "auto_walk": true,
            "play_music": true,
        }
        save_settings()
    var file = FileAccess.open(SAVED_SETTINGS_FILE, FileAccess.READ)
    settings_data = file.get_var()
    file = null

    # Unsure if this is necessary, but it was in the documentation.
    return settings_data

Well, technically I fixed it with this but I also didn't, I had to remove the save file then hope for the best, I'll test a bit more and decide whether this is good enough, but would be nice to have a way that just works

1 Answer

0 votes

Okay, it kind of works now?

I had to make @onready variables for Settings.settings_data and changed the file format to .dat and then deleted the save files

by (32 points)
Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read Frequently asked questions and How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to [email protected] with your username.