How to add a save/load game function to a Lua/C++ game engine

I'm curious what the best approach would be to save the current state of my game. The lua scripts contain the gamestate, but also some gameplay related info that doesn't need to be stored as part of a savegame.

Should I split my lua scripts into a 'saveable state' part and pure gameplay stuff like dialogs?

What would you recommend for a store/restore mechanic? I could serialize the info to JSON and just store it as a textfile, and on load set all the values in the lua state I suppose?

A alternative could be to have C++ load all relevant info from the Lua state, and store it in some format..but that seems more work than just serializing some lua tables.

As an example, here is one object inside a level that contains both gameplay logic (onOpen) and state info (opened):

skull = {
opened = false,
rect = { 64, 29, 14, 16 },
sprite = "entrance_door_skull",
dialogs = {
look = "It's the skull of some creature. Its meaning seems quite clear: death lurks inside.",
},
onOpen = function(self, scene)
if not self.opened then
addMove("skull", 1000, 0, -12, function ()
SceneGameEntrance.actionItems.skullKey.isVisible = true
end)
addDialog("As if by magic, the skull rises.")
self.opened = true
else
addDialog("It is already open.")
end
end
}

• Is your data shared between your c++ and your Lua code, or does it strictly remain handled in the Lua? Aug 23, 2022 at 12:53
• It's mostly lua apart from some minor stuff
– Oli
Aug 23, 2022 at 12:56
• I think what you suggest offers more flexibility than what is suggested in the answers. If you have your Lua objects implement a serialize/de-serialize function that would save/restore only what is specific to this instance, you would not need to implement a struct in c++, and modify this struct every time you change a Lua object. (As long as you can pair what data is saved to what type of object you have saved.) Aug 23, 2022 at 17:40
• I like the struct idea because I can only take the relevant data out of lua..I don't use lua objects, it's mostly a big table with too much stuff mixed in there
– Oli
Aug 23, 2022 at 22:30

2 Answers

The way I've done it in the past in C++ is to create a struct that only holds the information that a save needs.

For example, if you have a game where you need to save/load what levels has the user completed, you can make a struct like so:

struct MySaveData {
int level1Complete;
int level2Complete;
...
};


Then when you want to save your game, you'd need to create a struct of type MySaveData, and fill in all the details of the current state, then save the struct itself in the desired location. Loading would work in a similar way, where you load data from a file and apply them to an object of that struct, then tell the game how to behave based on it.

You can also create a class instead with its own functions to automate some of the process.

Admittedly this is a not very scalable solution, and in a big game it wouldn't be very usable, but hopefully it can give you a head start for a more complex implementation.

• For my small game I think this is a realistic option..I'll give it a shot!
– Oli
Aug 23, 2022 at 15:17

As already pointed out, you should use a struct containing the data required for a single save. Usually however, this is very easy to cheat on, and if you want a more hardened approach, this is a much better way (I have used it myself in a game):

1. Instead of using a single struct, use JSON and serialize that JSON into a binary file. I don't know which language you're using, but I was using C99. I know for sure libraries exist for most (If not all) programming languages.

2. If possible, make that file inaccessible by changing its permissions. This is very platform specific and also involves process permissions, which I won't go into depth either.

You can go on to think of more ways to make sure your game can't be worked around. Although as long as it doesn't interact with other players, you may not even care at all about all this and just want stuff to work. If that's the case, the existing answer will be enough.

• serializing to a binary file should be a good extra guard! and if people want to cheat at this tiny adventure game, well that's their business
– Oli
Aug 23, 2022 at 22:29