New to Monogame. How to save in 3.6

I’ve converted my project from Unity over to Monogame for efficiency reasons. However, I’ve been having a lot of difficulties with saving. I’m not entirely sure if it’s a 3.6 thing, but the tutorials involve either Microsoft.Xna.Framework.Storage or other classes/functions that I don’t seem to have.

If anyone could show me some examples of how they save it would be much appreciated.

1 Like

Usually what I like to do when it comes to saving is I like to get a platform-independent path equivalent to %AppData%\Roaming\Watercolor Games\Peacenet (game’s developed by Watercolor Games, and the game’s called Peacenet - fairly standard practice in that folder). I get this path when my game initiates, and store it in a variable.

string gamePath = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Watercolor Games", "Peacenet");

That’ll work on all desktop platforms. Not sure about Android, iOS, whatnot.

Then, I just use System.IO directly to read/write my save file - whether it be in JSON format, binary, or even a LiteDB database like it actually is in my game.

This gives you an obvious benefit, your save system’s independent from MonoGame, so you can use it anywhere - whether it be in a WinForms game, a server, an editor environment, what not.

The trick is to always use Path.Combine. Because this gives you paths in the correct format for the platform you’re on. On Unix-likes, you’ll get /path/to/whatever/thing.txt. On Windows, you’ll get C:\path\to\whatever\thing.txt. You also want to store your save data somewhere separate from your game’s EXE, that way it’s less likely it gets accidentally deleted or messed up when the game updates - and the player doesn’t have to copy their save over when you release a .zip file containing your game’s binaries and they decide to extract that somewhere other than where their current build is at.

So… in my case…

//get my game's save directory.
string gamePath = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Watercolor Games", "Peacenet");
//Get the save file path.
string saveFile = Path.Combine(gamePath, "savefile.db");
//Use this as a LiteDB connection string. This is specific to my game. You can name your save file whatever you want, use whatever format is best for you, just as long as you keep it somewhere inside your gamePath.
var db = new LiteDB.LiteDatabase(saveFile);
//If you were coding my game, you just loaded the player's save in 3 lines of code. And any time you modify the database you just loaded, it'll automatically save the game for you. Simply dispose the database when you're done the game session (and shrink if you wanna save disk space and optimize the DB) and you've unlocked the save file for another game session.
//
//If you're writing your own save system, you may want to consider implementing that stuff yourself so that you're sure the game saves when you modify something. There's nothing more insulting than having a crash after a ton of progress that wasn't saved because the dev never called `SaveGame()` when they modified your save file.

What type of data are you trying to save?

Me, or @XF20XY? If me, then, well, the database technique helps with a modding system I want to implement making it very easy to make save data modular and have the game not touch things it doesn’t need to. For example, a save file created in Peacenet June 2018 Week 2 will happily load up in an early May build, and it won’t touch any of the stuff that the June build wrote to the save.

This also means that a mod can add its own save data to the database, the player can uninstall it, and not break their save file. (And the mod doesn’t have to store its own separate save file).

My reply was actually to “XF20XY”, the original poster of this thread.

But to answer your question (“Watercolor_Games”) there are numerous ways to save your “session” data.

The simplest way is to save your data in a sequential flat file (ie: CSV) but this has issues when dealing with complex data output and its retrieval.

An XML file or an XML database is another way to but this too can become quite inefficient with complex data since XML tends to be notoriously inefficient due to its verbosity.

My preference has always been for an RDBMS, since this is what I have my training and experience in. With this genre, you have the option of using SQLite or Firebird (Firebird has a desktop database edition). Due to its extensive capabilities, Firebird is more complex to use.

However, both noted RDBMSs are quite fast and offer a lot of flexibility with complex data.

If however, you prefer more of an object structure to your database you can go with one of the freely available object databases such as Perst (see… Perst Download.

All of the noted database systems are freely available…