Warpers – Unreal Saving and Loading

SaveSystems

I’m currently taking the course Big Game Project at Uppsala University – Campus Gotland, where the goal is to have, after 10 weeks, a working vertical slice of a game which might have the potential to become a product worth selling at a later stage.


We’re now one week from exhibiting Warpers at the Gotland Game Conferance weeks into the production of the game Warpers and this time I’ll write a little about how we save and load custom spaceships. Warpers is a game where the core focus is aimed at players creating their own space ships and using them to traverse the different galaxies through the universe.

We use Unreal Engine 4’s save-game system which makes it easy to save all the kinds of data that we want to preserve between sessions.

There are a number of moments where the ships need to be loaded and saved. After a player have created a ship design that they’re happy with they probably want to try to fly that ship. As such, before the player leaves the ship editor the design gets saved and loaded again when the player leaves the hangar where the ship was built.

How all this is done in code is quite a simple process which I’ll go through in this weeks’ post.

First you need to define what data you want to have saved. This is done by inheriting from the class USaveGame. This class doesn’t contain any code and only acts as a base-class for all save games because all the functions which allow for saving and loading all take a UsaveGame as input.

UCLASS()
class MSSP_API USaveDataShip : public USaveGame
{
    GENERATED_BODY()
	
public:

    UPROPERTY(VisibleAnywhere, Category = Data)
    FString m_version;

    UPROPERTY(VisibleAnywhere, Category = Data)
    FString m_name;

    UPROPERTY(VisibleAnywhere, Category = Data)
    TArray m_moduleTypes;

    UPROPERTY(VisibleAnywhere, Category = Data)
    TArray m_moduleLocations;

    UPROPERTY(VisibleAnywhere, Category = Data)
    TArray m_moduleRotations;

    UPROPERTY(VisibleAnywhere, Category = Data)
    TArray m_wallData;

    UPROPERTY(VisibleAnywhere, Category = Data)
    TArray m_hullData;
};

The code above demonstrates roughly how the data for ships in Warpers is saved. The code up until the first public flag is a general Unreal Engine 4 class definition which specifies which class to inherit from as well as which package the code is considered to be part of. In this case the package is MSSP_API which only is a development name for Warpers.

All the variables marked with the UPROPERTY() macro is what gets saved to disk when a save is performed. Here the string m_version is a safeguard to prevent players from loading a ship where the data layout is different from the one that the game expects and which would result in a crash otherwise. The m_name only keeps track of the name of the ship in-case someone renames the save file, we don’t want the original ship name to be lost. The next three member variables: m_moduleTypes, m_moduleLocations and m_moduleRotations are quite self-explanatory, but they stores the locations, rotations and what types of parts that the ship consist of in forms of arrays of whichever data structure that is needed to describe the parts info.

The two final variables are for saving the walls and hull parts because they need further information than what regular parts have and that’s how the data is structured when saving spaceships. The process of saving and loading is ridiculously simple and I’ll demonstrate that next.

There are three steps when you want to save or load something within Unreal Engine 4. First you need to create the save object, this is done by this simple code.

USaveDataShip saveData 
    = Cast(UGameplayStatics::CreateSaveGameObject(USaveDataShip::StaticClass()));

Next you fill the object with the data that you want like any other object.

saveData.m_name = "Star Destroyer";

Finally you might want to save and load your data, both are quite similar to do and only requires a function call each.

When you want to save:

UGameplayStatics::SaveGameToSlot(saveData, saveData->m_name, 0);

The first paramenter is the save object that you want to save, second is the file name and the third is something which is called a user index. The user index is required by some platforms and I haven’t quite wrapped my head around what it’s purpose is but I set it to 0 and it seems to work fine on windows at least.

When you want to load:

saveData 
    = Cast(UGameplayStatics::LoadGameFromSlot(saveData->m_name, 0));

The parameters on the load function are the same as the previous save-function except that it doesn’t take the save object as the first argument, but rather returns the loaded save object filled with the previously saved data.

So that’s it, there isn’t any real complexity to saving in Unreal Engine 4 and now you know how we save all space ships in Warpers!

~Lead Designer and Programmer, Per “Gimmic” Johansson

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s