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.