Savegames - Hirato/lamiae GitHub Wiki

This article is about the structure of the save game format. This is of no use to you unless you're curious about the technical aspects behind it.

Lamiae is currently in Alpha, this means that the savegame format is clean and simple, and unbridled with concern for backwards compatibility.

This also means the format is in flux and subject to change, and in ways that may not yet be reflected here.

As a general guideline...

  1. The Savegames are a binary format compressed by zlib into a gz archive.
  2. All 2+ byte data tyes are written as Little Endian
  3. All time based variables have listmillis subtracted from themselves for being written to file

Early termination/safety

Firstly, it loads the header of the file. This header has the magic value RPGS, upon confirmation that it's a valid save game file, it then checks the version fields.

There are two version fields, the first is sversion, the second gversion, respectively for the versions of the savegame and the game itself.

If these versions mismatch, the process aborts, an incompatible saveversion means that the savegame can't be successfully loaded at all, due to the nature of the binary format.

An incompatible game version means that the maker of the game has decided your savegame was from a version of the game that's simply far too buggy, and which he will not support by providing import scripts. Your game can still be loaded if you deign to fiddle with the compatversion for the respective game.

For more information on the import # signals, see Scripting

The principle error at this point is iteration, Lamiae doesn't do sanity checks, if the savegame says there's 2 million entities, it will read 2 million times... Unless an EoF token is encountered. An unexpected EoF results in instant termination of the loading process.

Assuming it can load the file. the Loading process also aborts if there is unknown data it doesn't know how to deal with, like it someone fiddled with the file or just simple corruption. Such as finding an entity type that doesn't exist.

Header

struct saveheader
{
	char magic[4];
	int sversion; //save
	int gversion; //game
};

The header is relatively simple, it has a 4 byte magic sequence, and 2 version numbers.

Immediately following it are the string for the data directory, the name of the map the player saved on, and then the player itself.

Factions

Recipes

Merchants

Variables

Map data

Reference stack

Delayed Script stack

Journal