pandora icon indicating copy to clipboard operation
pandora copied to clipboard

Reference properties aren't serialized properly

Open TheWalruzz opened this issue 1 year ago • 1 comments

Godot version: 4.2.1

Describe the bug While trying to get equipment system working, I've noticed an issue with serialization of Reference properties. Apparently, using set_reference() on an entity instance with a reference property and then calling Pandora.serialize(...) results in that property being serialized as an object, instead of a Dictionary, which causes problems when trying to process serialized data further.

To Reproduce Consider an example project with this setup in Pandora as an example (ignore weird styling on dropdowns - I was messing with editor theme):

Zrzut ekranu 2024-02-14 174526

Initial reference in Helmet property is left empty.

Now, we run this code:

extends Node


@export var character: Character # extends PandoraEntity - Player entity is assigned
@export var item: HelmetItem # extends Item extends PandoraEntity - Simple Helmet entity is assigned


func _ready() -> void:
	var instance := character.instantiate()
	instance.set_reference("Helmet", item)
	var serialized := Pandora.serialize(instance)
	print(serialized)
	# prints: { "_id": "8", "_instanced_from_id": "8", "_instance_properties": [{ "_value": <PandoraEntity 'Simple Helmet'>, "_property_id": "7" }], "_index": 0 }
	var serialized_json := JSON.stringify(serialized)
	print(serialized_json)
	# prints: {"_id":"8","_index":0,"_instance_properties":[{"_property_id":"7","_value":"<PandoraEntity 'Simple Helmet'>"}],"_instanced_from_id":"8"}
	var deserialized_instance := Pandora.deserialize(JSON.parse_string(serialized_json))
	deserialized_instance.get_reference("Helmet")
	# Error: "Trying to assign a non-object value to a variable of type 'entity.gd'."

As you can see from the serialized Dictionary, Helmet property is serialized as { "_value": <PandoraEntity 'Simple Helmet'>, "_property_id": "7" } and when stringified to JSON it becomes a string, which is completely incorrect and causes an error in get_reference() method when trying to access that property after deserialization.

Expected behavior Reference property is properly serialized.

Desktop (please complete the following information):

  • OS: Windows
  • Version 11

Additional context Minimal reproduction project:

PandoraReferenceSerializationBug.zip

TheWalruzz avatar Feb 14 '24 17:02 TheWalruzz

I hit this a week or two ago, definitely not the expected behavior! A non-ideal workaround I went with was to use a string entity_id and fetching 'relations' with that id in the code. I didn't like it, but it doesn't leak too far if you're already writing a custom entity class:

@tool
extends Event
class_name PuzzleCompleted

func get_puzzle_set() -> PuzzleSet:
	return Pandora.get_entity(get_string("puzzle_set_id")) as PuzzleSet

Maybe a wrapper like this is how Pandora could handle this at serialize/deserialize time?

russmatney avatar Feb 14 '24 18:02 russmatney