[PLUGIN] Savior

Yes, the old plugin design is no longer used. There’s no template nor savior actor to be placed in maps anymore.

If your game design isn’t too complicated, “Save World” and “Load World” should be enough to save and load everything.
The “Save Game Mode” node is used when you just want to save Game Mode blueprints without care in which Map the game was saved in. With “Load Game Mode” you can load all Game Mode data without replacing current Level, like open world games do.

You aren’t missing anything. I make the plugin skip static meshes data…
Because otherwise Unreal Engine goes kaboom!

You can however map those meshes to a list of SoftReference | Bool map.
Whatever Ref in the map set to true would activate the static mesh component you need making it visible/loaded, and the plugin can auto save those Map properties just fine.

Submitted v2.8.1 for Unreal 4.22:

  • Refactored all the several (Async) nodes, aiming for an algorithm to prevent the bug where Success/Fail events (flow wires) wouldn’t execute anymore until Editor restarted if the save/load async process was interrupted (quit gameplay before finished save/load).

I have a question regarding :

Are “Class Reference”, “Soft Object Reference” and “Soft Class Reference” all considered being references? (I know they have reference in their name but you never know :slight_smile: )

“Soft” references are Structs with a String inside.
They are “value variables”. Can be saved in any way, inside Structs, in Arrays, etc.

“Class Reference” or “Object Reference” is a pointer to an object.
The plugin only restore those pointers if the referenced object exists by the time of loading the game from file.
“Auto Respawn” options in Plugin Settings will auto spawn any instance of a class if the lost pointer to the instance is from a class you have white-listed there and then it will restore the reference variables pointing to that instance of your object. It can do this for variables of references within any class (variables marked Save Game), within Sets, within Arrays, within Maps, within Objects.

However you should only white-list for auto-respawn, in plugin settings panel in Unreal Editor, classes that you create as direct children of the *UObject *class or children of *UAutoInstanced *class.
Why? Because people previously were adding there to the auto respawn list internal engine classes and then complaining about game crashing when the plugin spawns a instance of something it shouldn’t spawn.

Maps expect to be a TMap< FName , YourObjectReference > or TMap< YourObjectReference , anything >, if the Map key type isn’t either an Object Reference or a FName the plugin will complain in your logs saying it doesn’t know what you’re trying to do…

Those TMaps< YourObjectReference >,* TArray< YourObjectReference >*, *TSet< YourObjectReference *> and plain YourObjectReferencevariables work just fine when the variable is stored inside your Blueprints.
IF they are stored inside a Struct (then the Struct used in the Blueprints) however, you should see an error log telling you why the plugin won’t save those references for you. Epic have set in deep engine code an intentional crash if the plugin goes there to save references that aren’t inside a UClass, so the plugin will give up on references (not Soft ones) that are member of a Struct to avoid crashing your game, it can see the references, it just skips them :]

All other normal types like Int, Float, String, etc, they are common “value types” so they are pretty much universal, the plugin can see and restore their values in Structs or Objects, anywhere.

I have a problem, When I Save a Transform Value , Savior2 can save json into it, but load failed , I debug this UnpackRecord_Object method ,
const bool IsStruct = Property->IsA(UStructProperty::StaticClass()) is return false , But FTransform is Struct , Should be True is right . I am not understand

A FTransform is stored differently depending on the platform you’re building to. EpicGames engineer explained to me why it shouldn’t be used on save systems (it was preventing multi-platform packaging) due to compression issues…
So I removed all support for FTransform struct, there’s is no unpacking method for FTransform in plugin code.

Can you have a temporary save without it writing to a file? For instance I want to save the progress of a player while they are loading levels but only want to actually save the game to a file when they save at a check point

Yes. You can create a new Slot instance in your Game Instance and use “Save Object”, “Save Component”, “Save Actor”, and “Save Actor Hierarchy” nodes.

All those nodes mentioned above only write data to the Slot object instance, but they do not write to files, until you call manually “Write To File” node.
Save Game Mode”, “Save Game Instance”, and “Save Game World” automatically calls the “Write To File” function.
I particularly never use those that automatically write save files, I use Slot objects as runtime storage for a lot of things…

