0 votes

I have been trying to set up a custom save game, using the filedialog pop-up
However when I call these save/load functions.print(savename) does not respond, and load game fails to pass the check.

(Sorry for any clutter, I'll try to have separate projects for issues like this from now on.)

In my controller.gd

  extends Node
    #Item management
    var itemenabled = {
    Itemtest = true, 
    Coinage = true 
    }
    var itemquantity = {
    Itemtest = 0,
    Coinage = 0
    }
    #Player managment
    var spawn = Vector3(45.748199,3.45762,0)
    var inputenabled = true setget set_input
    enum enviromenttype { #To tell what enviroment the player is in
    outside
    inside
    home
    }
    var currentenvirment = enviromenttype.outside #The current levl enviroment type the player is in
    #Outside nodes
    onready var hud = get_node("/root/world/hud")
    #onready var hudinv = hud.get_node("inventory/label")
    #onready var text = hud.get_node("textbox/text")
    #onready var talkicon = hud.get_node("talkicon")

    #Save/Load Functions

    func save(): #returns the values of the selected node
        var savestruct ={
            filename=get_filename(),
            spawnx = spawn.x,
            spawny = spawn.y,
            spawnz = spawn.z,
            itemenabled = itemenabled,
            itemquantity = itemquantity
        }
        return savestruct

    func savegame(savename): #Saves the game
        print(savename)
        var file = File.new()#Creates data
        file.open(savename,File.WRITE)#Opens the file for saving data
    #   var savenodes = get_tree().get_nodes_in_group("save") #Get all the nodes in the group save
    #   for i in savenodes:
        var nodedata = save()
        file.store_line(nodedata.to_json())#stores node data, with the json file format.
        file.close()#Closes the file, finishes the saving process

    func loadgame(savename): #Loads the game
        var file = File.new() #set up the file variable
        if !file.file_exists(savename):#Checks if the file exists
            print("Check failed! No file exists")#Debug tool, checks if save game exists
            return #Check failed! No file exists

        var savenodes = get_tree().get_nodes_in_group("save") #Make sure the controller doesn't clone any nodes.
        for i in savenodes: #Gets the old nodes in group save
            i.queue_free() #Removes the old nodes in group save

        var currentline = {} #Load a line parameters
        file.open(savename,File.READ)#Opens the file for loading data
        while (!file.eof_reached()): #While there is negative integer (EOF)
            currentline.parse_json(file.get_line())#Gets the information on the save file
            var newnode = load(currentline["filename"]).instance() #Load the name of the file, based on savestruct of the file
            spawn = Vector3(currentline["spawnx"],currentline["spawny"],currentline["spawnz"])

            for i in currentline.keys(): #Get the rest of the variables in the savestruct
                if (i == "filename" or i == "spawn"): 
                    continue #There is no need to reload the filename, parent, or position, so skip them
                newnode.set(i,currentline[i]) #Load the remaining variables in the savestruct of the file
        file.close()#Closes the file, finishes the loading process
        pass

    #Player functions
    func set_input(value):#Disables or Enables the input of the player.
        inputenabled = value

in hud.gd

extends Control
#Outside nodes
onready var con = get_node("/root/controller")
#Characteristics
#Item management
onready var itemenabled = con.itemenabled 
onready var itemquantity = con.itemquantity 
#Child nodes
onready var text = get_node("textbox/text")
onready var storage = get_node("dialogstorage")
onready var inv = get_node("inventory")
onready var invlabel = inv.get_node("label")
onready var menu = get_node("menu")
onready var menufile = menu.get_node("filebox")

func _ready():
    add_to_group("save")#Add hud to group save, for save game
    invlabel.set_text(str(itemquantity)) #Makes the inventory viewable
#   print(con)#debug tool, for seeing if the controller.gd returns null
#   print("Items Enabled: "+str(itemenabled))
#   print("Items Quantity: "+str(itemquantity))
    pass

func setrichtext(value):
    text.clear()
    text.add_text(value)

func dialogtree(parameters): #Creates Dialog options
    #Children nodes for dialog tree
    var option = get_node("dialogoption").duplicate() #Duplicates the dialog option and it's children
    var button = option.get_node("button")#A duplicate of button
    var label = button.get_node("label")#A duplicate of label
    var command = parameters[0] #A action command with certain parameters
    var i = 0#The I stands for I, and thats a good thing 

    for operation in command: #adds a new dialog option, for every operation in the command parameters.
        var optiontext = operation.parameters[0]

        label.set_text(optiontext)#Set the duplicate's text
        button.connect("pressed", self, "selected", [i])#Will execute stuff like, animations and other functions

        var optionheight = Globals.get("playform/dialog_option_height")#Get a new height for the dialog option
        var optionsize = option.get_custom_minimum_size()#The space the dialog option will take up
        optionsize.y = optionsize.y*optionheight #Get the new height of the dialog option
        option.set_custom_minimum_size(optionsize) #Sets the new height of the dialog option

        storage.add_child(option)# Adds the dialog option
        if i == 0:
            button.grab_focus()
        i+=1 #increases the the I value

func selected(value):#When the dialog option is selected it will play this function
    pass


#Inventory
func addtoinv(item, value):#Inventory management, needs to be optimized better, replace the elif ladders with loops
    if item == "itemtest":
        if itemenabled.Itemtest == true:
            con.itemquantity.Itemtest += value
            invlabel.set_text(str(itemquantity))
            pass
        else:
            itemenabled.Itemtest = true
        pass 
    if item == "coinage":
        if itemenabled.Coinage == true:
            con.itemquantity.Coinage += value
            invlabel.set_text(str(itemquantity))
        else:
            itemenabled.Itemtest = true
    print(str(item) + str(value))
    pass

#Menu and buttons
func _on_buttonsave_pressed(): #opens the filebox for saving
    con.set_input(false) #Disable the input, so you can not move while typing
    menufile.set_mode(menu.get_node("filebox").MODE_SAVE_FILE)
    menufile.popup()
    pass

func _on_buttonload_pressed(): #opens the filebox for loading
    con.set_input(false) #Disable the input, so you can not move while typing
    menufile.set_mode(menu.get_node("filebox").MODE_OPEN_FILES)
    menufile.popup()
    pass

func _on_filebox_confirmed():#Saves/Loads a game depending on the filebox mode.
    print(str(menufile.get_filename()))#Debug tool checks the name of the filename WIP not reading the file name
    if menufile.get_mode() == menufile.MODE_SAVE_FILE:#Saves game
        con.savegame(menufile.get_filename())
    elif menufile.get_mode() == menufile.MODE_OPEN_FILES:#Loads game
        con.loadgame(menufile.get_filename())
    else:#If neigher it's not a supported file mode
        print("hud.gd failed to confirm files")
    con.set_input(true) #Reenables the input, so player can move

Could some one please tell me what I am doing wrong?

in Engine by (260 points)
edited by

Any error in the console?
What does file.open() returns? You should check error codes if you want to know what is happening.

uh how do I do that?

print(file.open(savename,File.WRITE))

gives me 12?

A good practice is to do this:

var ret = file.open(savename, File.WRITE)
if ret != 0:
    print("Could not open file, error ", ret)
    return

There is a list of error codes you can also get in GDScript in the documentatio of File... aaaaaand NO
The error codes are actually global constants, don't ask me why xD : http://docs.godotengine.org/en/stable/classes/class_@global%20scope.html?highlight=ERR_FILE
(scroll down to the ERR_FILE_* constants)

Okay thanks for the tips, but that still doesn't solve my problem. How do I get the function to open the file. More importantly, Why is it not opening the file?

Is your file in a subfolder that doesn't exist? Also, are you creating the file in user://? Never tried with filebox though... what's the path that you get?

in filedialog

user://home/user/folder/folder

testsave.sav

So It should work, but I have had an issue with print(str(menufile.get_filename())) it's not printing anything.

1 Answer

0 votes
Best answer

Okay I found out why I was having an issue with getting the file name from FileDialog.

 _on_filebox_confirmed():

is for AcceptDialog. getting the filepath (AKA: menufile.get_filename() ) Does nothing.

Instead there is a special function for FileDialog called file_selected( path )
Which gets the file path when the Ok button is pressed.

get_current_path() Also works.

by (260 points)
edited by
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 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 webmaster@godotengine.org with your username.