The debug mode will generally tell you exactly what line had the error and give a decent short explanation of the error. Your error happened at this point
"clothes: " + clothes
because the + operation does not accept a string and a dictionary as arguments. If the first operand is a string, then the second operand must also be a string. The correct form would be
"clothes: " + str(clothes)
Yes, it is possible to combine everything into a single line, but it starts to get cumbersome if you wish to include proper contingency management. The "get" function will attempt to retrieve the value corresponding to the given key, but if that key is not in the dictionary then it will return a null. The square bracket operation ( dictionary[key] ) will do basically the same thing but it will cause an error if the key is not in the dictionary. The dot operation for objects and dictionaries is simply an alias for the square bracket operation with a string key. Therefore these two lines are equivalent.
globals.state.unstackables.get(person.gear.accessory).code globals['state']['unstackables'].get(person['gear']['accessory'])['code']
When an item slot is empty there is a null stored in that slot and there is no null in the "unstackables" dictionary, so get() is used to avoid errors. However, nulls have no indexing operations like get() or [], so "null.code" will cause an error. There is an optional second argument to get() that replaces the null with another value, which if passed a dictionary will allow the indexing without an error, like this:
globals.state.unstackables.get(person.gear.accessory, {}).code
The downside to this approach is that it creates and discards the blank dictionary every time the line runs. Since dictionaries are part of the core structure of GDScript, you will have skipped creating another entry in an existing dictionary for your variable in favor of creating an entire new dictionary.
Your getaccessory() is correct as far as I can see, but if you are looking for shortcuts then there are several you could use here. Since "acc" is simply a temporary storage for the return value, you could skip the variable and return immediately.
func getaccessory(code): match code: "accslavecollar": return "collar" "acchandcuffs": return "handcuffs" return null
However your entire function is simply searching for a key and returning the corresponding value, which is exactly what a dictionary does but slower.
var accessoryTextDict = {'accslavecollar':"collar", 'acchandcuffs':"handcuffs"} var accessory = accessoryTextDict.get( globals.state.unstackables.get(person.gear.accessory, {}).code )
If you would rather avoid the empty dictionary, then use an if statement:
var accessoryTextDict = {'accslavecollar':"collar", 'acchandcuffs':"handcuffs"} var accessory = globals.state.unstackables.get(person.gear.accessory) if accessory: accessory = accessoryTextDict.get( accessory.code )
Including "!= null" in the if statement adds clarity, but null converts to false so it is optional in this case. The accessoryTextDict can be put in file scope so that it is re-used for the duration of the file rather than created anew each time a function is run. You may use typeof() checks whenever you want, but generally we refrain from having the code protected against every conceivable problem in favor of designing with the expectation that the data is well controlled. It may be a bit more risky, but development time is a larger problem around here.
The print() function will put text in the standard output stream which will be displayed in the terminal window if you are using the Debug mod or in the output panel if you are running the game through the Godot editor. If you are not using either of those, then everything in the output stream is ignored.