New deserializer method for you, in v2.8.3 for Unreal 4.22+.
Load an actor from slot by its “SGUID” property instead of searching for nameID:

Useful for actors you spawn frequently and actor’s nameID keeps changing ( Character_C_1, Character_C_2, Character_C_14, etc… )

You can find more info about the “SGUID” property here:
https://forums.unrealengine.com/unreal-engine/marketplace/1467088-plugin-savior-2?p=1467094#post1467094
[HR][/HR]
Keep in mid that YOU are responsible for the validity of the SGUID property to use this.
You will have to keep a valid Guid struct for your actor of interest and making sure that nothing in your game code ever compromise the constant value of that Guid.

Any chance we can get an interface function that is called before an actor / component / object is saved? For example i want to pull gameplay attributes out of the ability system component before it saves but right now i would have to do all that manually when i call save actor or whatever. it would be nice to have an interface function that i can add to a component / actor to get the data ready to be saved if needed.

Please explain what you mean with “get the data ready to be saved”, that is open to interpretations.

i have an array of a custom struct that will store all the attributes i want to save. This is not updated at automatically and instead i have to manually extract the attributes from the ability system and store them in my custom struct array. I need to do this before the component is saved so it saves the correct data. Right now i’m having to call the saving of the struct manually before i save the actor. It would be nice if its self contained inside the component so all i need to do is call my populate struct function from inside the interface function. Think of it as a OnBeginSave()

There’s a “OnPrepareToSave()” function in C++, I thought I had an Interface call there for Blueprints.
If there isn’t any then it’s an oversight.

Anyway, it’s one line of code needed.
I will look in source code tomorrow.

Added these events to v2.8.4 and sent source files to Epic for review:

Also included “Load Actor Hierarchy by GUID” function, some devs are using this to save inventory systems:
(it loads an actor + all its components + any attached actors and their components)

Submitted a tiny update with a fix in code for the “Load Actor Hierarchy by GUID” function.
The function would return a “Failed” result if any of the components in the hierarchy doesn’t have a *SGuid *property in place instead of ignoring that component.

Hey Bruno,

ive bought your plugin and have some problems.

  1. I want to save the map if im leaving it and if im return into the map, i want to load that.
    But at first i created a test in a single map.

[SPOILER]

https://forums.unrealengine.com/filedata/fetch?filedataid=170920&type=thumb

[/SPOILER]

This is the test setup.
And most times it failed, only if i restart the engine, it will save and load with success. But after at few time it failed again.

Here is a video for this issuse:

  1. How about the Slots, will the plugin saves all data into one slot or needs it more slots? One Slot for each map ?
    I have to create a new instance slot for the save, should i create always a new one or only once?

I really dont know.

  1. I always have to mark the variables i want to save with the save tag if im saving the level? Or its only if im saving a single actor?

Sorry for this questions, but quite difficult for me.

Greez

Do not assign the result from “New Slot Instance” to the reference of your slot asset.
Just use the node when needed. Or you can just use “Save/Load Game Mode” nodes to save data from all your game mode blueprints.

“Save/Load Level” is for streamed sub-levels, do not use those functions to save the current persistent level.
Use “Save/Load World” or the “Save/Load Game Mode” ones, you don’t have to create new slot instances to use those nodes.

Yes you can have only one slot to save your data or many per level.
Most devs create a fixed list, 10 slots, where player can pick one to save.

“SaveGame” tag is necessary for any plugin function, if no tag then property will never save.

Okay thanks for the help! I will try it next time.

But if i should use the save game mode node, than my game mode blueprint will be saved.
So i have to set all variables from all actors as mirrored variables into the game mode blueprint to save all actors?

Then its the same as the game instance, there i also have to mirror all variables from all actors that i want to save.

And if i load the game mode, than my current persistent level will be loaded too?
So i have to load the game mode after every map transfer? Or how i can set my saved level?

No, Save Game Mode only record blueprint members of Game Mode.
If you want to save entire level use Save World instead.

Thanks for your patience!

I updated my functions, but it works only if restart the editor and than only a few times and than it fails all the time.

I first create the instance with the T Key.
Than i save with U and than load with R.

If i create something wrong, could you show me a working setup?

Its really odd that my setup work only a few times.