Our project is based around world partition. In many cases, our game logic, done by scripting (ie, for missions), needs to establish a link between actors (ie, actors A and B) that is bidirectional in some cases. When using hard references between A and B, we are assured that these actors will be part of the same world partition cell and will be loaded/unloaded at the same time while when using soft references, there’s no garantee that A and B are loaded at the same time and one could unload before the other.
In our case, our missions are done in data layers and in many cases, some sharing needs to be done between specific missions where another common data layer is used. Since the Unreal engine doesn’t allow to have hard references between actors of different data layers, our designers often design their blueprints by using soft object pointers to make them generic (and usually they wait for them the first time they are spawned). But this creates, in many cases, various world partition issues where designers often don’t think about the fact that if the player goes far away, objects pointed to by soft object pointers could unload/reload and depending on which one is unloaded and which one is not, it becomes a pandora box of issues to deal with (mainly if a group of actors need to work together).
My question is how do you recommend to deal with this kind of issue via Unreal? Are there already some concepts in Unreal to help work around these issues to simplify game logic done in the world partition?
This is a common problem when designing quests in WP levels. The easy solution is to make the actor non-spatially loaded so they will be there at all time. That solution has the downside that it will make the assets referenced by those actors permanently loading which is not great for optimal memory use. There is the experimental Level Streaming Persistence plugin which can be used as an example of keeping track of changes but it does not allow for communicating or querying the state of unloaded actors.
Most teams are currently building a subsystem that handles the mission states and the “communication” between the actors in a deferred way. Think of a mix of a database and messaging solution.
Our missions are handled via a specific class that is blueprintable (controlled by a subsystem) and it exposes some events via blueprints that the designers use to perform their blueprint logic (ie, start/complete, etc.). But from that point, everything is done in blueprint and they access the actors directly via variables that they added (hard of soft refs) to call functions on them and perform logic (they can use some utilities to wait until a soft object ptr becomes valid in an async way also, but this is the part that can become confusing and error prone that I was saying in my first post). How would the messaging solution (“communication”) work in this case? Does it mean that you would avoid to use “normal” blueprint scripting in order to have something custom on top of Unreal to manage the access to actors? Also, we are talking about missions here, but the same issue can happen with anything else that has a dependency between 2 or more actors in the world partition (so it is not only “missions”).
We have not designed such systems here yet. If I had to, I would rely on soft references and predefined actions\messages. I would have a subsystem that would gather the messages and the actors would check the system for messages when they begin play.
Regarding missions, some licensees have built mission managers that are persistent and aggregate all mission related data.