Proper way to save various game settings?

Hi. I am using blueprints to make my game. Its a racing game and I’ve come to a point where I need to make game settings.
I’ve seen some tutorials, but they use different methods to save the game settings.
I would like to ask about what is the proper way to store and load various settings.

I need to save:
Graphics settings (various console commands, resolution, fullscreen mode etc.)
Sound settings (not even sure how to do this propertly)
Controls
Game settings (UI appearance, vehicle options, like lights and stuff)

Do I make a specific save game slot for every of these, or do I use “Save Game Settings” node. What is the difference between using these methods?

Thanks to anyone who can give a little insight on how this stuff works in UE4.

Some settings are saved by the engine when you use the Game User Settings nodes for setting things like overall quality settings and resolution, but this is really just for graphics settings. Some graphics settings have to be applied through console commands via the Execute Console Command node, and other non-graphics settings are almost completely inaccessible to Blueprints at the moment. Additionally, settings that are more specific to one game for gameplay reasons (stuff like show all ally players as one color and all enemy players as another) require a custom method for saving and loading.

Luckily, we have just such a thing: the SaveGame class! While the name implies it’s used to specifically save the game, it can be used to save nearly anything you’d like to a binary file that can be loaded later on. You can either have one catch-all save file for all your game settings, or divide them up into multiple SaveGame classes for more organization. For this example I’m just going to do one save for all the settings to give you a general idea. I’m also going to assume you’re doing this via Blueprints, but it can similarly be done in C++ if needed.

So, start off by creating a new Blueprint based on the SaveGame class. I’m going to call mine BP_SettingsSave. Now when you open this, all you have to do is add variables for each setting you want to save, no node work required. If using a single save for all of your settings, I recommend categorizing your variables by type. I usually do Graphics / Audio / Input / Gameplay. While you’re here, you should go ahead and set default values for these variables for when the save file can’t be loaded (either due to an error or fresh game install with no saved settings).

Once you have these setup, you’re done inside the SettingsSave class. Up next, we’ll add saving and loading functionality. This is best to be done in your GameInstance for your game since the GameInstance is created at launch, persists through the entirety of your game, and doesn’t go away until the game shuts down. This makes it an ideal place to handle saving and loading game settings since just about anywhere you can use a GetGameInstance node to access the settings. If you don’t already have a GameInstance class for your project, go ahead and make one. I’m going to call mine BP_CustomGameInstance.

Inside this class, create a new variable (mine is just named Settings) will hold an object reference of the settings save class you just made. For my example, this will be the BP_SettingsSave from the previous step. Then create a string variable that will hold the slot name of the settings save. I named mine SettingsSlot and set the value to “Settings”. This will be used to save and load the settings from a file in the Project/Saved/SaveGames folder.

Next, create a function and name it something like LoadSettings. This function will only load the saved settings, not apply them. Inside this function, add a Load Game from Slot node and link the slot name variable into the Slot Name input. Then take the output, which is a basic SaveGame object, and cast it to our Settings SaveGame. In my case, I cast to BP_SettingsSave. For the successful execution pin, we set the Settings variable to the As SettingsSave output. On the Failed pin, add a Save Game to Slot, which we use to write the current default values stored in Settings to the settings save file. I added an additional check after that to print a string to screen if that fails. Here’s what your LoadSettings should look like now:

Up next, we create our SaveSettings function. This one is even simpler: all we need to do is use a Save Game to Slot node on our Settings save variable and enter our slot name. You can add an extra check using the bool output to print a message if it fails, but it hopefully won’t. Here’s the final setup for this function:

The last thing you need to do in the custom GameInstance class is actually trigger the load on startup and save on shutdown. For that, we head to the Event Graph and add the Event Init and connect it to a LoadSettings node, then add the Event Shutdown node and connect it to a SaveSettings node. This is what the setup should look like:

230603-load-and-save-settings.png

We’re now done with saving and loading! The final part we need to cover is how to access and modify these values from anywhere. This can be done by using a Get Game Instance node, casting it to your custom Game Instance, and then accessing the Settings variable to either set or get the values in it. Here’s an example of how to set one of the values:

And how to get a game setting:

You may be wondering why I had you create the save and load functions instead of just building them directly in the event graph. I did it this way so you can save and load the settings anywhere you can access the game instance. For example, say you have an apply button in your settings menu. You wouldn’t want to wait to save the new settings until shutdown in case you crash, so instead you can now call your SaveSettings function anywhere you can use Get Game Instance, such as when you click Apply in the settings menu.

That should be all you need to get saving and loading set up. Actually applying the settings is more dependent on what settings you’re trying to apply and if I went into more detail on it this post would be way too long (some settings are handled by GameUserSettings, some can only be done via console commands, and some require custom C++ to access right now). Basically the general idea for how to apply game settings would be add another function to your game instance called ApplySettings where you handle applying the settings from your Settings save variable. Then you just call this after your initial LoadSettings call in the event graph, as well as after you change settings in your settings menu.

