[PLUGIN] Savior

WHAT is Savior:

This is a major update for the “Auto-Save Game” system I’ve been maintaining up on Unreal Marketplace for last couple years.

Focused on performance and data reach, I’ve totally scrapped original code and wrote this version from scratch, implementing a fully custom serialization engine that made possible for me to achieve the goal of moving away from the built-in ‘FArchive’ system and it’s ’ << ’ operator constraints. The reasons why I moved away from the internal FArchive operator are many, so I won’t go too much into details about this… Instead, let me throw at screen the new ‘features’ for you:

  • Savior 3 is tens of times faster than Savior 1.x releases.

  • Multi-Threaded Save & Load capabilities, no freezes or hiccups.

  • Save all data from outside your Game’s main thread, even Actor References.

  • Save any class. Any UObject is now supported, not just Actors or Components.

  • Versioning. Your Game will be capable of loading from old ‘*.SAV’ files after patches.

  • Encryption. All data goes through a lightweight, fast, multi-platform compatible encryption pass.

  • Optimized: Savior 3 is designed to predict and avoid crashes at all costs, no matter how complex Levels are.

  • Optimized: NO Components needed to be attached anywhere thus no memory eaten for the sake of storing data.

  • Optimized: NO destructive workflow. Existing Actors aren’t destroyed/replaced, keeping references alive and safe.

  • Optimized: NO containers created when saving game data thus no big chunks of memory garbage generated.

  • Optimized: Savior 3 Slots are UObjects, not Actor nor Component, avoiding large resource allocations.

  • Automatic Level Transitions on Load from Slot.

  • Threaded Save & Load the whole Game World or individual Actors.

  • Threaded Save & Load Game Mode in real-time, independent of Level.

  • Threaded Save & Load Streamed Levels without pausing the Gameplay.

  • Threaded Save & Load all Properties marked ‘Save Game’, no C++ required.

  • Threaded Save & Load any Dynamically-Created Classes of Actors and Components spawned in Runtime.

  • Threaded Save & Load Actor’s Scale, Location and Rotation, Linear and Angular Velocity automatically.

  • Threaded Save & Load Actor’s Visibility state, Collectibles’ or Particle Systems’ state automatically.

  • Optional Built-in HUD Class with auto generated Load-Screens with Blur, Splash-Screens or Videos.

  • Optional Built-in Progress Bar System with auto generated UI Elements for your Loadscreens.

  • Optional Built-in Slot Widgets with auto generated UI Slot Elements for your HUD Menus.

  • Optional Built-in support for Slot UI Thumbnails and UI/UX Decorators.

An intuitive Slot System for Save & Load:

https://i.imgur.com/R9N8qXw.png

Threaded World Save & Load for Performance Boost:

https://i.imgur.com/sozYw4F.png

Built-In Load Screens System:

https://i.imgur.com/vfKKoiO.png

https://i.imgur.com/rxH6ZMP.png

5 Likes

[API REFERENCE]

Full List of Savior’s Blueprint Functions (Savior 3)

3 Likes

How to Setup a Slot:

As always, create a Slot Asset on Asset Browser;
Opening the Asset you can quickly adjust default Properties such as Default Player Name, Levels Thumbnails, etc:

2 Likes

How to Save & Load from any Slot Asset:

All you have to do is right click any graph on any of your Blueprints and search from one of main nodes in “Savior 3” section.
These main Save/Load functions automatically creates a runtime instance of a Slot object for you… So you don’t have to instantiate anything, just reference the Slot Asset and let the node work:

https://i.imgur.com/muiPiDr.png

From any UMG Widget you simply setup your “On Button Clicked” events to call one of these “Savior 2” functions.
It’s THAT simple, everything in scope marked ‘SaveGame’ tag will save or load:

https://i.imgur.com/JNseaSb.png

2 Likes

How to Setup Pickups to Auto-Destroy on Load:

Any Actor you wish to remember it was destroyed and should not respawn on Level load, you have to add a “Destroyed” Boolean Property to it. And mark it ‘Save Game’ tag as well:

https://i.imgur.com/Rmq7TDb.png

The Property must be a Boolean named “Destroyed”, case sensitive.
The Property must be marked ‘Save Game’ tag.

Then in your Blueprint Graph, create a new Function calling it whatever you’d like, this Function will be a substitute of “Destroy Actor” node for the Game.
Inside this Graph Function set the value of “Destroyed” to true, but don’t destroy this Actor before you save the Game, maybe hide it instead:

https://i.imgur.com/KHPG44O.png

Having that Boolean “Destroyed” Property set to TRUE will tell the Plugin that this Actor must destroy itself once the Level was loaded, making it be gone the next time a Player visits that Level…

To do that, when you want a Pickup to be destroyed, simply call your newly created Function that hides the Actor and sets “Destroyed” to True instead of destroying the Actor with a Destroy node:

https://i.imgur.com/uvp1CJM.png

