NVSaveLoad is a plugin for saving and loading the state of the game.
It is designed to “just work”, being very easy to integrate with almost no setup. Unlike other save/load systems, you don't need to explicitly tag the specific actors or properties to save - it instead saves everything that has changed automatically.
Its basic functionality can be used by simply installing the plugin and assigning input bindings for saving and loading functions.
Key Features
Minimal setup
For most common use-cases, saving and loading “just works” with a single function call.
An event handler to update or rebuild the game’s UI after a reload is generally also needed, UI state is not saved.
Save and load full level snapshots
Everything (or nearly everything, see Limitations) in the level will be saved automatically.
Every actor in the current map will be saved, including any of its properties which have changed, all without needing any explicit setup.
This includes all properties, and also the internal non-property state of most standard Unreal components.
The state of the GameInstance is also saved.
Fast same-map reloads
When reloading a game from the same map as the one the player is currently in, the save will be applied to the map without reloading it, resulting in extremely fast load times in this scenario.
Minimal saved data
While all changes are saved, the plugin minimises the amount of un-changed data saved for each actor, in order to keep the size of save files relatively low.
This also allows saves to maintain compatibility across different (patched) versions of the map, without the save overriding those changes.
User-readable saves
Saves are stored in human-readable JSON format, and screenshot images in standard JPEG or PNG format.
Save files are stored inside zip files (optional), keeping filesize down.
Multi-level support (optional)
When streamed sub-levels are unloaded (via Unreal’s Level Streaming system), the plugin can remember their state and restore it when the level is re-loaded.
This allows parts of a large level to be dynamically loaded/unloaded without losing their state.
The player and other actors can also be transferred between entirely separate maps; the state of the departed map will be saved, and restored upon re-entry.
This allows for a more classic-style multi-level with loading zones, such as those used in games like Half-Life or System Shock 2.
Highly configurable
Most features can be configured through the plugin’s configuration page.
The data being saved can be customised, by specifying classes or properties to ignore, or configuring getter and setter functions to use.
The plugin can also be extended by adding custom serialisation logic in C++.
Rolling save backups
Saves can be configured to have a number of rolling backups, allowing you to e.g. cycle between several quicksave and autosaves slots.
Support for loading screens (optional.)
Support for an on-screen saving indicator (optional)
Limitations
While the system will generally save almost everything automatically, there are some things which it will not be saved:
Static mesh actors with static mobility
These are intentionally not saved, because they represent the game world and are not expected to change.
If you need to save the state of such an actor, either change its mobility, or apply the provided NVSavable interface.
UI Widgets
While saving these would be possible, it would be saving a huge amount of data for something that is generally not persistent anyway, massively inflating the size of save files.
For complex UI, it is recommended to rebuild the UI after loading a game, using the provided post-load hooks.
Non-dynamic events and timers
Only dynamic timers and event bindings can be saved.
All timers and event bindings set up in Blueprints are dynamic.
Static event bindings and timers (e.g. C++ bindings with direct function pointers) cannot be saved.
If a C++ timer or event handler needs to be saved, use a Dynamic Delegate for it instead.
Randomised elements on BeginPlay
These can cause issues with saving; this can be worked around by waiting a tick before applying randomisations.
State trees
Limited saving; only global parameters are saved and loaded. The tree will be restarted upon reload.
Open world
The plugin does not support open worlds that use world partitioning. This kind of massive map generally doesn’t fit with the “save the entire map” paradigm that the plugin uses.
The plugin’s support of dynamically loading and unloading sub-levels through Blueprints is also somewhat limited, see full documentation for more details.
Multiplayer
The plugin does not support multiplayer. Mulitplayer games generally have a different architecture, and likely need something more custom.
Complicated, custom C++ systems
These are beyond the scope of a generic plugin.
Custom C++ logic which relies on anything other than UPROPERTY values will likely need custom logic around saving and loading