Saving game settings

Let’s say your MonoGame-based game has the “typical” game settings:

  • sound fx volume
  • music volume
  • full screen or windowed
  • controls

How should these be saved?

I’m hoping someone replies with “use this portable library that does the right thing on every platform”. But other answers are welcome.

My first interest is in Windows desktop and OS X desktop. But I’m also interested in PS4, XboxOne, iOS and Android.

I didn’t see anything poking around the docs, google or these forums, but maybe I just missed it.

I have used a streamreader/stream writer to save to and load from txt files… That way, you can easily edit the settings file manually, if settings dont work for current user system… (make sure you overload your streamreader to be culture-independent, so it’ll run correctly on any language/ region setting)

I have also used xml… Which is probably better, and very easy to do… You can basically read data-entries from xml like its variables in a class… only of coarse the xml is a stored file :slight_smile:

If you dont know xml it sounds like a hassle, but you will be able to do what you are talking about today if you set out to learn xml… its as easy as note-pad, almost.

I’m familiar with XML and other formats including JSON, YAML and INI. I don’t know the correct file system path on the numerous platforms, though I could look it up and write the correct code for each one. However, I imagine someone has already done this.

Maybe it’s enough to use Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData):

Or maybe I should use Properties.Settings.Default[“key”] as described at:

I guess I’m wondering if there is a “best practice” or “typical practice” for portable monogames.

https://msdn.microsoft.com/en-us/library/bb203924.aspx

StorageContainer class, I wonder if it works multi platform in MonoGame and stores/saves correctly depending whats being played on?

Pretty sure xml is considered typical. I think even some console games use xml?
-Anyways, I hear people mention it all the time, it seems pretty conventional.

And you can just drag your xml files into the solution explorer, and store/distribute it like any other content. That goes for txt too… So you dont have to worry about various platform paths… The program just retrieves them from its own install folder.

Sounds good,

I have actually been meaning to try figure out how MonoGame/.NET code compiles onto different platforms and what can and can’t run.

I know that fundamentally a string works different between C#/windows compared to a mac etc or iphone or android. So how these other platforms “know” to read strings, save xml etc is still beyond me

Don’t use StorageContainer, it has been removed in the newest MG from source, so 3.6 won’t have it.

On the question of how to save stuff, I would recommend you look into XmlSerialization (or any type of serialization for that matter). Serialization allows you to save an instance of an object which is very useful since you can create a class named Settings which instance you just save/load from a file.

@monopalle, your description here does not cover saving the info for later use. Here is a use case:

  1. The user launches your game.
  2. The user picks “Settings” from the main menu.
  3. The user changes music volume and controls.
  4. The user escapes to the main menu.
  5. The user plays the game.
  6. The user quits the game.
  7. Later, the user launches the game.
  8. The user-selected settings for music volume and controls are required to be in effect.

Note that settings are not normally saved back into the program’s install directory. Instead they go into some kind of “user data folder” which varies by platform.

Your description of putting an XML file in the project would be fine for read-only settings.

I’m 100% comfortable with serialization and various file formats including XML and others.

What I’m mostly interested in is the variance in platforms regarding where to save data. I’m mostly interested in hearing from people who have shipped MonoGame games on multiple platforms.

If I don’t hear anything more authoritative, I will start with

var appDataDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
appDataDir = Path.Combine(appDataDir, "/:MyGameName:\\");
Directory.CreateDirectory(appDataDir); // to-do: handle exceptions
var settingsFileName = Path.Combine(appDataDir, "Settings.ini");
SaveSettings(settingsFileName);

And use it until it I run into an issue. I’m sure this will work find on Windows and probably Mac. Don’t know about other platforms like mobile and consoles.

1 Like

oh, never mind, I understand, you are looking for info on various different systems… I assume to get user-specific settings on the same machine.

I only know windows, so sorry to have wasted your time. -I’d go with one settings file though, store it anywhere practical.
Users tend to have their own devices anyways, don’t they?

I use the IsolatedStorage APIs on all the platforms I have developed for. There is also IsolatedStorageSettings which is a container of key/value pairs if you want the simplest approach.

1 Like

That’s desktop platforms only, right?

Which platforms did you use IsolatedStorage on?

I asked this in gitter and this is what @Tom wrote in gitter just a few days ago:

The only rub with isolated storage is that it doesn’t work on consoles
for “save games” or “game settings” type of data storage… it is really a per-platform issue on consoles

In general you can reuse 99% of all your save game code across all platforms.

The issue is on some platforms, like consoles, there are very specific ways to “open” the save game location and specific ways you need to react to out of space situations, corrupt saves, etc.

So just split your save game system into two parts:

  • The cross-platform part that just writes/reads from a Stream.
  • The platform specific part that decides where to save and how to open/create the Stream.

This makes it easier to port to all platforms.

1 Like

Sorry for digging this topic (239 days old yeah!), but I’m trying to port my game to Android and it seems that IsolatedStorageSettings class is not available and it’s strange because similiar class IsolatedStorageFile is cross-platform. Is there any similiar cross-platform class to store app settings ? Or should I write something on my own, like IsolatedStorageSettings for WP, SharedPreferences for Android etc. I know I could also use IsolatedStorageFile but I don’t want messing with saving/reading file just for settings.

Anybody ? If there’s nothing like this, which approach will be better:

  1. Use native solutions: SharedPreferences for Android, IsolatedStorageSettings for WP8 etc.
  2. Keep settings in dictionary and store them as file (using serialization JSON or XML), with IsolatedStorageFile to work on files

I ended up to use PCLStorage that seems to be cross platform (but not tested it on other platforms than Windows yet).

For an engine I wrote in MG, I used code I found here:

And made a singleton class that can write objects as XML or Binary.
It’s pretty straight-forward and you can extract just the class from here:

And use it like this:

GameFiles.Instance.WriteToFile(FileFormats.Xml, "somefile.txt", value);

1 Like