If you're creating a game that will take your players multiple sessions to complete you'll more than likely want a way to persist said player's session. Not only will your player want to save his/her game state before exiting the game, but other times may arise where you'll want to save snippets of information (i.e. checkpoints, updates to the player's inventory, or the game unexpectedly crashes). I'd like to share my approach I've been using lately in my last couple games.
Saving Data
First, The Love2D Filesystem...
A common topic you'll find in Love2D Forums is confusion surrounding how to use the love.filesystem
library (sometimes argued). You aren't given much access, in fact you're only allow access to one directory. This is fine though since we're looking to save one to many .txt
documents.
You can read more on this page for your Operating System's folder location. Since love.filesystem
can only interact with this location we aren't really concerned with it. Just know that these files exist and you can find them on your computer.
Furthermore, setting the identity
property of Love2D's conf table will name the subfolder where your files will be stored. And finally we'll be giving our save files each a name (referenced as {filename}
).
For example, on a Mac your path may look something like this:
/Users/{username}/Library/Application Support/LOVE/{identity}/{filename}.txt
Now, onto actually saving this {filename}.txt
file.
Save Module
Below is a simple module for loading and saving game data. With the help of Binser, a lua serializer, we can serialize our save data.
Usage
Our game data will be saved within a lua table, for example:
{
player = {
attr = { hp = 50, hpMax = 100, ... },
weapons = { ... },
items = { ... }
},
checkpoint = { map = A1, row = 3, col = 4 },
...
}
Now, let's set up some convienence functions to quickly save data.
function newGame(name)
SAVE = Saver:save(name, {
-- initial data
player = {...},
checkpoint = {...},
...
})
end
function loadGame(name)
if Saver:exists(name) then
SAVE = Saver:load(name)
else
newGame(name)
end
end
function saveGame(name, data)
SAVE = Saver:save(name, data)
end
New Game
Remember how we said we would be saving to a {filename}.txt
file? You are able to save multiple files for the same game. We've included a parameter in functions to name
each save file. For example, when you first load your game:
function love.load()
loadGame('game-a')
end
The path to your save file will thus be:
/Users/{username}/Library/Application Support/LOVE/{identity}/game-a.txt
Save Game
When you want to save data, we'll pull the entire table, edit what we need, and then call our saveGame
function. Example, if we wanted to update our player's hp
attribute:
-- save on the global variable
SAVE.player.attr.hp = 100
-- save time
saveGame(SAVE)
And that's it! Next time you return the game the player's hp
attributes will show the updated value.