The Engine was crashing on a stack overflow. I suspect it was because it was looping in the Nodes to save because they all exported one another.
You had an exported Array which is meant to be unique, but you set it directly, making it shared by default.
I changed your code to make Nodes keep a numeric id, and keep links using only those. To get the Node using the id, I used a shared Dictionary (const) named siblings where all instances register themselves. Also added a delete button.
tool
extends Sprite
export var relatedList: Array #saved, not shared (see _init, would be with relatedList = [])
export var id := 0 #saved, not shared (as it is not reference passed)
const max_id := [0] #shared, not saved, the value (max_id[0]) only needs to be unique on creation, not accurate
const siblings := {} #shared, not saved
export (bool) var createNewTool = false setget create_new #editor 'button' to create new instance
export (bool) var delete = false setget delete #editor 'button' to cleanly delete self
var sceneResource = load("res://MySprite.tscn")
func _ready() -> void:
if Engine.is_editor_hint():
if id > max_id[0]: #keep the max updated when loading
max_id[0] = id+1
if !relatedList: #not loaded, newly created
relatedList = []
max_id[0] += 1
id = max_id[0]
siblings[id] = self
printt(name, self, id, max_id, siblings)
func create_new(value):
if Engine.is_editor_hint() and value and is_instance_valid(get_parent()):
#create new instance and add to scene/tree
var newSprite = sceneResource.instance()
get_parent().add_child(newSprite)
newSprite.set_owner(get_tree().get_edited_scene_root())
#update list of related nodes
relatedList.push_back(newSprite.id)
newSprite.relatedList.push_back(id)
#update exported array values
property_list_changed_notify()
newSprite.property_list_changed_notify()
func delete(value):
if Engine.is_editor_hint() and value and is_instance_valid(get_parent()):
siblings.erase(id)
print(siblings)
for related_id in relatedList:
var related = siblings.get(related_id, null)
if is_instance_valid(related):
var list: Array= related.relatedList
list.erase(id)
queue_free()
The Editor crashing is not normal, even if you tell it to do weird things. I recorded the crash under valgrind, here is the relevant section:
==62415== Stack overflow in thread #1: can't grow stack to 0x1ffe801000
==62415== Stack overflow in thread #1: can't grow stack to 0x1ffe801000
==62415== Can't extend stack to 0x1ffe801078 during signal delivery for thread 1:
==62415== no stack segment
==62415==
==62415== Process terminating with default action of signal 11 (SIGSEGV)
==62415== Access not within mapped region at address 0x1FFE801078
==62415== Stack overflow in thread #1: can't grow stack to 0x1ffe801000
==62415== at 0x77F1AF7: __printf_fp_l (printf_fp.c:933)
==62415== If you believe this happened as a result of a stack
==62415== overflow in your program's main thread (unlikely but
==62415== possible), you can try to increase the size of the
==62415== main thread stack using the --main-stacksize= flag.
==62415== The main thread stack size used in this run was 8388608.
==62415== Stack overflow in thread #1: can't grow stack to 0x1ffe801000
==62415==
==62415== Process terminating with default action of signal 11 (SIGSEGV)
==62415== Access not within mapped region at address 0x1FFE801F40
==62415== Stack overflow in thread #1: can't grow stack to 0x1ffe801000
==62415== at 0x71C2134: _vgnU_freeres (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_core-amd64-linux.so)
==62415== If you believe this happened as a result of a stack
==62415== overflow in your program's main thread (unlikely but
==62415== possible), you can try to increase the size of the
==62415== main thread stack using the --main-stacksize= flag.
==62415== The main thread stack size used in this run was 8388608.
Run with valgrind ./Editor --editor --path ./debug
using your original reproduction steps. Please consider filling a bug at https://github.com/godotengine/godot/issues
using your reproductions steps and the above error message.