What happens immediately after deleting a game object?

I have a problem where the comparison between a game object’s id before and after go.delete() differs depending on how the game object was created. I guess getting the id after go.delete() might be a bit silly, but since it’s not deleted until the post update (?) I thought it’d be OK.

Here’s a script showing the problem (attached to the go):

function init(self)
	msg.post(".", "acquire_input_focus")
	self.id = go.get_id()
end

function on_input(self, action_id, action)
	if action.pressed then
		go.delete()
		print(go.get_id() == self.id) --false if the go is in a collection created from a collection factory, otherwise true
		print(go.get_id(), self.id) --prints the same hash twice no matter how the go is created
	end
end

Putting the game object (1) directly in the bootstrap collection, (2) in another collection in the bootstrap collection or (3) creating the game object with a factory all yield the same result: The id comparison returns true. However, when I put the game object in a collection that is created using a collection factory, the ids are different in the equals operation even if they look the same.

What happens directly after deleting the game object and why does the behaviour differ depending on how the game object was created?

2 Likes

When reading the internal C++ code, I don’t see a reason why it couldn’t currently work. :thinking:

The thing is though: I would personally consider that game object to be “dead” after the call to delete(), and I would manage the code in such a fashion.

I’m not sure we have other use cases, e.g. where we might get callbacks to the script, after the GO was deleted. That’s also something to consider.

Not sure what our preferred way is here to be honest. Perhaps @britzl and @AGulev has some thoughts?

I totally agree. I would not expect anything related to a game object to work after calling go.delete().

True, you can probably get collision messages in the same frame as you delete a game object. And if go.get_id() behaves like described it might be a problem. @einar feel free to create an issue on GitHub!

Here’s the github issue: https://github.com/defold/defold/issues/7666. Let me know if I misunderstood anything about how go.delete is supposed to work.

So if I manage the game objects from elsewhere, best practice would be to delete them from there? This problem arose when I no longer could delete the id from a list because the id comparison didn’t work.

I’ve answered this issue on GH, and while I initially thought that go.delete() should invalidate the object, it would mean trouble for other scripts using the same url.
E.g. other scripts are already relying on the object existing for the remainder of the frame. If we were to change that, I guess a lot of games would break.

I think the biggest issue might be the discrepancy between functionalities, i.e. most functions still work, but some doesn’t.

2 Likes

All right. As the id comparison after go.delete() is one of those broken cases (at least for an object created from a collection factory), my workaround was to call go.delete(passed_id) after the list lookup. It seems to work just fine.

3 Likes

I’ve found that in this situation, comparing the results of hash_to_hex() of the ids works as expected. It’s possibly a little slow, and it’s not ideal, but it solved a problem.

1 Like