I've made a wonderful optimization to Airscape by dividing up all the levels into a grid and destroying certain static objects which are too far away from the player, and using 'recreate initial objects' To bring them back when the player gets nearby again. All of these static objects are part of a family and so can be easily regenerated with the aforementioned action.
It works fantastically, however I've run into a fairly substantial issue and I was wondering if anyone could help out.
Airscape has a robust 'terrain motion' system where almost all the game objects can optionally be pinned to nodes that will move them in certain ways. Most of the static terrain instances that are subject to the optimization aren't pinned to nodes like this, but in most levels a few are. When using the create/destroy grid optimization, these pinned objects are destroyed/recreated - and when they are recreated, they are totally misaligned with their node and unpinned, since the initial state is reset.
Putting the nodes themselves in the family isn't an option, because they need to be operational even when the player is far away. Doing other sorts of fancy tricks won't work either - what happens when destroyed terrain is brought closer to the player by a node?
All I need is a way to exclude certain instances from the destroy/recreate process. Excluding them from being destroyed is easy, because I have full control over my method of destroying objects occupying a certain region. Excluding them from being recreated, however, is proving impossible as the 'recreate initial objects' action doesn't leave its loop exposed to the event sheet - it simply recreates all instances - and if those instances haven't been destroyed, it just creates another copy on top of them! If the action was instead 'recreate instance' I could do something with that - but as it stands, it does appear like there's no way to exclude certain instances from this action.
It's possible that I could create my own recreation function entirely, by storing valid objects in JSON format at start of layout (along with their coordinates) and recreating them as necessary, but this seems messy and expensive - I'd have to use the Nickname plugin to recreate objects by object type. Presumably for the 'recreate initial objects' action C2 does this internally, or something similar, but in a more efficient way.
Does anyone have a method that I could have missed? And does anyone thing that this is a feature worth looking at adding?
i don't know if i understand correctly but if i did then this propably can help you?
or try adding an instance variable sort of Boolean and then execute actions based on this?
Fidasx Yes I'd obviously add a boolean, but the point is, recreate objects doesn't let you filter which instances are regenerated, it just regenerates them all.
the instance bank does look promising though, I'll look into it.
EDIT: Just looked into Instance bank, doesn't work because it requires loading all saved objects, not objects by region.
I looked into Grid Freezer too but it seems to be weirdly complicated, performance intensive, and doesn't preserve Z order.
If you can easily identify which of the recreated objects should be pinned, but aren't, can you just destroy those?
AllanR good idea, I thought the same thing, but how would I identify them? If I just pick all the objects with the boolean variable set, then I'll delete the originals and the duplicates.
I suppose I could store a list of UID's of all the originals, then delete everything with the boolean *except* the objects on this list! I just hate the idea of creating something only to destroy it right away.
A little side question: what kind of performance gains do you get there? Is it like 1000000 objects that are clogging the CPU? (it should not be a rendering issue, those are culled by themselves, if they are far away)
if you select by the Boolean variable, and another condition "not is pinned"
then you would only delete the new duplicates.
I know how you feel about creating something only to destroy it. But that may be less expensive than any other system of tracking and deciding what to recreate. It is probably only a little pointer you are wasting - don't think of it as some giant image : )
Eisenhans the layout has about 2000 objects. 'engine' CPU usage is about 30% with that many objects. You're correct, it's not a rendering issue, and render cells are on.
AllanR Good point however I also want to be able to make some objects exempt even if they might not be pinned to anything. And yeah, you're probably right, it's not too much to worry about probably.
well, you could add another Boolean flag for the exempt ones, then only delete the ones that aren't pinned and not exempt.
Edit: actually, you could probably do it with one flag - just the exempt flag. When you pin an object, just make it one of the exempt ones.
Then after recreating objects, only exempt ones would be duplicates. I guess you would have to check for the exempt flag in an On Created event, and delete them there.
Develop games in your browser. Powerful, performant & highly capable.
All right, I got it to work with two booleans (one set at edit-time) but it's still dodgy and has a few problems.
The main problem is that I can't set the boolean dynamically, because presumably 'recreate initial objects' collects the object state before any events have even been run. It's important that they are set dynamically because I do not want to have to manually set this flag for every single object that's pinned/exempt.
An ideal solution for all of this would be to have an action to 'freeze' or 'unfreeze' an object, and have it go into zero-CPU mode. I noticed Ashley looked into this in another thread but it seems like it was abandoned in favour of the 'recreate initial objects' action.