[PLUGIN] Savior

Can you tell me if I’m doing anything wrong with this setup then? Because I think I followed the directions.

As I said, the plugin doesn’t re-possess anything that is unpossessed.

You have to make your own code for that.

And, for Game Mode member classes, that are spawned at runtime, but are always treated like singleton classes… Use Make SGUID node in Static Name to GUID instead of Create Once Node.

This, use the last one in construction script for your classes member of Game Mode group:

My problem was that I was setting the save slot in the game instance and then attempting to reload the level. Once the level reloaded, the game mode itself then attempted to run load game mode. Instead, I’m not reloading the level at all. I’m now loading the game mode the moment I click the load button in the widget. That seemed to work. My character is now possessed.

Slot Instances are often garbage collected (which is a good thing).

They are killed as garbage because the parent (the owner/outer) of that instance is the instance of the blueprint whoever used New Slot Instance node.

The slot instance becomes a temporary sub-object of the blueprint that created it…
If you execute a Open Level action then most likely that blueprint will be destroyed and the instance of your slot is killed with it’s parent actor/object that was a member of that previous level loaded.

I still have one issue where none of the game mode variables are updated when I load with the Load Game Mode node. I put some info in a summary block below!

Summary

And here’s the variable:
image

I was able to replicate the above issue in the demo. So unless I’m doing something terribly wrong, I don’t think the game mode variables ever actually get reloaded from the save slot.

I replicated this in the demo by adding one actor to the test pointers array on the GM_Demo object and then saving. So there should be one actor in the array. Then before loading, I add one more actor to the array so that there are now two. Then I load the game mode and print the actors, but there are still two actors when there should only be one from the save slot. :frowning:

Load Game Mode will not reset state of objects or open levels like Load World does. But those variables should load if they saved to the file.

On slot class you can enable debug logs that will print to output panel what have been saved and loaded by the nodes.

I have just tested a Save Game Mode in demo project and all GM variables loaded for me.

A couple of questions:

  1. Does this support consoles?
  2. Can it create an arbitrary number of save states (i.e. give the player a “Create New Save State” option or is it limited to the save states defined in the editor?
  3. Is it possible to “author” save states, i.e. preparing a specific world state for QA / cert?
  4. Does it come with “progress” tracking? To elaborate, we use gameplay tags to track completed objectives / quests etc. and we like this workflow (AddProgressTag / HasProgressTag). How does the workflow for something like this look like with Savior?
  5. How does the size scale with the number of modified objects? Say I want to keep track of every single change the player makes to the game world Skyrim style. Would I be looking at 1GB+ save states eventually?

This is what I get from output logs after I added a SGUID to my GM_Demo blueprint and save/load:


Actor pointers have been loaded successfully because my SGUID value is correctly the same SGuid that stored in the save file.

1 Like

Okay, I did not add a SGUID to the GM_Demo, so maybe that was the problem.

EDIT: That worked, at least in the demo. I’ll add it to my project! Thank you

1 Like

The confusion you were facing was because I have added in recent release a

TAG_ANOGUID(…)

check that skips loading data for every actor that doesn’t own a SGUID property whilst also does not implement a !Guid actor tag to tell the plugin “this actor does not care about SGuid values, just load it!

The plugin was ignoring Game Mode because in demo it was lacking both and the demo is older than latest plugin release (sorry!)

This plugin have been implemented into several PlayStation titles;
But none have shared implementation code with me, because obvious Sony reasons.

You have to either pre-allocate slot classes in editor, or keep a “slot ID” variable in your single slot class to determine in which “player profile” a player is saving to.
Non coders find it easier to simply create new slot base classes in editor.

You can add and remove “records” to slots at runtime from c++ or blueprints for automated testing.
Some devs use automated testing frameworks for that, I do not have the details of how they do it.

SaviorMetaData.h is a very simple header file where many determine custom progression properties that are independent of bulk save files (they can loaded without loading a save file from this).
Then they modify / include Getters into the Savior3.h header to support their custom gameplay tags that can be displayed to player UI without performing any heavy slot data loading.

You can use plugin API to only save what you need or use Scope filters to determine the reach of the Save World node.
In Slot Scopes you can set the classes that you want to include into save files, by default anything child of AActor or UActorComponent is accepted by the Slot Scope.

Thanks for the info! Will definitely evaluate this for our next thingy.

How can I save an exponential height fog on my persistent level? I change it’s values based on where the player is.
For example I have like 3 heightfogs, each with their own settings, for things like bright morning, cave etc, but I have each of them hidden. And when the player walks into an new area, I copy the values from the appropriate height fog over to the persistent height fog.

I tried putting a reference to my persistent height fog on the game mode, but it wasn’t updated when I loaded. I tried adding it’s class to the object scope in the save slot too.

Looking at the logs, it’s not serialized… maybe if I create a new exponential height fog blueprint that extends the base one, I can add the SGUID onto it?

EDIT: That is not possible, Exponential Height Fog cannot be extended from blueprints

You can create mirror variables in your player blueprint and mark them ‘Save Game’ to save.

Then from player’s On Loaded event you can find the target and apply the variables loaded from file.

They can’t be saved directly as there are no ‘Save Game’ properties on them by default.

There’s a lot of Unreal devs that today consider Game Instance a part of the Game Mode group, or at least work that way, joining them while building a project.

So to avoid the need some feel to call multiple nodes and end up fighting against lifecycle of a save thread, I will in a future update add this option to the Save Game Mode and Load Game Mode nodes:

Save/Load GM with Game Instance

SAV_GM_GI

This way when you launch a background task you can save both without launching yet another thread just to save a Game Instance blueprint.

1 Like

Sorry another question.
My player character uses the femaleBP that I’ve created. The skeletal mesh has a ton of morph targets that I have to allow the user to customize the character. These same morph targets are used to set the appearance of NPC female characters. Given that, what SGUID should I use for this femaleBP since it’s used by both the player and NPC characters?

@roundpitt When I use a Character BP as a player that is the same class of other Characters, I do a check on BeginPlay.

If “Self” BP == Player Character: Invalidate my SGuid.

So my playable character’s Guid is always 0000-0000-0000.


I think this is done in demo project’s characters as well.

1 Like

I’m kind pretty fresh with UE4 and I’m having trouble figuring out how to set this up with level streaming. Can I still use the Save Game World node to get a broad save of anything flagged in the level? Is there a way I can make this work with sublevels?