Invalid access to property or key 'item_name' on a base object of type 'EncodedObjectAsID'

Godot Version

4.6.2

Question

Hi, I’m in the process of making a text based adventure game and I’m currently working on implementing saving/loading. Right now there’s an issue when I try to load the player inventory. After loading the game and opening up the inventory it gives me the following error (Invalid access to property or key ‘item_name’ on a base object of type ‘EncodedObjectAsID’). I’m unsure why it would be causing an error because I though it was just saving what was in the player inventory array and just loading what was in that.

If anyone knows what the cause of the issue is please let me know.

This is the player class. It’s having an error on line 21 in the show_inventory func. The “item_s += i.item_name” line specifically.

extends Node

var vertus_inventory: Array = []

func add_to_inventory(item: Items):
	vertus_inventory.append(item)
	
func remove_from_inventory(item: Items):
	vertus_inventory.erase(item)
	
func show_inventory() ->String:
	if vertus_inventory.size() == 0:
		return IType.color("Vertus looks in his pack...nothing was found.", "SYSTEM")
	var item_s = ""
	var last_item = vertus_inventory[-1]
	
	for i in vertus_inventory:
		if i != last_item:
			item_s += IType.color(i.item_name, "ITEM") + IType.color(",", "DEFAULT") + " "
		else:
			item_s += i.item_name
		#item_n = i.item_name
	return "Inventory: " + IType.color(item_s, "ITEM") + "\n"

This is the save_load script.

extends Node

## Called when the node enters the scene tree for the first time.
func _ready() -> void:
	_load()

const FILE_PATH: String = "user://SaveFile.json"

var save_data: Dictionary = {
	"player_inventory": []
}

#"current_room": Room.new()
func _save() -> void:
	var file: FileAccess = FileAccess.open(FILE_PATH, FileAccess.WRITE)
	file.store_var(save_data)
	file.close()

func _load() -> void:
	if FileAccess.file_exists(FILE_PATH):
		var file: FileAccess = FileAccess. open(FILE_PATH, FileAccess.READ)
		var data: Dictionary = file.get_var()
		for i in data:
			if save_data.has(i):
				save_data[i] = data[i]
		file.close()

And this is a portion of the command processor. The match statement is what all of the player commands are. At the end of the match statement is my save and load commands.

extends Node

signal change_room(new_room)
signal update_room(cur_room)

var cur_room = null
var vertus = null

func initialize(start_room, vertus) -> String:
	self.vertus = vertus
	return changing_rooms(start_room)

func process_a_command(input: String) -> String:
	# Splits the string the user inputs at each space.
	var player_words = input.split(" ", false)
	if player_words.size() == 0:
		push_error("Player has no words to parse.") #"Error: No words have been parsed."
	var word1 = player_words[0].to_lower()
	var word2 = ""
	var word3 = ""
	var word4 = ""
	if player_words.size() > 1:
		word2 = player_words[1].to_lower()
	if player_words.size() > 2:
		word3 = player_words[2].to_lower()
	if player_words.size() > 3:
		word4 = player_words[3].to_lower()
	match word1:
		"move":
			var array = move(word2, word3, word4)
			var s = ""
			for i in array:
				s = s + str(i)
			return s
		"help":
			return player_help()
		"grab":
			return grab(word2, word3)
		"inventory":
			return show_inventory()
		"drop":
			return drop_item(word2, word3)
		"use":
			return use_item(word2, word3)
		"speak":
			return speak(word2)
		"give":
			return give(word2, word3)
		"save":
			SaveSystem.save_data.player_inventory = vertus.vertus_inventory
			
			SaveSystem._save()
			return IType.color("Game Saved", "SYSTEM")
		"load":
			SaveSystem._load()
			
			vertus.vertus_inventory = SaveSystem.save_data.player_inventory
			
			return IType.color("Game Loaded", "SYSTEM")
		_:
			return IType.color("Think carefully...what does Vertus do?", "SYSTEM")

Both store_var() and get_var() have a parameter full_objects: bool = false. If you want to save and load Objects to a file, you need to pass true as additional argument.

Thank you this worked! I’ve never messed with saving/loading before in Godot so I was unfamiliar with the additional parameter.