I would like to check if an instance reference is still valid to avoid errors. I’ve searched for this issue and only see mention that nothing like this exists. Is there some engine design reason that this isn’t incorporated or some major performance hit that would occur if it were supported?
The reason I ask: I created a (somewhat) complex path-finding design where enemies can notify other enemies if they spot the player to allow enemies which don’t see the player to follow the enemy which has spotted the player. However, the enemy the other enemy is following may die and then the reference becomes invalidated.
Defold has many design ideas based on past experience with things that didn’t work out well.
One of those things is continuously checking if an object exists.
This can, if one is not careful, lead to extra code bloat.
Another idea behind the engine is that we want to supply enough building blocks, so that our users can build what they need.
In this case, if you store your live enemies in a table, you can check if it’s alive or not.
This table game be located in a game_state.lua or similar, that is used by the other scripts.
With the caveat that @Mathias_Westerdahl’s answer is the best way to structure things (and indeed, it is what I do in my games), here is an example of how you can explicitly check if a game object exists:
function does_object_exist(id)
return pcall(function(id) go.get_position(id) end, id) == true
end
I’ve ended up using this function very occasionally in Fates of Ort, but it’s in situations where my state tables fail at detecting game object deletions (due to some error on my part) and I need to run a check just to make sure the script doesn’t error out and cause serious problems. Had my design been perfect I don’t think I would’ve needed the above function.
I have another use cases were I don’t think would lead to bad design or bad performance.
I can’t find communication in the direction from the editor to the code. I can’t ask anything to the scene while from code I need to know everything in advance. (Almost there ):
e.g. 1) Recently I had a group of several game objects with enumerated IDs (go1, go2, go3…), that need to be created and placed in editor. I needed to associate some data and behaviour from a single script. I could pre-process the level from script Init to find all the game objects with IDs go#, but since I don’t have a go.valid(id) function or similar to stop I couldn’t do it.
Current solution. Hard code the list, update the code if the level design changes.
e.g.2) Simpler. A dummy game object that a level designer can place on a level just to tell the code to activate certain game mode or enable disable some features, anything, without having to add more code or sending messages.
In general I wish ask even more features that have being requested in other posts. Knowing the list and hierarchy of the collection game object to at least pre-process it on the Init function. Allowing to associate our “classes” with game objects, for some of us that prefer to keep code in centralized Lua modules instead of associating scripts files with every game object or collections we put on our game.
PD: Thanks for the ‘pcall’ trick. I’ll use it, but it kind of scare me… I can see pcall is used for handling exceptions !
We’re pretty busy with the iOS and Android bundling issues, but as soon as that’s out of the way we can start looking into these suggestions and also continue with other things from our roadmap. Three useful functions that I feel we should prioritise are:
go.get_parent([id]) – get parent of own game object or game object with provided id
go.exists(id|url) – check if there’s a game object with the provided id or url
go.create([pos], [rot], [scale]) or go.new([pos], [rot], [scale]) – create an empty game object with provided transform