How to handle World Partition and Save Data

Hi, in our project we have a you could say souls-like save system. Player can either exit the game’s level and then return to that level with the exact same state.
Furthemore player can “rest” at a bonfire-like object which restores everything non-permanent in the level while keeping the permanent objects state (destroyed structures, defeated bosses etc…) and of course player progress.

We have considered switching to World Partition as a convenient way to travel across one bigger world instead of many smaller levels. Capturing state of currently loaded level cells is unchanged, the problem to solve is when player traverses cells, does some changes in that world and then leaves the cell so it gets unloaded.
Me scouting in UWorldPartitionSubsystem I did not find any delegates indicating cells load / unload events. How is this exactly intended to be accessable to the developer?

Theory would be to capture a state of a cell before it gets unloaded and restore a state of a cell when it gets loaded again. But currently I am not sure that the World Partition API supports this without engine modifications.

Its all manual, and if you are modifying systems like foliage you have to save/load their state(s) as well.

Generally, just make all your objects that can be changed and saved have a dedicated gameplay tag, write some c++ to loop and store/restore their state.

Word partition will load/unload cells based on distance.

Your objects should probably handle their own state instantiation by loadong/unloading their state when in proximity to the player - that could also be a bad idea if many objects are near, so how you handle it depends on how things are positioned.

A catch all to that would be creating a manager that uses a non game thread to handle the loading part.

That all makes sense and is already partially done. Instead of a tag I use ISaveableEntity class which works almost the same in practice. My biggest issue to solve when thinking about how to do this, is how can I capture a state of a cell before it gets unloaded. Does the actor EndPlay have a specific reason in them that I could maybe use?

  1. Segmentation: Divide the game world into manageable partitions using world partitioning techniques to optimize performance and memory usage.
  2. Data Management: Develop a robust system to save and load data specific to each partition, including player progress, object states, and dynamic changes.
  3. Serialization: Implement proper serialization methods to convert complex data structures into formats that can be saved and loaded efficiently.
  4. Consistency: Ensure data consistency during save/load operations by using checkpoints and validating data integrity to prevent errors or discrepancies.
  5. Testing: Thoroughly test the partitioning and save/load processes to ensure seamless transitions between sections of the world while maintaining gameplay integrity.

Generalized nonsense aside,

No, but the cells should have a load/unload call you can tap into.

Depending on engine version, data layers offer a more accessible way to set this up.

I think in the older .18 i had to custom code the engine source to perform a function on load/unload. Could have been .22. Its been long enough that I can’t remeber.
However thats probably a good option for you as well.

Having the engine source and building from source is usually better since oh-so-much of the engine doesn’t work right anyway…

1 Like