Invalid Access to property or key '{ }'

4.6

I am once again out here losing my marbles. I’m making a little point and click, menus only dog breeding game to demo some systems I might use for my other bigger project and get a little more familiar with gdscript. I’ve been doing pretty well, but I’m starting to set up the saving and loading. I want the game to write the dogs into a dictionary system kept on a global script, and then auto populate things like the kennel and breeding menu selection with the amount of dogs in the dictionary. I have separate ones for the male and female dogs, but the code is essentially the same, just with some names changed so I’ll just be showing one of them here.

the issue I’m hitting right now is the breeding menu. I’ve done an auto populating button system before while following a tutorial and it worked well, so I’m using the same code again but adjusted for the current needs. However, trying to run the game immediately crashes with the error ‘Invalid access to property or key ‘{ }’ on a base object of type ‘Dictionary[Dictionary, String]’ which just makes no sense to me? are the brackets not part of the dictionary? I am incapable of finding anything related online as the brackets are not considered in the search and nothing else I’ve found otherwise has been relevant to my particular issue. I had wondered for a moment if it was caused by nesting the dictionaries but that seems to be a pretty common practice for compiling information, as far as I’ve seen?

this is the global script the dogs are kept on (the individual dogs will later have more relevant information in their dictionaries, for now I just have placeholder names to test the code) I have the Options as a dictionary instead of an array because I’d like the buttons to display the names of the dogs, if I’ve even coded that part right. The tutorial I’d followed was for setting up a list of presaved colors the player could choose from, so I very well might’ve just fumbled rewriting it for this instead.

extends Node

#collection of dogs in the kennel

const OPTIONS_FEM: Dictionary [Dictionary, String] = {
	DOG_1:"F1",
	DOG_3:"F2"
}

const OPTIONS_MALE: Dictionary [Dictionary, String] = {
	DOG_2:"M1",
	DOG_4:"M2"
}

const DOG_1: Dictionary[String, String] = {
	"Name":"F1"
}

const DOG_2: Dictionary[String, String] = {
	"Name":"M1"
}

const DOG_3: Dictionary[String, String] = {
	"Name":"F2"
}

const DOG_4: Dictionary[String, String] = {
	"Name":"M2"
}

this is the button script, and I am getting the error on the last line of code here

class_name dog_select_fem extends Button

var dog: Dictionary

@onready var dog_button: Button = $"."

func _ready():
	dog_button.text = dogdict.OPTIONS_FEM[dog]

and this is the script for the menu itself

class_name dog_select_menu extends Control

signal changed_f(dog_f: String)
signal changed_m(dog_m: String)

@onready var _dog_button_f: PackedScene = preload("res://dogbutton.tscn")
@onready var _dog_button_m: PackedScene = preload("res://dogbuttonmale.tscn")
@onready var vbox_fem: VBoxContainer = $female/ScrollContainer/PanelContainer/VBoxContainer2
@onready var vbox_male: VBoxContainer = $male/ScrollContainer/PanelContainer/VBoxContainer2

var _dog_buttons_f: Dictionary[String, dog_select_fem] ={}
var _dog_buttons_m: Dictionary[String, dog_select_male] = {}
var _current_female: String
var _current_male: String

func _ready():
	_create_buttons_female()
	_create_buttons_male()
	
func _create_buttons_female():
	var options_f: Array = dogdict.OPTIONS_FEM.keys()
	
	for dog_f in options_f:
		var _dog_option_f: dog_select_fem = _dog_button_f.instantiate()
		
		_dog_option_f = dog_f
		_dog_button_f.pressed.connect(_on_dog_button_pressed_f.bind(dog_f))
		
		vbox_fem.add_child(_dog_option_f)
		_dog_buttons_f.text[dog_f] = _dog_option_f
		
func _create_buttons_male():
	var options_m: Array = dogdict.OPTIONS_MALE.keys()
	
	for dog_m in options_m:
		var _dog_option_m: dog_select_male = _dog_button_m.instantiate()
		
		_dog_option_m.dog_m = dog_m
		_dog_button_m.pressed.connect(_on_dog_button_pressed_m.bind(dog_m))
		
		vbox_male.add_child(_dog_option_m)
		_dog_buttons_m.text[dog_m] = _dog_option_m

func _on_dog_button_pressed_f(dog_f: String):
	_current_female = dog_f
	changed_f.emit(dog_f)

func _on_dog_button_pressed_m(dog_m: String):
	_current_male = dog_m
	changed_m.emit(dog_m)

You’re initializing a variable, but never assign any value to it.
The default value for a Dictionary variable is an empty Dictionary, which is {}.

Assign a value to that variable, e.g. like this (just change the Global to whatever your autoload is called)

var dog: Dictionary = Global.DOG_1
1 Like

if your keys for OPTIONS_FEM are dictionaries then dog_f is a dictionary. at the end you try to use _dog_buttons_f which is of type Dictionary[String, Button(dog_select_fem)], this last line is wrong in many ways. You cannot get .text from a dictionary, you probably meant to index into the dictionary to get the button, but then the way you are trying to index with dog_f is invalid since dog_f is a dictionary, not a String.

I don’t know how you would fix this, but I’d start by using Resources more than Dictionaries and especially Dictionaries of Dictionaries. As a rule of thumb if you intend to always have the save keys, such as “Name” it’s better as a Resource than a dictionary.

1 Like

You also make a new scene with _dog_option_f of type Button(dog_select_fem) but then immediately override it with this Dictionary.

thank you guys for the help! I figured I was probably just messing up changing the code from one node type to another :sweat_smile: I’ll take the time to learn more about resources :saluting_face:

adding this did stop this particular error, so thank you! I don’t know why that didn’t come to mind as I had to do something similar for a different error just a few days ago lol

I’d changed some names of things to make things a little clearer for the post and I guess accidentally took a bit of the code with it, whoops! it should be _dog_options_f.dog_f = dog_f if that makes any difference