I have a bit of a conundrum that I am trying to sort out. In our project, we have enabled Actor pooling via a fork of MassActorSpawnerSubsystem, which means that we often have actors that are “destroyed” and lay dormant until they are needed for re-use. However, unlike *actual* destruction, this means that the pointers to these Actors are not invalidated but remain in use. Most of our game systems handle this by subscribing to the broadcast that indicates these need to be cleaned up and doing it at useage sites, but I have not been able to determine a way to handle this feature integration smoothly with StateTree.
While it is true that we can write our tasks and property functions to validate the state of actors being operated on at runtime, there is an edge case that concerns me where we may store a reference to an Actor or many Actors in a StateTree parameter, and then reference this parameter later in the tree. But in the meantime it is possible for that Actor to both enter the pool and then come out of it for re-use - in that case we would want to ignore trying to operate on it, and in any other scenario it would be removed from a variable.
The approach that I have tried to undertake is to find a way to modify the InstanceData at the beginning of the tick to seek out and manually null pointers to Actors that are in a pooled state, but I haven’t been able to figure out how to access StateTreeInstanceStorage in a way that would let me perform this operation. I had poked around at FStateTreeExecutionContext::UpdateInstanceData but am somewhat at a loss trying to understand all the Index values in use and how to appropriately look for Actor references within all the untyped FInstancedStruct representations. I’d appreciate any direction here if anyone has ideas. 
I do not know what version of the engine you are using. However, you could use a global task on your StateTree that binds to the delegate you have created for when an actor is recycled to the pool. That global task could use FStateTreePropertyRef to bind to the parameter(s) that would hold a reference to the actors so it could remove and update the parameters. This could be done async outside of a tick on the tree with capturing WeakExecutionContext for the tree. If you have data stored in State Parameters as well, you could have the global task use the StateTreeDelegateDispatcher to signal what was changed to tasks on those states that use property refs so they can update their data.
-James
No worries. I just didn’t want to say to use something that might be missing if you were in earlier versions. It is also a possibility that something got reset while making the question.
The task should only need to be present for where new parameters were being stored. If you keep the array of Actors as a global parameter for the whole tree, a global task accessing that parameter as a property ref would be all that is needed. If you are storing them at several places in the tree as a parameters for states, you would need a task that could bind to that parameter to handle removing recycled actors. This should not require a task for every state (assuming the state does not have an Actor or array of Actors parameter. So their can be tasks that use the array of actors but no tasks that update it at any place in the tree. With a system like this, I would think to use a global parameter and task for managing the lifecycle of the parameter.
I think you could likely create a validator to run as we have other validators for property bindings. I do not think I would recommend trying to do this fully from outside code accessing instance data as there could be issues as we make more of StateTree able to run off the game thread. Changing data could be potentially problematic if an async task is running on that data. Normally, we copy values for parameters when starting a task, but propertyrefs mean that some are dealing with the data directly.
-James
Oh my mistake, I thought I had assigned the engine version here - we are currently on 5.6.1.
The task approach would probably work, but I was hoping for a solution that I could set up in code that didn’t require manually binding to every actor property in each tree we create in order for it to have the “right” behavior. It seems like an easy thing for us to miss on the project. Is modifying the execution context to automatically take care of this problem just a bad idea?
Alternatively, if a task-based approach is really the way we need to go about this, do you think it would be possible to write data validation for our trees at editor time to scan for Actor parameters and ensure that there is a property binding for them to this type of watchdog task? The new Bindings window lead me to believe it should be possible to test for the existence of a specific target task but I haven’t dug into it too much.