Skip to content
Philip Pavlick edited this page Sep 11, 2020 · 4 revisions

This page will detail the save file format specification for SwashRL. This file format is defined by the methods used to save dungeon levels in savefile.d.

Table of Contents

  1. General Structure
    1. Version Marker
    2. Separator Marker
    3. Placeholder Marker
  2. Dungeon Level
    1. Map Tiles
    2. Items
    3. Monsters
    4. The Player

General Structure

Although it is possible in theory to simply write structs directly to files in the D programming language, I had some issues actually getting this to work in practice; for some reason the compiler would complain any time I attempted to save Map structs this way. As such, SwashRL saves level data by writing every variable pertinent to the level on a separate line (using the newline character as a delimiter).

Back to top

Version Marker

For compatibility purposes, every save file starts with the version number as defined in global.d.

The version number is written as a floating-point number with three digits after the decimal place, following the V.RRR version numbering system that SwashRL uses, where V is the version number and RRR is the three-digit revision number. The commit number is not included.

Back to top

Separator Marker

The save data for each level is split up into sections separated by a Separator Marker represented by the ASCII value 20. This is used to show where each section begins and ends as well as to keep track of where in the file we are while reading in the level data later on so that we can be sure that the level data is being read in properly. In the case of the list of monsters it is necessary to place the separator marker because the monsters are stored in a dynamically-sized array.

Back to top

Placeholder Marker

The way that map data is structured in SwashRL necessitates that the Map struct contain a certain amount of Item data, consisting of exactly one Item per map tile. However, in the majority of cases, most of these Items will be the placeholder No_item, indicating that there is in fact no item on this map tile. To save space, the ASCII value 19 is used to quickly determine that there is No_item here, both to save space and to make reading and writing level data faster.

Back to top

Dungeon Level

At time of writing, SwashRL is on version 0.032, and the save files only save data on the level that the player was on when they saved their game.

Dungeon levels are saved in the directory save/lev.

The dungeon level file begins with the version number followed by a separator marker.

Back to top

Map Tiles

Each Tile in the Map struct is saved row-by-row in linear order. The data written in order to save each tile t, in order, is as follows:

Variable Data Type Explanation
t.sym.ch char What character is used to represent t
t.sym.color ` Colors An enum used to select the appropriate color pair for t
t.block_cardinal_movement bool Whether or not t blocks movement in cardinal directions (i.e. north, south, east, or west)
t.block_diagonal_movement bool Whether or not t blocks movement in diagonal directions (i.e. northwest, northeast, southeast, and southwest)
t.block_vision bool Whether or not t blocks line-of-sight
t.lit bool Whether or not t is illuminated
t.seen bool Whether or not the player has seen t, or to put it another way whether or not t should be visible in the "fog of war" while the player does not have line-of-sight with it
t.hazard uint A flag indicating special properties that the tile may have, such as traps, mold, or blood splatters

After every map tile has been written, a separator is written to indicate that Tile output has been completed.

Back to top

Items

Each Item in the Map struct is checked row-by-row in linear order. For each item i in the map data, i.sym.ch is checked first. If it is null (ASCII value 0, indicated by the '\0' character in the source code) then this is a sign that there is no item in this space and a placeholder marker is written to save space.

If a placeholder has not been written, the following data is written to the save file in order:

Variable Data Type Explanation
i.sym.ch char What character is used to represent i
i.sym.color Colors An enum used to select the appropriate color pair for i
i.name string i's name
i.type uint A flag indicating what type of item i is, e.g. weapon, armor, &c
i.equip uint A flag indicating what equipment slot i goes into, if i is an equippable item
i.addd int The number of dice to add (or subtract) from the player's dice rolls, if applicable
i.addm int The number to add (or subtract) from modifiers to the player's dice rolls, if applicable

After every item has been written, a separator is written to indicate that Item output has been completed.

Back to top

Monsters

Each Monst in the Map struct is checked in linear order. If for whatever reason the monster has 0 hit points, it is not written into the save file. Otherwise, for each monster m, the following data is written in order:

Variable Data Type Explanation
m.sym.ch char What character is used to represent m
m.sym.color Colors An enum used to select the appropriate color pair for m
m.name string m's name
m.hp int m's hit points as of the creation of the save file
m.fly uint A flag indicating whether or not m can fly
m.swim uint A flag indicating whether or not m can swim
m.x uint m's x coordinate as of the creation of the save file
m.y uint m's y coordinate as of the creation of the save file
m.attack_roll.dice uint The number of dice in m's attack rolls
m.attack_roll.modifier int The modifier to add (or subtract) from m's attack rolls
m.attack_roll.floor int The lowest possible number m can score on an attack roll
m.attack_roll.ceiling int The highest possible number m can score on an attack roll

The monster's inventory, m.inventory, is not saved, because monster inventories have not been properly implemented as of version 0.031.

After all of the monsters have been written, a separator is written to indicate that Monst output has been completed. This is necessary to the saving and loading process because all monsters in a Map are stored in a dynamically-allocated array, rather than a fixed array like with Items and Tiles.

Back to top

The Player

As of version 0.032, the player character's x and y coordinates, stored as ubytes, is saved with the map data. This is because, as mentioned previously, the only save function currently available is the one which saves the map data. This means that any time the player saves their game, their inventory is lost and their hit points will have to be re-rolled.

There is no separator marker following the writing of the player, as it is the last piece of data written to the save file.

Back to top