+2 votes

Hi, I'm trying to save some variables and load them. The saving part works perfectly, but the loading doesn't.

Here are my 2 scripts Player.GD and SaveAndLoad.gd (which is on autoload)

extends KinematicBody2D

    export (int) var speed = 200

    var vel = Vector2()
    var player = SaveAndLoad.player
    var damage : int = 1
    var maxHp : int = 20
    onready var rayCast = $RayCast2D




    var xpToNextLevel : int = 50
    var xpToLevelIncreaseRate : float = 1.2

    var interactDist : int = 70
    var facingDir = Vector2()

    onready var anim = $AnimatedSprite
    onready var ui = get_node("/root/MainScene/CanvasLayer/UI")


    func _ready ():
        ui.update_textLevel(player["curlvl"])
        ui.update_health_bar(player["curhp"], maxHp)
        ui.update_xp_bar(player["curxp"], xpToNextLevel)


    func _physics_process(delta):
      vel = Vector2()
      if Input.is_action_just_pressed("attack"):
        try_interact()
      if Input.is_action_just_pressed("save"):
        SaveAndLoad.player = player
        SaveAndLoad.save()
      if Input.is_action_pressed('Right'):
        vel.x += 1
        facingDir = Vector2(1, 0)
      if Input.is_action_pressed('Left'):
        vel.x -= 1
        facingDir = Vector2(-1, 0)
      if Input.is_action_pressed('Down'):
        vel.y += 1
        facingDir = Vector2(0, 1)
      if Input.is_action_pressed('Up'):
        vel.y -= 1
        facingDir = Vector2(0, -1)

      vel = vel.normalized() * speed
      vel = move_and_slide(vel, Vector2.ZERO)
      manage_animations()


    func manage_animations ():

        if vel.x > 0:
            play_animation("RunRight")
        elif vel.x < 0:
            play_animation("RunLeft")
        elif vel.y < 0:
            play_animation("RunFront")
        elif vel.y > 0:
            play_animation("RunDown")
        elif facingDir.x == 1:
            play_animation("IdleRight")
        elif facingDir.x == -1:
            play_animation("IdleLeft")
        elif facingDir.y == -1:
            play_animation("IdleUp")
        elif facingDir.y == 1:
            play_animation("IdleDown")

    func play_animation (anim_name):

        if anim.animation != anim_name:
            anim.play(anim_name)


    func give_xp (amount):

        player["curxp"] += amount
        ui.update_xp_bar(player["curxp"], xpToNextLevel)
        if player["curxp"] >= xpToNextLevel:
            level_up()

    func level_up ():

        var overflowXp = player["cuxp"] - xpToNextLevel

        xpToNextLevel *= xpToLevelIncreaseRate
        player["curxp"] = overflowXp
        player["curlvl"] += 1
        ui.update_level_text(player["curlvl"])
        ui.update_xp_bar(player["curlvl"], xpToNextLevel)

    func take_damage (dmgToTake):

        player["curhp"] -= dmgToTake
        ui.update_health_bar(player["curhp"], maxHp)
        if player["curhp"] <= 0:
            die()

    func die ():

        get_tree().reload_current_scene()

    func try_interact ():

        rayCast.cast_to = facingDir * interactDist 

        if rayCast.is_colliding():
            if rayCast.get_collider() is KinematicBody2D:
                rayCast.get_collider().take_damage(damage)
            elif rayCast.get_collider().has_method("on_interact"):
                rayCast.get_collider().on_interact(self)

    func _notification(what):
        if (what == MainLoop.NOTIFICATION_WM_QUIT_REQUEST):
            SaveAndLoad.player = player
            SaveAndLoad.save()
            get_tree().quit() # default behavior

SaveAndLoad
extends Node

const FILE_NAME = "user://game-data.json"
var player = {
    "name": "Zippy",
    "curhp": 10,
    "curxp": 10,
    "curlvl": 1

}

func _ready():
    SaveAndLoad.load_game()

func save():
    var file = File.new()
    file.open(FILE_NAME, File.WRITE)
    file.store_string(to_json(player))
    file.close()


func load_game():
    var file = File.new()
    if file.file_exists(FILE_NAME):
        file.open(FILE_NAME, File.READ)
        var data : Dictionary = parse_json(file.get_line())
        file.close()
        if typeof(data) == TYPE_DICTIONARY:
            player = data
        else:
            printerr("Corrupted data!")
    else:
        printerr("No saved data!")

Like I was saying, the Saving works, the data goes into the file, but when it loads, it goes back to the default I have put in var player.

in Engine by (26 points)
edited by

1 Answer

0 votes
Best answer

In SaveAndLoad.gd, player variable gets updated via load_game function called from _ready function which is executed once the script enters or is instanced from an active scene.
So in Player.gd you assign defaultplayer value before it was processed by any methods.
Either move player = SaveAndLoad.player expression to _ready or call load_game manually from Player.gd before it.

by (68 points)
selected 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.

Categories