Once the Game is saved, the Plugin will Destroy the Actor after it’s “Destroyed” Property has been recorded, so the Actor won’t be left there consuming memory.

1 Like

How to Setup Procedural Actors Spawned at Runtime to Auto Save & Load:

An Actor, or Component, you are spawning at Runtime will be saved as usual.
However loading them back is a complex task because we cannot control whatever ID the internal engine will assign to a runtime spawned Object.
Often the new Object’s ID will be random internal pointer that used to reference another object; to overcome this obstacle to Save & Load “Procedural Actor” properly, your Procedural Class is required to implement three things:

  • Implement the “SAVIOR_Procedural” Function Interface.
  • Include a “Guid” Property to its Variables List, named “SGUID”.
  • In its Construction Script, call a special node called “Make SGUID”.

Those three simple steps above will guarantee your Procedural Class will be loaded correctly from Slot’s Data without mismatching Data with another instance of your Class also spawned in Runtime, turning them into Absolutely Identifiable Procedural Objects. So…

IMPORTANT:

First, within desired Procedural Actor’s Blueprint, we have to implement our “Procedural” Function Interface:

Once that is done, we now have to create a “Guid” Property for the Procedural Class and name it “SGUID”:

The Property must be a Guid Struct named “SGUID”. Savior will ‘read’ the Property and expects it to be this type, otherwise it will be ignored.
The Property must be marked ‘Save Game’ tag to be visible to the Auto-Save System.

That been done, only step left now is making sure SGUID’s value is persistent and unique.
That would be a headache for you to do, so instead of trying to control its behavior, there’s a node that can do that for you within a Construction Script…

Add the “Make SGUID” node to your Construction Script Graph and assign its output value to the “SGUID” Property:

Do NOT use a default “New Guid” node! The Guids created by that aren’t persistent, it would break our logic.

And it’s done, your ‘Procedural Class’ is ready to be freely spawned in Runtime and be automatically respawned with it’s correct Property’s values restored once the Game is reloaded from a Slot.

More Info about IDs:
Understanding SGUID

1 Like

How to Use Tags as Command Parsers for Save/Load Functions in C++ Domain:

You can customize Serialization of certain characteristics of your Class with Savior without typing code; using simple “Tag” commands.

With a few String Tags you can configure your Class to opt-out of specific data that would otherwise be serialized in “Save World/Level” functions:


Just apply the Tag you see fit your Design to your “Actor Tags” or “Component Tags” list, like the example below:

1 Like

Savior 3 update:

[Improvement]:

  • Savior 3 is nearly 30% faster on heavy data loading. :heavy_check_mark:
  • Restores Relative Transform attachments on respawn. :heavy_check_mark:
  • Load World: added “Reset Level on Load” option. :heavy_check_mark:
  • Load Level: added “Stream Level on Load” option. :heavy_check_mark:
  • Mitigating ‘Child Actor’ transform conflicts on load. :heavy_check_mark:
  • Added support for Class Reference properties. :heavy_check_mark:
  • Added support for Int64 properties. :heavy_check_mark:

[New Built-in Systems]:

  • Save/load Skeletal/Mesh Reference (root component mesh). :heavy_check_mark:
  • Save/load Animation Blueprints’ properties (Variables). :heavy_check_mark:
  • Save/load Movable Lights’ native properties. :heavy_check_mark:
  • Save/load Dynamic Materials’ properties. :heavy_check_mark:

[New Nodes]:

  • [SAVIOR] Open Level (+HUD). :heavy_check_mark:
  • [SAVIOR] Open Level (+HUD) +Callbacks]. :heavy_check_mark:
  • [SAVIOR] Load Object : (Slot Data). :heavy_check_mark:
  • [SAVIOR] Load Component : (Slot Data). :heavy_check_mark:
  • [SAVIOR] Load Actor : (Slot Data). :heavy_check_mark:

Open Level (+HUD) nodes:

These nodes can execute an action to open a persistent level while triggering a Savior Slot’s loading screen.
It doesn’t perform any data load from any slot, just opens a regular persistent map.

https://i.imgur.com/pmtpt0J.png

Load Object nodes:

The Load xxx (Data) internally were called StaticLoadxXx functions…
This have changed, you will have to replace them to new ones now they have been renamed in C++.

https://i.imgur.com/PyXPhih.png

Animation Blueprint Variables:

I have added support for directly saving and loading properties of Anim Instance Blueprints that are marked ‘Save Game’ on spawned Characters;
Removing the need to pass data through Characters to their AnimBP after a slot was loaded.
Your Animation Blueprint must implement the ‘Savior Serializable’ interface for this to work.

https://i.imgur.com/BuQiulT.png

https://i.imgur.com/AFDA4Cb.png

https://i.imgur.com/3na8G8C.png

Skeletal Meshes, Static Meshes, and Dynamic Material Instances:

