Save file format: Difference between revisions

From Arx Libertatis Wiki
Jump to navigation Jump to search
No edit summary
Line 1: Line 1:
This page describes the save format used by Arx Fatalis as well as Arx Libertatis extensions. All integers are encoded in little-endian byte order. Types are the same as in <code>platform/Platform.h</code> - <b>s</b> (signed integer) / <b>u</b> (unsigned integer) / <b>f</b> (float), followed by the number of bits. Arrays are denoted by brackets like in c++.
This page describes the save format used by Arx Fatalis as well as Arx Libertatis extensions.
 
See [[Common file format types]] for a description of the type names used here.


== Arx save file container (.sav) ==
== Arx save file container (.sav) ==
Line 68: Line 70:
! Description
! Description
|-
|-
| null-terminated string
| <b>c string</b>
| File name
| File name
|}
|}
Line 162: Line 164:
| Savegame data version
| Savegame data version
|-
|-
| <b>u8[256]</b>
| <b>char[256]</b>
| Savegame name
| Savegame name
|-
|-
Line 177: Line 179:
Savegame data version specifies the version number of the data structures stored in this save file (not the version number of the savefile container). Currently this value is always <code><b>1.005f</b></code>.
Savegame data version specifies the version number of the data structures stored in this save file (not the version number of the savefile container). Currently this value is always <code><b>1.005f</b></code>.


The version is followed by the user-supplied name for the savegame, padded to 256 bytes with null characters. Strings longer that 256 characters are not allowed. The original Arx Fatalis code did not define an encoding for this name and presumably only allowed ASCII characters. Arx Libertatis interprets this name as an UTF-8 encoded string. The special name <code>"<b>ARX_QUICK_ARX</b>"</code> is used for quicksaves. Arx Fatalis and older Arx Libertatis versions also used <code>"<b>ARX_QUICK_ARX1</b>"</code> for the second quicksave.
The version is followed by the user-supplied name for the savegame. The special name <code>"<b>ARX_QUICK_ARX</b>"</code> is used for quicksaves. Arx Fatalis and older Arx Libertatis versions also used <code>"<b>ARX_QUICK_ARX1</b>"</code> for the second quicksave.


The current level specifies the number of the level in which the player resided when the savegame was last updated. This number can be padded to 3 digits with leading zeroes and prepended with <code>"lvl"</code> to get the level file (<code>1</code> becomes <code>"lvl001"</code>)
The current level specifies the number of the level in which the player resided when the savegame was last updated. This number can be padded to 3 digits with leading zeroes and prepended with <code>"lvl"</code> to get the level file (<code>1</code> becomes <code>"lvl001"</code>)

Revision as of 06:19, 11 February 2012

This page describes the save format used by Arx Fatalis as well as Arx Libertatis extensions.

See Common file format types for a description of the type names used here.

Arx save file container (.sav)

Save files are stored in a generic container that maps names (arbitrary strings) to chunks of data. Arx Libertatis adds two extensions to the vanilla Arx Fatalis .sav format. The .sav container format can be read and written using the SaveBlock class (io/SaveBlock.h)

Header

The file header starts at byte position 0 - there is no magic number.

Type Description
u32 File table offset

The file table offset is the location of the file table (in bytes) relative to the first byte after the header. Add 4 bytes to get the offset relative to the start of the file.

File table

The file table starts with a file table header:

File table header

Type Description
u32 Format version
u32 Number of file entries

Currently, the following version numbers are defined.

Value Name Description
0x00010000 SAV_VERSION_LEGACY Legacy version
0x00010001 SAV_VERSION_RELEASE Current Arx Fatalis version
0x00020000 SAV_VERSION_DEFLATE Added support for different compression algorithms (Arx Libertatis extension)
0x00020001 SAV_VERSION_NOEXT Removed ".sav" suffix from internal filenames (Arx Libertatis extension)

The file table is followed by the specified number of file entries. For save files with version SAV_VERSION_LEGACY the first file entry should be ignored.

File table entries

Type Description
c string File name

Each file table entry is preceded by a null-terminated string - the file name. Versions older than SAV_VERSION_NOEXT store file names case-insensitively and append ".sav". When loading such versions, the filename should be converted to lowercase and the ".sav" extension removed.

For versions older than SAV_VERSION_DEFLATE:

Type Description
u32 Stored (compressed) file size - This can be ignored and calculated from chunk sizes.
u32 Number of chunks - 0 means 1!
u32 Useless data. This can be safely ignored

For SAV_VERSION_DEFLATE and newer:

Type Description
u32 Uncompressed file size
u32 Number of chunks
u32 Compression algorithm

Currently, the following compression algorithms are defined.

Value Name Description
0 Stored No compression. Data is stored as-is.
1 ImplodeCrypt Data is compressed using the PKWARE implode library. The result is bitwise negated.
2 Deflate Data is compressed using the ZLIB deflate format.

Code to decompress PKWARE implode-encoded data can be found in blast.c in the contrib directory of the zlib source.

Versions older than SAV_VERSION_DEFLATE always use the ImplodeCrypt algorithm. To allow changing save files without decompressing all data, the value 0xffffffff may be used to indicate that the uncompressed size is not known if (and only if) the compression algorithm is ImplodeCrypt.

The rest of the file entry is a list of as many chunk offsets as specified. For versions older than SAV_VERSION_DEFLATE, the actual number of chunks is always 1 or more, even if the file entry says 0. The concatenation of the chunks referenced by these offsets makes up the compressed file data.

Chunk offsets
Type Description
u32 Chunk size
u32 Chunk offset

The chunk offset is the location of the chunk data (in bytes) relative to the first byte after the header. Add 4 bytes to get the offset relative to the start of the file. The chunk size is given in bytes. There is no guarantee that all parts of the .sav file are used in chunks or the file table.

Saved structures

These structures are filled and parsed in src/scene/ChangeLevel.cpp and described in src/scene/SaveFormat.h in Arx Libertatis.

Savegame info (pld)

The savegame info file called "pld" consist of a single structure:

Type Description
f32 Savegame data version
char[256] Savegame name
s32 Current level
u32 Current time
s32[32] (padding - always 0)

Savegame data version specifies the version number of the data structures stored in this save file (not the version number of the savefile container). Currently this value is always 1.005f.

The version is followed by the user-supplied name for the savegame. The special name "ARX_QUICK_ARX" is used for quicksaves. Arx Fatalis and older Arx Libertatis versions also used "ARX_QUICK_ARX1" for the second quicksave.

The current level specifies the number of the level in which the player resided when the savegame was last updated. This number can be padded to 3 digits with leading zeroes and prepended with "lvl" to get the level file (1 becomes "lvl001")

The current time is the in-game time when the savegame was last updated. This is the total number of in-game milliseconds since the game start.

Player state (player)

TODO

Global script state (globals)

TODO

Level state (lvl???)

TODO

Interactive object state

TODO