Simple answer: No, we shouldn’t! But, your FPS are too low or you really need/would like to have more FPS? Then: Yes. – And if you’re not sure at all? Then just try it! Implement a pre-allocated memory structure. Many ways to do that. E.g.: Use one haxe.ds.Vector
for all your game objects (they must share the same extend
class or implements
the same interface). (Or you do ECS. But that’s another topic.)
So, you finally need this, when you iterate over things (often! maybe many times per second). It just means your game data isn’t all over the place in the RAM, which can be the case for a List
or an Array
. And be creative! E.g.:
var all_game_objects : Vector;
var all_NPCs : Vector;
var hostile_creatures : Vector;
var wild_animals : Vector;
(more on Haxe Vector API + manual)
…
worrying about creating new objects and letting them go
Of course once implemented you also have to think of the life-cycle of this fixed array and at some point when there’s no more space for new data in that array you have to re-allocate it to give it more space. (So FPS might/will drop in that moment.)
HashLink
Like you said HashLink has a garbage collector deleting all objects that don’t have any reference refering to them.
Check if not null!
I think a simple, good idea can be just to check if a reference is null
before you act on it. So the “hunter” first checks if the “prey” is still available (hasn’t been deleted). Actually that should solve most issues and otherwise you get an error of course.
if( entity != null ) {...}
pre-allocating memory, pooling, etc.
Of course fixed arrays are faster for iterations, because the memory is pre-allocated, yes. If you need this than consider using haxe.ds.Vector instead of List, Array and others. (Reminder: the Array
class in Haxe is not equivalent to the array class in C++/Java, but a for instance a list)
(Also more details can be found → here. But this is getting indepth…)
Other concerns
“Zombies”
But for instance when you delete something – something with a sprite maybe – then someone or something has to make sure also e.g. it’s sprite gets deleted and doesn’t stay in the scene like a zombie/ghost . E.g. either you delete let’s say “sheep” with/by its custom “delete()” function that knows what to do (has the reference to the sprite to delete it, too)… or you have a decoupled graphics system that sees “oh this sprite has a null reference to its owner object so the sprite is also to remove” …
and then to code that is either complex or unnecessarily complicated…
Under more special circumstances you can give an object (that will be removed) a list/array/vector of objects that need to be informed when it is deleted (like a subscriber pattern). Like so they come to it’s funeral…
– or you only mark things that need to be deleted because you want to make sure that some other task/function is executed first (but can’t imagine right now where exactly you would need that…) but then things get complicated (maybe)
But, whenever you can, keep it as simple as possible.
sorry, answer became quite bloated and messy …