đșïž Savior Plugin Documentation
Savior is a C++ tool designed to extend Unreal's save system, providing a more powerful serialization framework for complex Unreal projects. Savior is a custom serialization system built from scratch with efficiency in mind, together with a focus in productivity and ease-of-use in Unreal. This documentation summarizes most common doubts of new users, most common mistakes, and the best solutions to achieve developer's goals.
Features
| Productivity |
|---|
| Savior eliminates micro-management of individual properties, becoming a valuable time saver for small teams. |
| Marking a property with Unreal's 'Save Game' exposes property to the save system, no mirror property required. |
| A rich library of helper functions brings free customization of the save process within blueprints, no coding. |
| Deleting or adding new blueprint properties will not corrupt existing save files; Contrary to other save systems. |
| Built-in versioning system helps patching live games, without causing players to lose existing progress. |
| Performance |
|---|
| Savior abuses Unreal's multi-threading capabilities. Saving data is absurdly fast, only limited by target hardware. |
| Blueprint properties are read directly from target, mirror property in slots not required, increasing performance. |
| Actor's location, rotation, scale, velocity, mesh, materials; Are all recorded from multi-threaded algorithms. |
| Utility |
|---|
| Savior is based on slots to persist data. |
| A full HUD system ships with the plugin, making easy to implement loading screens, slot selection screens. |
| Data loading progress is automatically calculated, generating feedback progress bars without developer efforts. |
Contents
Savior API
Installation
How to Setup a Slot
How to Save & Load
How to Setup Pickups
How to Setup Procedural Actors
Understanding SGUID
Tips & Tricks
Savior in C++
Specifications
Extras
FAQ
Quick Guides
Installation
Open the Epic Games Launcher and install the Savior plugin from Marketplace, or the FAB store. You must have a valid Epic games account to purchase any products from Unreal Marketplace.
How to Setup a Slot
Create a Slot Asset on Asset Browser (right-click), look for HKH >> New Slot menu;
You can also create a new slot at the root Content folder by opening the File main menu and clicking New Slot... under the [HKH] Savior sub-category.


When opening the Asset you can quickly adjust default Properties such as Default Player Name, Levels Thumbnails, etc:

How to Save Load
All you have to do is right click any graph on any of your Blueprints and search from one of main nodes in âSaviorâ 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:

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:

Manual Slot Instances Management
If you desire to perform custom Save/Load operations and not necessarily just fire a "Save Game World" to save everything, you can do so by building a process starting from the New Slot Instance Node. Example:

How to Setup Pickups
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:

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:

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:

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.
WARNING: If you overwrite the data existing in a slot file, the 'Destroyed' record will be erased as well. So, if your design involves persistently destroyed enties, you most likely want to LOAD a slot from file before saving again! This way your destroyed actors records will never be erased whenever your slot files are updated with new data.
How to Setup Procedural Actors
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.

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.
Understanding SGUID
There are three types of Actors in any Unreal Engine world:
- Actors you've placed in the Level by hand.
- Actors that are unique, but only exist at runtime.
- Actors that you spawn multiple instances of same class at runtime.
For each type of Actor above, you have to understand how Unreal Engine identifies these instances. When you place any amount of instantiated Actors in the Level, Unreal Editor automatically resolves instance ID, these IDs created are the same at runtime.
When you have a Game Mode that is spawned at runtime, and then spawns an instance of a Character, new IDs are created, but you usually treat these Actors as singleton Actors. That means, if Savior knows the class of your Game Mode, it doesn't have to care if that Character is Character_C_0 or Character_C_55.
It knows that it's the Player's Character. However when you spawn at runtime any amount of instances of any arbitrary class, the same process of resolving instance IDs is performed by the engine; and Savior cannot assume it knows which Actor is which, because every time the application launches, different IDs will be applied.
So, in order to identify Actors properly, Savior requires a SGUID property in the base class of the Actors you are spawning. Example of a SGUID value, a property of type Guid (or FGuid in C++):
1D371B88-46704C84-75D4E493-62CCF89A
Savior uses these structs, a composition of various integer values, to properly identify Actor instances, regardless of instance ID these Actors were given by the engine. Because Unreal Engine by default applies ID shuffling to Actors when you package a Shipping Build, having a SGUID value is very important for Savior to be sure it knows who is who when saving and loading data.
So, you have very simple choices to deal with this...
- Create a value for your SGUID property manually, taking pen note of who is who in your Level.
- Use Create Once Node for Actors you keep in a list.
- Use Make SGUID Node for Actors you spawn at runtime, but expect them to act as a Singleton entity.
Example:
This Player Character is spawned at runtime... Here its ID has a suffix " _C_0 ", but that can be changed by the engine.
So, to counter this inconvenience, I add to Blueprint a SGUID property and use in its Construction Script a Make SGUID node.
IMPORTANT:
Since Fortnite cheaters appeared, Epic Games is encrypting ID of some core actors, like the main playable character. But they only do this at runtime (shipping package), this is hardcoded into the Unreal Engine.
You wonât notice that until you package for shipping. In shipping mode Epic seem to add memory address encoded into the internal name of the actor⊠and that is going to change every time you launch the game (to difficult the work of memory scanners used by cheaters).
So, for a main character, I simply will NOT use the SGUID making nodes in constructorâŠ
I just leave it as a 0000-0000-0000 guid instead.
Tips n Tricks
One Template Class for multiple slot instances
- You only need 1 slot template asset, then you can just override the Slot File Name property, like in this example below:

Savior in C++
If you have native C++ classes you desire to implement Savior's API directly, follow these steps:
Build.cs:
You must add Savior3 module to your Build.cs list of dependencies >>
PublicDependencyModuleNames.AddRange(new string[]
{
"Core", "CoreUObject", "Engine", "InputCore", "Savior"
});
C++:
Your class definition have to include Savior hears >>
#include "Savior.h"
#include "SaviorMetaData.h"
Your class should implement one or both of Savior's event interfaces >>
UCLASS()
class MYGAME_API ALoot : public AActor, public ISAVIOR_Serializable, public ISAVIOR_Procedural
{
// ...
}
Override Interface functions >>
UFUNCTION() virtual void OnLoaded_Implementation(const FSlotMeta &MetaData) override;
Include and construct SGUID Property >>
UPROPERTY() FGuid SGUID;
AMyActor::AMyActor()
{
SGUID = USavior3::MakeActorGUID( this , EGuidGeneratorMode::ResolvedNameToGUID );
}
Full Example:
.H
#pragma once
#include "Savior3.h"
#include "SaviorMetaData.h"
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Loot.generated.h"
UCLASS()
class MYGAME_API ALoot : public AActor, public ISAVIOR_Serializable, public ISAVIOR_Procedural
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
ALoot();
UPROPERTY(EditDefaultsOnly, Category = Mesh)
class USkeletalMeshComponent* Mesh;
UPROPERTY(EditDefaultsOnly, Category = Mesh)
class USkeletalMeshComponent* Outline;
/** Returns MeshSK subobject **/
UFUNCTION(BlueprintCallable)
class USkeletalMeshComponent* GetSKMesh() const { return Mesh; }
//image to display in Inventory
UPROPERTY(EditAnywhere, Category = "Inventory")
class UTexture* InventoryImage;
UPROPERTY(EditAnywhere, Category = "Inventory")
FName ItemName;
UFUNCTION(BlueprintCallable)
class UTexture* GetImage() { if (InventoryImage != nullptr) return InventoryImage; else return nullptr; }
UFUNCTION(BlueprintCallable)
FName GetItemName() { return ItemName; }
UFUNCTION(BlueprintCallable)
void DecrementAmnt() { --Amnt; }
class UMaterialInstanceDynamic* MatOutline;
class UMaterialInstanceDynamic* MatMesh;
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
UFUNCTION(BlueprintCallable)
virtual void BeginView();
UFUNCTION(BlueprintCallable)
void EndView();
virtual void Equip();
virtual void UnEquip();
UFUNCTION()
void PickedUp();
UFUNCTION()
void Dropped(FVector DropLoc);
UFUNCTION(BlueprintImplementableEvent)
void DroppedBP();
//For Inventory/UI purposes. Determines where in inventory and how much space each takes up.
UPROPERTY(EditAnywhere)
int32 XPos;
UPROPERTY(EditAnywhere)
int32 YPos;
UPROPERTY(BlueprintReadWrite, Category = "Inventory")
int32 XFill;
UPROPERTY(BlueprintReadWrite, Category = "Inventory")
int32 YFill;
UPROPERTY(EditAnywhere)
int32 Rarity;
//for loading
UPROPERTY(SaveGame)
FGuid SGUID;
UPROPERTY(EditAnywhere, SaveGame)
bool bIsOwned = false;
UPROPERTY(EditAnywhere, SaveGame)
int32 HotBarIndex = 5; //0-4 index, 5 is not on hotbaar
UPROPERTY(EditAnywhere, SaveGame)
bool bIsEquipped = false;
UPROPERTY(EditAnywhere, SaveGame)
FIntPoint SavedPosition;
UFUNCTION()
virtual void OnLoaded_Implementation(const FSlotMeta &MetaData) override;
//logic for stackable items such as arrows/bombs/healing item
UPROPERTY(BlueprintReadWrite)
bool bIsStackable = false;
UPROPERTY(BlueprintReadOnly)
int32 Amnt = 1;
private:
float OutlineScale = .5f;
};
.CPP
#include "Loot.h"
#include "Engine/Texture.h"
#include "Materials/MaterialInstanceDynamic.h"
#include "Materials/MaterialInterface.h"
#include "Components/SkeletalMeshComponent.h"
// Sets default values
ALoot::ALoot()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
SGUID = USavior3::MakeActorGUID(this,EGuidGeneratorMode::ResolvedNameToGUID);
Mesh = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("Mesh"));
Mesh->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);
Mesh->SetCollisionResponseToAllChannels(ECollisionResponse::ECR_Block);
Mesh->SetCollisionResponseToChannel(ECollisionChannel::ECC_Pawn, ECollisionResponse::ECR_Ignore);
Mesh->SetSimulatePhysics(false);
SetRootComponent(Mesh);
Outline = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("Outline"));
Outline->SetCollisionEnabled(ECollisionEnabled::NoCollision);
Outline->SetupAttachment(Mesh, FName("None"));
InventoryImage = CreateDefaultSubobject<UTexture>(TEXT("Inventory Image"));
}
// Called when the game starts or when spawned
void ALoot::BeginPlay()
{
Super::BeginPlay();
Outline->SetMasterPoseComponent(Mesh);
MatOutline = UMaterialInstanceDynamic::Create(Outline->GetMaterial(0), this);
MatMesh = UMaterialInstanceDynamic::Create(Mesh->GetMaterial(0), this);
Outline->SetMaterial(0, MatOutline);
Mesh->SetMaterial(0, MatMesh);
EndView();
}
// Called every frame
void ALoot::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
void ALoot::BeginView()
{
MatOutline->SetScalarParameterValue(FName("Glow"), 500.0f);
MatOutline->SetScalarParameterValue(FName("MaskAmnt"), 1.0f);
if (Rarity == 1) MatOutline->SetVectorParameterValue(FName("Color"), FColor::Green);
if (Rarity == 2) MatOutline->SetVectorParameterValue(FName("Color"), FColor::Blue);
if (Rarity == 3) MatOutline->SetVectorParameterValue(FName("Color"), FColor::Purple);
if (Rarity == 4) MatOutline->SetVectorParameterValue(FName("Color"), FColor::Red);
if (Rarity == 5) MatOutline->SetVectorParameterValue(FName("Color"), FColor::Yellow);
}
void ALoot::EndView()
{
MatOutline->SetScalarParameterValue(FName("Glow"), 0.0f);
MatOutline->SetScalarParameterValue(FName("MaskAmnt"), 0.0f);
}
void ALoot::Equip()
{
bIsEquipped = true;
MatMesh->SetScalarParameterValue(FName("OffsetFOV"), 1.0f);
}
void ALoot::UnEquip()
{
bIsEquipped = false;
}
void ALoot::PickedUp()
{
bIsOwned = true;
Mesh->SetSimulatePhysics(false);
Mesh->SetCollisionEnabled(ECollisionEnabled::NoCollision);
Mesh->SetCollisionResponseToAllChannels(ECollisionResponse::ECR_Overlap);
Mesh->SetCastShadow(false);
}
void ALoot::Dropped(FVector DropLoc)
{
bIsOwned = false;
MatMesh->SetScalarParameterValue(FName("OffsetFOV"), 0.0f);
Mesh->SetSimulatePhysics(true);
Mesh->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);
Mesh->SetCollisionResponseToAllChannels(ECollisionResponse::ECR_Block);
Mesh->SetCollisionResponseToChannel(ECollisionChannel::ECC_Pawn, ECollisionResponse::ECR_Ignore);
Mesh->SetCastShadow(true);
EndView();
SetActorLocation(DropLoc, true, nullptr, ETeleportType::TeleportPhysics);
DroppedBP();
}
void ALoot::OnLoaded_Implementation(const FSlotMeta &MetaData)
{
//GetCharacterNameRenderer()->SetText(CharacterName);
LOG_SV(true, ESeverity::Warning,
FString::Printf(TEXT("OnLoaded() ==>> %s :: %s"),
*MetaData.SaveLocation,
*GetName()
)
);
if ( bIsOwned ) {
auto Player = GetWorld()->GetFirstPlayerController();
if (!Player) return;
// call event...
}
}
FAQs
How, why my Actor isn't saving?
Chances are you did not setup a SGUID Property properly.
Save World or Game Mode returns Failed result, why?
Check thread state with Get Thread Safety node. If you have another save process running, you have to wait until previous process is complete to start a new one.
I still can't save anything?! Make sure you are creating an instance with New Slot Instance node. Don't try to save data directly into your Slot Class.
Extras
Savior is one of few save systems in Unreal that supports saving object pointers. And it's the only that actually supports saving a chain of nested UObjects. This is perfect for complex inventory systems based on the UObject class.
In Unreal Engine 5, Savior has built-in support for recording and restoring states of Chaos Destruction System's fracturing and geometry collections (EXPERIMENTAL).
In Unreal Engine 5, Savior has partial built-in support for saving and loading the state of Mutable Characters and their parts (EXPERIMENTAL).
Module Specifications
Savior Core â C++ API
The following is technical documentation for the Savior.h header file from the Unreal Engine plugin Savior Auto-Save Plugin by Bruno Xavier Leite.
đŠ USaviorSettings â Plugin Configuration Settings
This class holds plugin-level configuration data, categorized under gameplay, performance, and object handling.
đ§© UPROPERTY Members
General Settings
int32 DefaultPlayerID: ID for the default player controller.int32 DefaultPlayerLevel: Local player's level (for progression-based games).FString DefaultPlayerName: Name or alias of the player.FString DefaultChapter: Current chapter of the game/story.FString DefaultLocation: Name of the map or level being saved.
Performance
bool RespawnDynamicActors: Enable auto-respawn of missing actors.bool RespawnDynamicComponents: Enable auto-respawn of missing components.bool AccurateDynamicRespawnChecks: Ensures accurate respawn, potentially impacting performance.
Reflector Scope
TSet<TSubclassOf<UObject>> InstanceScope: Auto-instantiation classes.TSet<TSubclassOf<UObject>> RespawnScope: Auto-respawn target classes.
đŸ USavior â Core Save/Load Slot Object
This class provides a runtime object that handles saving and loading of game state data.
đ§© UPROPERTY Members
Configuration
Debug,DeepLogs,RuntimeModeâ Control debug output and threading behavior.ObjectScope,ComponentScope,ActorScopeâ Define serialization targets.
Load Screen
- Includes customizable fields like
LoadScreenMode,SplashImage,FeedbackSAVE,BackBlurPower, etc.
UI/UX
SlotFileName,SlotThumbnail,LevelThumbnailsâ Control UI visuals and file metadata.
Events
- Bindable multicast delegates such as
EVENT_OnBeginDataSAVE,EVENT_OnFinishDataLOAD, etc.
Misc
- Runtime-related fields:
WriteMetaOnSave,IgnorePawnTransformOnLoad,SlotMeta,SlotData,World
đ ïž UFUNCTION Methods Overview
1. Core Slot File I/O
WriteSlotToFile,ReadSlotFromFile,DeleteSlotFile,FindSlotFileSaveSlotMetaData,LoadSlotMetaDataGetSlotMetaData()
2. Object/Component/Actor Save/Load
- Save:
SaveObject,SaveActor,SaveComponent, etc. - Load:
LoadObject,LoadActor,LoadComponent, etc. - Hierarchical:
SaveObjectHierarchy,LoadActorHierarchy, etc.
3. Game Scope Save/Load
SaveGameWorld,LoadGameWorldSaveGameMode,LoadGameModeSaveGameInstance,LoadGameInstanceSavePlayerState,LoadPlayerState
4. Level and Data Layer Serialization
SaveLevel,LoadLevelSaveWorldLayers,LoadWorldLayersSaveGameFeatures,LoadGameFeatures
5. Low-Level Record Management
GenerateRecord_*,UnpackRecord_*FindRecordByName,FindRecordByGUIDAppendDataRecords,InsertDataRecord,RemoveDataRecordByName, etc.
6. GUID and ID Utilities
MakeObjectGUID,CreateSGUID,MatchesGUID,MarkActorAutoDestroyed, etc.- Check/Generate/Query SGUIDs
7. UI/UX Getters and Setters
SetChapter,SetProgress,SetPlayerName,GetSaveTimeISO, etc.
8. Utility + Meta Methods
NewSlotInstance,GetClassDefaultObject,ShadowCopySlotGetSaveProgress,GetLoadWorkload, etc.
â Summary
The USavior class exposes a highly granular and flexible API to Unreal Engineâs Blueprint system, empowering developers to implement robust save/load functionality, auto-respawn logic, UI/UX enhancements, and system configurationâentirely through C++ or Blueprints.
Savior API
Asynchronous Methods:
- Load Game Instance (Async)
- Load Game Instance [+Callbacks]
- Load Game Mode (Async)
- Load Game Mode [+Callbacks]
- Load Game World (Async)
- Load Game World [+Callbacks]
- Load Level (Async)
- Load Level [+Callbacks]
- Open Level (+HUD)
- Open Level (+HUD) [+Callback]
- Save Game Instance (Async)
- Save Game Instance [+Callbacks]
- Save Game Mode (Async)
- Save Game Mode [+Callbacks]
- Save Game World (Async)
- Save Game World [+Callbacks]
- Save Level (Async)
- Save Level [+Callbacks]
Serializable Interface:
- Event: On Loaded
- Event: On Marked (Auto-Destroy)
- Event: On Prepare To Load
- Event: On Prepare To Save
- Event: On Saved
Procedural Interface:
HUD Custom Class:
- Event: On Begin Load-Screen
- Event: On Finish Load-Screen
- Invoke Load Screen (Blur)
- Invoke Load Screen (Splash)
- Remove Load Screen
- Hide Slots UI
- Show Slots UI
Slot Methods:
- Get Chapter
- Get Object of Class
- Get Play Time
- Get Player Level
- Get Player Name
- Get Progress
- Get Save Date
- Get Save Location
- New Object GUID
- New Object Instance
- New Object Instance
- Set Chapter
- Set Play Time
- Set Player Level
- Set Player Name
- Set Progress
- Set Save Date
- Set Save Location
- Calculate Load Workload
- Calculate Save Workload
- Create Once : SGUID
- Delete Slot's File (.SAV)
- Find Actor With GUID
- Find Slot's File (.SAV)
- Get Load Progress
- Get Loads Done
- Get Save Progress
- Get Save-Date ISO
- Get Save-Time ISO
- Get Saves Done
- Get Slot Data
- Get Slot Meta-Data
- Get Slot Thumbnail
- Get Thread Safety
- Is Actor Marked (Auto-Destroy)
- Is Component Marked (Auto-Destroy)
- Is Object Marked (Auto-Destroy)
- Load Actor
- Load Actor : (Slot Data)
- Load Actor : (Static)
- Load Actor Hierarchy
- Load Actor Hierarchy by GUID
- Load Actor by GUID
- Load Actors of Class
- Load Animation
- Load Component
- Load Component : (Slot Data)
- Load Component : (Static)
- Load Component by GUID
- Load Dynamic Materials (Actor)
- Load GI Singleton
- Load Game Instance
- Load Game Mode
- Load Game World
- Load Level
- Load Object
- Load Object : (Slot Data)
- Load Object : (Static)
- Load Object Hierarchy
- Load Objects of Class
- Load Slot Meta-Data (.SAV)
- Mark Actor (Auto-Destroy)
- Mark Component (Auto-Destroy)
- Mark Object (Auto-Destroy)
- Matches : SGUID
- New Slot Instance
- Read Slot from File (.SAV)
- Save Actor
- Save Actor Hierarchy
- Save Actors of Class
- Save Animation
- Save Component
- Save Dynamic Materials (Actor)
- Save GI Singleton
- Save Game Instance
- Save Game Mode
- Save Game World
- Save Level
- Save Object
- Save Object Hierarchy
- Save Objects of Class
- Save Slot Meta-Data (.SAV)
- Set Default Chapter
- Set Default Player ID
- Set Default Player Level
- Set Default Player Name
- Set Default Save Location
- Write Slot to File (.SAV)