A bundle of new algorithms that allows us to save and runtime load skeletals or meshes of root components;
As well as restoring dynamic material instances’ parameters, such as scalar params, vector params, and texture object params.
This was the hardest one to add since it touches stuff from a bunch of different threads, including the rendering thread.

https://i.imgur.com/RhgN9qs.gif

Movable Light Sources:

And finally, native C++ properties of movable light sources can be saved and restored without requiring ‘Save Game’ flags.
Only ‘Movable’ light sources are supported.

https://i.imgur.com/52gtwVx.png

Some notes to keep in mind with Savior v3:

  • Savior 3 can save and restore scalar public parameters, vector parameters, and public texture parameters of dynamic material instances on Actors’ meshes.

  • So “Save Actor” function automatically saves Dynamic Material Instances for Actor that implements the ‘Serializable’ interface.

  • And “Save World” function makes use of the Save Actor node, so the same rule from above applies when using this function.

  • Dynamic Material Instances does not require ‘Save Game’ check box on properties.

  • Check Epic’s documentation on dynamic material instances.

  • To save an Animation Instance, the Anim BP class must implement the ‘Serializable’ interface.

  • When serializing Animations, it’s not desirable to add a SGUID to Animation Instance if owning Actor already has a valid SGUID (it’s just not necessary).

  • Animation Properties to be saved require to be marked with the ‘Save Game’ check box, just like properties of regular Blueprints.

  • Light Component properties are only saved/loaded if the light source transform is set to ‘Movable’, dynamic lights.

  • None of Savior 3 features work for the ‘Minimal’ data set, only slots using ‘Complex’ data format (‘Compression’ setting on Slot class) support these new features.

2 Likes

. [HR][/HR][DEMO PROJECTS]:

Demo Project 4.18 don’t work with this error:

It’s a demo project.
The plugin is obviously NOT included.

Please remove second post or wrap it in a /code tag.
It pollutes the forums and makes the page hard to read.

1 Like

hey there [USER=“434”]BrUnO XaVIeR[/USER] , we’re just creating a SaveState/LoadState function on our game. Maybe we will be better off focusing on other things and getting your plugin, because frankly with all the projects i have to code right now and managing our artists and assets, time is really falling short on my behalf, and i have to start thinking that, even if i want to code everything by myself, i have other critical areas that i need to attend.

Will give it a try once it’s on the marketplace, will mostly use it for generating checkpoints in stages, i assume that’s supported.

Good job as always, always pleased to see your content. Experienced programmers are a joy to find.

1 Like

Thank you, this is already on Marketplace; but I can mail you a precompiled version if your team have to try it out first.

I don’t have files here, but if you pm me an email I forward to you when I’m back home.

1 Like

Have a compiled version .EXE to test???

No, thanks for removing the logs (too long post).

​​​​​Pm me an email and when I’m home I can send you a pre-compiled plugin for you to test and see if it fits your project (source code won’t be included).

Remember to note me which Unreal Engine version you use.

My UE is 4.19.2. What you email to request pre-compiled version to test???

My public email is bruno_xavier_(at)msn.com

I reply as soon I can.
I might not send it today because crunch time, but when I’m home I compile it and send file to you.

Hi Bruno;
I’m in the process of migrating to 4.19 so I’d like to use Savior2. How do we set up loading progress bar and such? If they are auto-generated, how can I adjust its style?

Plugin includes a custom HUD Class.
Reparent your HUD to this class and Loading Screen + Progress Bar will be auto generated.

You can customize visuals and widgets in default settings of a Savior 2 Slot object.
The shape of progress bar itself can’t be customized however, unless you know C++ Slate programming, because it is a Unreal Engine’s built-in object.
You customize its color, transparency, font type, etc.

In demo project you can see how splash screen is used and how media asset for a video-based loading screen is imported.
Video only work on packaged game and the media asset must point to a mpeg file within the game project folder.


Edit:
​​​​​​
If you need completely custom progress bar style, from the instanced Slot you can call “Get Save Progress” and “Get Load Progress” functions and feed your widget with the return value / 100.

Sorry, you lost me. You mean I should reparent my default Hud classs to your HUDSavior Class? Just like that? I did that but when I loaded a level I didn’t see any loading screen at all. I also created a slot asset from asset browser. At the moment I just want to see a loading screen and a loading icon, that’s all.

I think Savior2 should have separate documentation, I couldn’t find it.

Reparent HUD Class to HUD_SaviorUI.

On “Load Screen” section of the Slot asset, change the “Screen Mode” to “Splash Screen”.
Apply a texture asset to the “Splash-Screen” field on the same section.

https://forums.unrealengine.com/unreal-engine/marketplace/1467088-plugin-savior-2?p=1467090#post1467090

Then when you use “Save/Load Game World” and etc, you should see the texture as a splash screen.
If the splash screen image disappear too quickly, increase minimum time for “Load Screen Duration” option there on same Slot default settings section.