Need Help: Custom Save Game System

I tried creating a custom save game system.
Created a structure class, holding the following structure, with game data.

UCLASS()
class MY_API UCndSysSave_GD : public USaveGame

	GENERATED_BODY()

public:

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "GameSystems||Save||Developer||Structures||GD")
FCndSaveSys_GameData GD;

This is my save system.

UCLASS()
class MY_API UCndSysSave_Sys : public USaveGame

Here’s what happens when my own GameInstance is initialized.

void UCndGameInstance::BPF_Init()
{
    // Load Game Data Synchronous
    CndSys_Save->BPF_GD_SaveLoad(GD_Load, false, CndGD_SlotName, CndGD_User_Index, GD_All);

}

Here’s the function that acts as both save and load.

void UCndSysSave_Sys::BPF_GD_SaveLoad()
{

if (SaveLoadType == GD_Load)
    {

        if (DoesSaveExists(SlotName, UserIndex))
        {
        }
        else // Save Does Not Exists
        {

            BPF_GD_CreateNew();

        }

    }

}

But executing this line inside BPF_GD_CreateNew causes the engine to crash.

void UCndSysSave_Sys::BPF_GD_CreateNew()
{
Cnd_SavedGD = Cast<UCndSysSave_GD>(UGameplayStatics::CreateSaveGameObject(UCndSysSave_GD::StaticClass()));
}

I tried everything, but it always keeps crashing. What am I doing wrong?

Can you show crash log ?

Why does the save system extend USaveGame ? Does itself need to be saved ?
If I get this right, it should probably be some kind of function library, or a singleton such as a GameInstance Subsystem.

Where does CndSys_Save come from ? Are you sure it’s not null ?

I might’ve been stupid, but I think I solved this somehow…
FYI: I tried creating the save system to be both Sync and ASync, and to be quite easy to use, and accessible as possible.

UCndSys_Save - is a save system object.
UCndSysSave_GD - is data structure class containing all player data.

The issue with creating the save object, which resulted in crash, during initialization was… that the game data structure class (Cnd_SaveObject_GD) was called from the inside of the save system, not from my CndGameInstance when I tried using this:

Cast<UCndSysSave_GD>(UGameplayStatics::CreateSaveGameObject(UCndSysSave_GD::StaticClass()));

To solve this, I added my data struct class to this function as a parameter:

CndSys_Save_Data.h

void BPF_GD_SaveLoad(UCndSysSave_GD* GameData, ECndSysSave_GD_SaveLoadType SaveLoadType, bool ASync, FString SlotName, int32 UserIndex,
	ECndSysSave_GD_SaveLoadIndividual GD_IndividualType, TArray<TEnumAsByte<ECndSysSave_GD_Type>> Array_GD_Type);

And this fixed the crash during engine initialization, when CndGameInstance called the save system.

CndGameInstance.h

void UCndGameInstance::BPF_Init()
{

    // If save type is set to GD_Individual, save certain data only
    CndArray_GD_Type.Empty();

    // Load Game Data Synchronous
    CndSys_Save->BPF_GD_SaveLoad(CndSaveData, GD_Load, false, CndGD_SlotName, CndGD_User_Index, GD_All, CndArray_GD_Type);

}
CndSysSave_Data.cpp

void UCndSysSave_Sys::BPF_GD_SaveLoad(UCndSysSave_GD* GameData, ECndSysSave_GD_SaveLoadType SaveLoadType, bool ASync, FString SlotName, int32 UserIndex,
    ECndSysSave_GD_SaveLoadIndividual GD_IndividualType, TArray<TEnumAsByte<ECndSysSave_GD_Type>> Array_GD_Type)
{

if (SaveLoadType == GD_Load)
    {

        if (DoesSaveExists(SlotName, UserIndex))
        {

            if (ASync)
            {

                // Broadcast event once data is being loaded via ASync
                OnGD_LoadStart.Broadcast();

                DEL_CndGD_ASyncLoad.BindLambda(
                    [this, GameData, GD_IndividualType, Array_GD_Type](const FString& SlotName, const int32 UserIndex, USaveGame* LoadedGame)
                    {
                        if (LoadedGame)
                        {
                            // Cnd_SaveInstance = Cast<UCndSysSave_Sys>(LoadedGame);
                            BPF_PTR_GD_SaveLoad(GameData, GD_Load, true, SlotName, UserIndex, GD_IndividualType, Array_GD_Type); // Update game state - ASync

                        }
                        else
                        {
                            UE_LOG(LogTemp, Error, TEXT("CND_DEBUG: SaveSys - Failed to load data asynchronously from slot: %s"), *SlotName);
                        }
                    }
                );

                

            }
            else // if ASync is not true
            {

                BPF_PTR_GD_SaveLoad(GameData, GD_Load, false, SlotName, UserIndex, GD_IndividualType, Array_GD_Type); // Update game state - Sync

            }

        }
        else // Save Does Not Exists
        {

            BPF_GD_CreateNew(GameData);

        }

    }

}


void UCndSysSave_Sys::BPF_GD_CreateNew(UCndSysSave_GD* GameData)
{

    UE_LOG(LogTemp, Log, TEXT("CND_DEBUG - SAVE SYS (GD): Creating new save game object."));

    // Create new save game object
    GameData = Cast<UCndSysSave_GD>(UGameplayStatics::CreateSaveGameObject(UCndSysSave_GD::StaticClass()));

}