godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
89.51k stars 20.26k forks source link

ConfigFile should print distinctive error message when trying to use `get_value()` before loading a file #72337

Open HPCR-SD opened 1 year ago

HPCR-SD commented 1 year ago

Godot version

4.0 Beta 16

System information

Windows 10

Issue description

I wrote a settings config file which takes some settings and saves them with ConfigFile. Well I can save no problem, but if you try and load it keeps telling me:

Invalid set index 'gamemode_selected' (on base: 'Node ()') with value of type 'Nil'.

If I go into the newly created settings.cfg file and remove the line between [section] and the keys and rerun my project it will work

Steps to reproduce

  1. Save data with ConfigFile
  2. load data with ConfigFile

Minimal reproduction project

Variables

const settings_filepath = "user://settings.cfg" var gamemode_selected: int = 4 var reversetime = false var finishbuttons = 0 var screenmode = 0

Save and load functions

func save_settings(): var configs = ConfigFile.new() configs.set_value("Game Mode Settings", "Game Mode", gamemode_selected) configs.set_value("Game Mode Settings", "Time Limit", reversetime) configs.set_value("Screen", "Screen Mode", screenmode) configs.set_value("Layout", "Finish Button", finishbuttons) configs.save(settings_filepath)

func load_settings(): var configs = ConfigFile.new() gamemode_selected = configs.get_value("Game Mode Settings", "Game Mode") # , 4) reversetime = configs.get_value("Game Mode Settings", "Time Limit") # , 0) screenmode = configs.get_value("Screen", "Screen Mode") # , 0) finishbuttons = configs.get_value("Layout", "Finish Button") # , 0)

Ready

func _ready(): SaveLoad.load_settings()

AThousandShips commented 1 year ago

You aren't opening the file according to this example code

HPCR-SD commented 1 year ago

Oh My...I had been going at this for over an hour trying to figure out what I was doing wrong what little thing I was missing. I have a load in mind that I didn't put here because the way I was using it wasn't relative and when I pulled it out to be sure or think I was sure, it acted the same. I should have realized at that moment what I was clearly missing too! I thought for sure I ran into something strange. You are correct though I quickly fixed that into my code and it is working. Well thank you and I apologize this wasn't the place for this then.

AThousandShips commented 1 year ago

It's a common mistake, it's very easy to stare at your code and just see what you think you had typed

HPCR-SD commented 1 year ago

What still has me confused is that if I changed a value in the settings.cfg file when I removed the line break between a section and keys it would load the variable still the same as it does now. I tested and was able to change gamemode_selected to return 3 when I print after loading. Maybe I still came across something...just not quite what I thought? That's kinda how my last bug report went lol!

Calinou commented 1 year ago

The following fails with an error message, but it's not clear that it's due to no ConfigFile being loaded first:

    var cf = ConfigFile.new()
    cf.get_value("hello", "world")
ERROR: Couldn't find the given section "hello" and key "world", and no default was given.
   at: get_value (core/io/config_file.cpp:84)

The following fails silently (it'll always return 5):

    var cf = ConfigFile.new()
    cf.get_value("hello", "world", 5)

Reopening, as we should make those cases print a clear, different error message. The second case technically works, but is very likely to be a mistake on the programmer's end – the kind of mistake that can leave you scratching your head for hours :slightly_smiling_face: