How do you make a save game function?

Hi, I was wondering if anybody knows how to make a save game function. I’m a beginner at coding and I can’t find any tutorials on the topic.

Thanks

There is a couple tutorial you could of find using the search function here.

Here’s one that include saving highscore:

Looking at source of games is also a good way to learn more if you feel like it.

Enjoy!

Thank you.
That was super helpful!

The tutorial doesn’t show how you can store a structure into memory.

For example, let’s say you want to store the level the player got to along with their score, health, etc.

You can create a simple structure:

struct SaveData {
    uint8_t level = 0;
    uint16_t score = 0;
    uinit8_t health = 0;
    uint8_t etc = 0;
};

In your game, you can simply create a copy of the structure and use the variables within it:

SaveData mySaveData;

mySaveData.score = 1234;

And then save it using the eeprom methods:

EEPROM.put(EEPROM_STORAGE_SPACE_START, mySaveData);
EEPROM.get(EEPROM_STORAGE_SPACE_START, mySaveData);

Its all here!

2 Likes

Thanks for the edit @pharap … not sure why I went with ‘update’ when its ‘put’.

1 Like

There is an update function, but it’s only for uint8_ts.
I don’t really know why they didn’t just use read and update for both.

Exactly … we do have overloads, right?

Yep, and an overload would have worked absolutely fine here.

If put had been named update then both the template and non-template overloads would be considered when uint8_t is passed, but the non-template version would be considered a better match because non-template matches are always preferred over templates.

read wouldn’t have mattered because the number of parameters would be different anyway.

But even if the authors hadn’t known that and were worried about whether or not it would work, they could have just called the non-template versions readByte, writeByte and updateByte, which would have been more descriptive, and then kept read and update for the template versions instead of opting for the vague inaccuracy of put and get.

(Which incidentally is more or less what I did for that EEPROM API that I was working on ages ago and then completely forgot about. Oops.)

Can’t you also save the game state to the “FX-chip”?
If so, how is that done?

Which would be more challenging: creating a save game function or generating a save code for the players?

I’m pretty sure that’s definitely possible somehow (e.g. just saving/loading certain variables, possibly to other variables stored solely on the FX chip), but I’m not as knowledgeable as other people when it comes to the FX chip.

I’d guess the latter would be more challenging. If you go the first route it’s really just a matter of storing and retrieving data from the EEPROM.

It depends on the style of game and what you want the save code to do.

If you’re making a game that has a number of fixed levels and each code corresponds to a particular level then it’s as simple as comparing the user’s input code to a list of valid codes and loading the corresponding level.

If your level code also encodes information like the number of lives remaining then that’s a little bit more complicated, but not massively so.

There’s lots of different ways of going about it depending on how much information you need to encode, how efficient you need it to be, and how much you want to make it hard for players to be able to guess valid codes.

For most games, saving and loading without a code is as simple as just making a data structure that holds all the data you want to save and saving/loading that using put/get.

In both cases the most complicated part is probably making the user interfaces for saving and selecting save data or inputting the code. (Unless you’re using the save code to encode a large amount of differing information, in which case the encoding scheme could potentially get quite complex.)

1 Like

To load and save from the FX chip, you only need to do the following:

struct SaveData {
    uint8_t level = 0;
    uint16_t score = 0;
    uinit8_t health = 0;
    uint8_t etc = 0;
};

void setup() {

    ...
    FX::begin(FX_DATA_PAGE, FX_SAVE_PAGE);
    FX::disableOLED();
   ...

}

You can then create a structure to save, such as:

SaveData mySaveData;
mySaveData.score = 1234;

...

// Save
FX::saveGameState(mySaveData);

// Load
FX::loadGameState(mySaveData);
4 Likes

Thank you everyone for the help, I’m new to this forum and I didn’t realize how active it was.
If you were wondering the reason I asked is that I wanted to make a puzzle game but I didn’t know how to make the save feature. Thanks again for all the help!

4 Likes