Skip to content
This repository was archived by the owner on Apr 23, 2025. It is now read-only.

Game State

John Ellis edited this page Oct 24, 2021 · 1 revision

Saving and Restoring Game State

The 32blit SDK does have an abstraction over the PicoSystem file system that allows you to serialize and then save or restore C++ objects to flash. So long as you stick to structs without any pointers, this is a very simple way of saving game state so that you can restore it later. Without save/restore operations, your game re-starts with default values whenever it is powered off and on again.

Creating Save Game Objects

Before you can write your game's state to flash, you need to create an object representation of it to be serialized (transformed into a data format suitable for saving as a file). The easiest way to do this is to create a C++ struct with properties for the game state elements you want to save and restore.

As an example, picosystem-demo defines the following struct to represent game state on disk:

struct SaveData {
  std::pair<blit::Point, uint8_t> field[FIELD_COLS][FIELD_ROWS];
  uint32_t current_score = 0;
  uint32_t best_score = 0;
  uint32_t time_elapsed = 0;
};

This saves the PicoSystem's current score, the best score, how much time has elapsed in the current round, and a two-dimensional array representing the current state of the playing field. Note no pointers are included - all properties hold concrete values.

Writing Save Game Objects to disk

To write save game data to flash, first populate your save game object with current state data, then write that object using the 32blit SDK. picosystem-demo does this with:

void save_game() {
  SaveData data = SaveData();
  data.time_elapsed = time_elapsed;
  data.current_score = current_score;
  data.best_score = best_score;
  field.serialize(data.field);
  write_save(data);
}

Here we create an instance of the save game struct, we populate this struct with current game data, then we call the 32blit write_save function. Pretty easy.

Reading Save Game Objects

Reading objects is similar to saving objects - we create a new save data object, populate it from data saved in flash, and then copy the save data object to the currently running game. In picosystem-demo this is done using:

SaveData data;
read_save(data);
current_score = data.current_score;
best_score = data.best_score;
time_elapsed = data.time_elapsed;
field.deserialize(data.field);

However - we may not have any save data stored on disk! If this is the first time the game has been launched, we need to build the game state from scratch using defaults. To do that, we can test read_save(data) and ensure it loads data successfully, then populate current game state with defaults if it does not:

SaveData data;
if(read_save(data)) { // We have a save file
  current_score = data.current_score;
  best_score = data.best_score;
  time_elapsed = data.time_elapsed;
  field.deserialize(data.field);
} else { // No save file, start from scratch
  current_score = 0;
  best_score = 0;
  time_elapsed = 0;
  field.create();
}

Here we check and see if the save data was read - if not, we start with some safe defaults.