I hope this helps you! Let me know if you need any more help on this.

5 Likes

Thank you for this comprehensive guide. Worked like a charm.

Thank you.

I have been looking for this all night.
All of the examples I have found so far used their load and save Functions in Ui Widget or on some key press and for me, which is relatively new to UE, was confusing as how to get it to the Game Instance variables.

Thank you for the great explanation and example.

Good guide, however, it didn’t work for me until I modified the load function to use the create Game Save node first if the cast failed. Probably because the first time around there is no game save to load and you have to create one before setting it to your Game Save variable.

1 Like

@tonyrvd can you post a screenshot of the modified functions?

I followed your tutorial point to point except adding the create save game node as suggested by @tonyrvd in the comments but seem to encounter a problem. I successfully create/load save game object, cast it to save my values and then it gets saved when the game exits(verified in the logs after save game successful). but when I play the game next time, I again starts from the default values.
The cause of this problem is that the object where the value is stored and the object which is fetched is different. This one is MyGameInstance_C_29. The previous one where the value was also successful stored may have been MyGameInstance_C_28. How can I solve this issue?

From what I understand, the “_C_Number” bit, like the “_C_29” added to your MyGameInstance class is just an iterator the engine uses on compiled versions of Blueprints and has no bearing on the actual class name for functionality, so the issue shouldn’t be with the “_C_X” ending.

It’s likely the issue is with how you’re saving and loading the data, as this system saves it to a file on disk and loads it from said file on disk instead of making it persist inside a class between game loads. Make sure you’re passing the same filename and path to both the Save and Load functions. Last I checked, the Save to and Load from Slot nodes always point to a subfolder of your project’s Saved/SaveGames directory, but leaving the filename blank (or possibly invalid) won’t save anything.

This functionality may have changed in the engine since I figured this out back around 4.17 or 4.18, so I’ll look into it and see if there’s anything I need to fix with the guide.

Thank you for your comment. I just needed a fresh start on a fresh day. I figured it out. The problem was not the save/load function, It was just I wasn’t using the data and therefore, it was using the default values of the variable everytime the game started.
Although, it would be even more informative if it would include how to initialize the save file initially, but this tutorial was really nice. Good job!

@Chromarict if you are still here and you understood these functions in 4.20+. Could you tell me what to do? This method saves and loads widget states (buttons, checkboxes, comboboxes, etc.). But the settings herself are not applied (because they require the use of the GameUserSettings, ApplySettings, SetFullscreenMode, SetScreenResolution etc. functions). Is there any way to do this without these nodes? (Sorry my bad english)

Thank you for the guide. Also you forgot to specify that you need to choose correct Game Instance class in Project Settings.

Follow-up question:
Would this approach work for in-editor settings as well?

–For example, multiple Actors/BPs contribute to overall lighting ambiance, and I’d like to save and restore various groups of settings across multiple Actors/BPs simultaneously, (e.g. BP_SunPosition, ExponentialHeightFog, Skylight, DirectionalLight, PostProcessVol) such that I can restore a certain ambient setting w/ a click or two w/o having to toggle 15 different controls in 5 different Actors…

Or is there a simpler way to save/restore these settings?

Thx,
-dt

This guide worked well for me except for a crash (in 4.23) when my GameInstance subclass tried to execute the Save Game To Slot node for the first time in the Load Settings function. This happened because my GameSettings variable (derived from SaveGame class) had not been initialised. In the Init function of my subclass of GameInstance I added a Create Save Game Object node and selected my subclass of SaveGame. I stored the output in my gameSettings variable and all worked well.

Thank you, thank you!!! :slight_smile:
I was stuck with this for well over an hour, I was about to give up and go to bed (it’s currently 02h30) but then I saw your post.

Looks like the newer versions of UE need you to explicitly execute the “Create Save Game Object” function, so what I did was add it where Chromarict added the “Save Game To Slot” node after the “Cast Failed” pin and it works!

I also have a follow up question. Does saving the file overwrite the previous file or simply update the modified values?
I have several different settings from different screens and pressing a save button in a settings screen writes the changes to the SaveGame object. But if I save that object, then it looks like the other settings return to their default values.

I have the same problem, I rewrote your functions exactly. SavedGame object reference is nullptr because no object was created that will be referenced in this variable or im not getting how references works in blueprints? Anyway, i decided to modify LoadGameSettings and added construction of SavedGame object if there is no such and now i think everything is working fine. At least I haven’t noticed any errors yet

Thank you Chromarict and glaucobacchi, I confirm that the “Create Save Game Object” is needed before saving initial save game. Unreal Engine Version 4.26.2

I did this and I’m still getting a crash when saving. I have no idea what it could be because the crash doesn’t give me any information. Any ideas? I’m in 4.23 too

I did this and I’m still getting a crash when saving. I have no idea what it could be because the crash doesn’t give me any information. Any ideas? I’m in 4.23 too

saving settings under a slot ? that sounds inapropriate