Resource error: "Invalid access to property or key 'speed' on a base object of type 'Nil'."

Thanks a lot for your detailed feedback! That’s surely a way to do it, but I wanted to try the Resource way since it’s a Godot advantage.

I managed to make it work like this.
Players script:

@export var _stats: PlayerResource: set = _set_stats, get = _get_stats
var speed = 0.0

func _process(delta: float) -> void:
	if _stats != null:
		speed = _stats.speed
	else:
		push_error("PlayerResource is not set! Make sure it's assigned in the Inspector")

func _set_stats(_new_stats):
	print("Enter Set new stats")
	_stats = _new_stats

func _get_stats():
	return _stats

PlayerResource script stays the same.
And of course I imported the .tres PlayerResource in the Player’s Inspector.

Also, if you’re interested, I finished the Saving Manager by adding this to the Main script:

@onready var _player = $PlayerRoot/Player
var _save_game = SaveGame

func save_and_load() -> void:
	if Input.is_action_just_pressed("save"):
		print("Save pressed")
		_save_game = SaveGame.new()
		_save_game.player_resource = PlayerResource.new()
		_save_game.player_resource = PlayerResource.new()
		_save_game.global_position = _player.global_position
		_save_game.save_game()
	elif Input.is_action_just_pressed("load"):
		print("Load pressed")
		_save_game = SaveGame.load_game()
		_player.global_position = _save_game.global_position
		_player._stats = _save_game.player_resource


func _process(delta):
	save_and_load()

and this in the SaveGame Resource (which also incorporates PlayerResource as a sub-resource):

const SAVE_GAME_PATH := "user://save.tres"

# The Resource incorporates whatever other sub-resource gets added here (eg: HUD, inventory, etc.)
@export var player_resource: Resource
# This allows to save the current Player's position.
@export var global_position := Vector2.ZERO


# Save the SaveGame resource at the pointed folder.
func save_game() -> void:
	ResourceSaver.save(self, SAVE_GAME_PATH)
	print("Game saved")


# Load the SaveGame resource. If there's no file at the pointed folder, it results in an error.
static func load_game() -> SaveGame:
	var res = ResourceLoader.load(SAVE_GAME_PATH)
	if res == null:
		push_error("Failed to load save game.")
		return null
	print("Game loaded")
	return res as SaveGame


# Check if there's already a saved file.
static func save_exists() -> bool:
	return ResourceLoader.exists(SAVE_GAME_PATH)

Hope this helps somebody!
Also, please let me know if there’s anything you’d do differently or a more efficient way to adjust the code. I’m all ears!

Thanks again!
Cheers

1 Like